ACodec.cpp revision bf927f8ec7979f2b64331c2b2f12a6a5dba05bca
199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten/*
265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Copyright (C) 2010 The Android Open Source Project
365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * you may not use this file except in compliance with the License.
665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * You may obtain a copy of the License at
765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Unless required by applicable law or agreed to in writing, software
1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * See the License for the specific language governing permissions and
1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * limitations under the License.
1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian */
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0
1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "ACodec"
1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/ACodec.h>
2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten#include <binder/MemoryDealer.h>
23d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/foundation/hexdump.h>
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/foundation/ABuffer.h>
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/foundation/ADebug.h>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/foundation/AMessage.h>
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
299ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang#include <media/stagefright/BufferProducerWrapper.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/MediaCodecList.h>
3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/MediaDefs.h>
32d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/OMXClient.h>
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/OMXCodec.h>
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/hardware/HardwareAPI.h>
3738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <OMX_AudioExt.h>
39fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <OMX_Component.h>
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <OMX_IndexExt.h>
41f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten
4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "include/avc_utils.h"
43d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten
44d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kastennamespace android {
45d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten
469ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wangtemplate<class T>
4725b248eb52a0a16adaef6b79c9d92cb88b9a2bc2Glenn Kastenstatic void InitOMXParams(T *params) {
48d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten    params->nSize = sizeof(T);
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    params->nVersion.s.nVersionMajor = 1;
5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    params->nVersion.s.nVersionMinor = 0;
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    params->nVersion.s.nRevision = 0;
52fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    params->nVersion.s.nStep = 0;
5364760240f931714858a59c1579f07264d7182ba2Dima Zavin}
547394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstruct CodecObserver : public BnOMXObserver {
5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CodecObserver() {}
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5844deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    void setNotificationMessage(const sp<AMessage> &msg) {
5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNotify = msg;
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
616d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent
6259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    // from IOMXObserver
6359bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    virtual void onMessage(const omx_message &omx_msg) {
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> msg = mNotify->dup();
653b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten
663b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten        msg->setInt32("type", omx_msg.type);
67feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        msg->setPointer("node", omx_msg.node);
68190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
694d8d0c30abfa4b8d75866d42094cc797e05068faGlenn Kasten        switch (omx_msg.type) {
70190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            case omx_message::EVENT:
71190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            {
72190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                msg->setInt32("event", omx_msg.u.event_data.event);
73190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                msg->setInt32("data1", omx_msg.u.event_data.data1);
744d8d0c30abfa4b8d75866d42094cc797e05068faGlenn Kasten                msg->setInt32("data2", omx_msg.u.event_data.data2);
754ff14bae91075eb274eb1c2975982358946e7e63John Grossman                break;
764ff14bae91075eb274eb1c2975982358946e7e63John Grossman            }
774ff14bae91075eb274eb1c2975982358946e7e63John Grossman
7858912562617941964939a4182cda71eaeb153d4bGlenn Kasten            case omx_message::EMPTY_BUFFER_DONE:
7958912562617941964939a4182cda71eaeb153d4bGlenn Kasten            {
8058912562617941964939a4182cda71eaeb153d4bGlenn Kasten                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
8158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                break;
8258912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
8358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
8458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            case omx_message::FILL_BUFFER_DONE:
8558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            {
861dc28b794587be22c90a97070d928f94586db638Glenn Kasten                msg->setPointer(
871dc28b794587be22c90a97070d928f94586db638Glenn Kasten                        "buffer", omx_msg.u.extended_buffer_data.buffer);
881dc28b794587be22c90a97070d928f94586db638Glenn Kasten                msg->setInt32(
891dc28b794587be22c90a97070d928f94586db638Glenn Kasten                        "range_offset",
9058912562617941964939a4182cda71eaeb153d4bGlenn Kasten                        omx_msg.u.extended_buffer_data.range_offset);
9158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                msg->setInt32(
9258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                        "range_length",
9358912562617941964939a4182cda71eaeb153d4bGlenn Kasten                        omx_msg.u.extended_buffer_data.range_length);
9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                msg->setInt32(
9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        "flags",
961c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                        omx_msg.u.extended_buffer_data.flags);
971c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                msg->setInt64(
981c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                        "timestamp",
991c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                        omx_msg.u.extended_buffer_data.timestamp);
1001c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                msg->setPointer(
1011c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                        "platform_private",
1021c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                        omx_msg.u.extended_buffer_data.platform_private);
1031c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                msg->setPointer(
1041c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                        "data_ptr",
1051c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                        omx_msg.u.extended_buffer_data.data_ptr);
1061c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                break;
1071c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            }
108de070137f11d346fba77605bd76a44c040a618fcEric Laurent
10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            default:
11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                TRESPASS();
111ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kasten                break;
112ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kasten        }
11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        msg->post();
115b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten    }
11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprotected:
11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual ~CodecObserver() {}
11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprivate:
12165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> mNotify;
12265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian};
12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
1277dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten
12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstruct ACodec::BaseState : public AState {
1297dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
1307dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten
13165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprotected:
1327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    enum PortMode {
1337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        KEEP_BUFFERS,
13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        RESUBMIT_BUFFERS,
1357dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        FREE_BUFFERS,
1367dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten    };
13760cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent
1387cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent    ACodec *mCodec;
1397cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent
1407cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent    virtual PortMode getPortMode(OMX_U32 portIndex);
1417cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent
1427cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent    virtual bool onMessageReceived(const sp<AMessage> &msg);
14358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
14458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
1454adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
1464adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
14758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    virtual void onInputBufferFilled(const sp<AMessage> &msg);
1484ff14bae91075eb274eb1c2975982358946e7e63John Grossman
1497cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent    void postFillThisBuffer(BufferInfo *info);
150300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
151300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kastenprivate:
152300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    bool onOMXMessage(const sp<AMessage> &msg);
153300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
154300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
155300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
1564adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    bool onOMXFillBufferDone(
157300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            IOMX::buffer_id bufferID,
1584adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            size_t rangeOffset, size_t rangeLength,
159300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            OMX_U32 flags,
160300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            int64_t timeUs,
161300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            void *platformPrivate,
162300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            void *dataPtr);
163300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
164300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    void getMoreInputDataIfPossible();
165300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
166300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
16765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian};
16865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
169d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten////////////////////////////////////////////////////////////////////////////////
1709ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
1719ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wangstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
17225b248eb52a0a16adaef6b79c9d92cb88b9a2bc2Glenn Kasten    DeathNotifier(const sp<AMessage> &notify)
17325b248eb52a0a16adaef6b79c9d92cb88b9a2bc2Glenn Kasten        : mNotify(notify) {
17425b248eb52a0a16adaef6b79c9d92cb88b9a2bc2Glenn Kasten    }
1759ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
1769ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    virtual void binderDied(const wp<IBinder> &) {
1779ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        mNotify->post();
1789ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    }
1799ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
180d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kastenprotected:
1819ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    virtual ~DeathNotifier() {}
182f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
183799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinprivate:
184f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    sp<AMessage> mNotify;
185799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
186799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
187f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent};
188f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
189f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurentstruct ACodec::UninitializedState : public ACodec::BaseState {
190f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    UninitializedState(ACodec *codec);
191799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
192f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurentprotected:
193f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    virtual bool onMessageReceived(const sp<AMessage> &msg);
194f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    virtual void stateEntered();
195f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
196f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurentprivate:
197799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    void onSetup(const sp<AMessage> &msg);
198f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    bool onAllocateComponent(const sp<AMessage> &msg);
199f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
200f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    sp<DeathNotifier> mDeathNotifier;
201f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
202f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
203f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent};
204799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
205799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin////////////////////////////////////////////////////////////////////////////////
206799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
207799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinstruct ACodec::LoadedState : public ACodec::BaseState {
208799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    LoadedState(ACodec *codec);
209799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
210799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinprotected:
21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual bool onMessageReceived(const sp<AMessage> &msg);
21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual void stateEntered();
21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprivate:
2154ff14bae91075eb274eb1c2975982358946e7e63John Grossman    friend struct ACodec::UninitializedState;
2164ff14bae91075eb274eb1c2975982358946e7e63John Grossman
2174ff14bae91075eb274eb1c2975982358946e7e63John Grossman    bool onConfigureComponent(const sp<AMessage> &msg);
2184ff14bae91075eb274eb1c2975982358946e7e63John Grossman    void onCreateInputSurface(const sp<AMessage> &msg);
2194ff14bae91075eb274eb1c2975982358946e7e63John Grossman    void onStart();
2204ff14bae91075eb274eb1c2975982358946e7e63John Grossman    void onShutdown(bool keepComponentAllocated);
2214ff14bae91075eb274eb1c2975982358946e7e63John Grossman
2224ff14bae91075eb274eb1c2975982358946e7e63John Grossman    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian};
2245a61d2f277af3098fc10b2881babca16391362daDima Zavin
2255a61d2f277af3098fc10b2881babca16391362daDima Zavin////////////////////////////////////////////////////////////////////////////////
2265a61d2f277af3098fc10b2881babca16391362daDima Zavin
2275a61d2f277af3098fc10b2881babca16391362daDima Zavinstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
228799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    LoadedToIdleState(ACodec *codec);
229fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
230935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurentprotected:
231935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    virtual bool onMessageReceived(const sp<AMessage> &msg);
232799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
2334ff14bae91075eb274eb1c2975982358946e7e63John Grossman    virtual void stateEntered();
2344ff14bae91075eb274eb1c2975982358946e7e63John Grossman
2354ff14bae91075eb274eb1c2975982358946e7e63John Grossmanprivate:
2364ff14bae91075eb274eb1c2975982358946e7e63John Grossman    status_t allocateBuffers();
2374ff14bae91075eb274eb1c2975982358946e7e63John Grossman
2384ff14bae91075eb274eb1c2975982358946e7e63John Grossman    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
2394ff14bae91075eb274eb1c2975982358946e7e63John Grossman};
2404ff14bae91075eb274eb1c2975982358946e7e63John Grossman
2414ff14bae91075eb274eb1c2975982358946e7e63John Grossman////////////////////////////////////////////////////////////////////////////////
2424ff14bae91075eb274eb1c2975982358946e7e63John Grossman
2434ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
2444ff14bae91075eb274eb1c2975982358946e7e63John Grossman    IdleToExecutingState(ACodec *codec);
24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
246a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentprotected:
247a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual bool onMessageReceived(const sp<AMessage> &msg);
248a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
2494ff14bae91075eb274eb1c2975982358946e7e63John Grossman    virtual void stateEntered();
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprivate:
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian};
254799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstruct ACodec::ExecutingState : public ACodec::BaseState {
25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ExecutingState(ACodec *codec);
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    void submitRegularOutputBuffers();
26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    void submitOutputMetaBuffers();
26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    void submitOutputBuffers();
263799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
2642b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    // Submit output buffers to the decoder, submit input buffers to client
2652b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    // to fill with data.
266a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    void resume();
267a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Returns true iff input and output buffers are in play.
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool active() const { return mActive; }
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
271a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentprotected:
272a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual PortMode getPortMode(OMX_U32 portIndex);
273a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual bool onMessageReceived(const sp<AMessage> &msg);
274a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual void stateEntered();
275a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
276a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
277a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
278a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentprivate:
279799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    bool mActive;
280a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
281a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
282a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent};
283a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
284a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent////////////////////////////////////////////////////////////////////////////////
285a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
286a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
287a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    OutputPortSettingsChangedState(ACodec *codec);
288a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
289a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentprotected:
290a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual PortMode getPortMode(OMX_U32 portIndex);
291a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual bool onMessageReceived(const sp<AMessage> &msg);
292a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual void stateEntered();
293a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
294a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
295799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
296a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentprivate:
297799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
298799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin};
299799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
300a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent////////////////////////////////////////////////////////////////////////////////
301799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
302799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ExecutingToIdleState(ACodec *codec);
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprotected:
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual bool onMessageReceived(const sp<AMessage> &msg);
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual void stateEntered();
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
31277c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten    virtual void onInputBufferFilled(const sp<AMessage> &msg);
31377c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten
31477c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kastenprivate:
31577c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten    void changeStateIfWeOwnAllBuffers();
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool mComponentNowIdle;
3183a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
3193a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
320012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten};
3213a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
3223a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen////////////////////////////////////////////////////////////////////////////////
323012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten
3243a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissenstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
3253a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    IdleToLoadedState(ACodec *codec);
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprotected:
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual bool onMessageReceived(const sp<AMessage> &msg);
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual void stateEntered();
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprivate:
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian};
336a4454b4765c5905f14186893b0688be375642283Glenn Kasten
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
3384ff14bae91075eb274eb1c2975982358946e7e63John Grossman
3394ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstruct ACodec::FlushingState : public ACodec::BaseState {
3404ff14bae91075eb274eb1c2975982358946e7e63John Grossman    FlushingState(ACodec *codec);
3414ff14bae91075eb274eb1c2975982358946e7e63John Grossman
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprotected:
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual bool onMessageReceived(const sp<AMessage> &msg);
34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual void stateEntered();
34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    virtual void onInputBufferFilled(const sp<AMessage> &msg);
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprivate:
35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool mFlushComplete[2];
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    void changeStateIfWeOwnAllBuffers();
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian};
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianACodec::ACodec()
36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : mQuirks(0),
36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mNode(NULL),
36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mSentFormat(false),
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mIsEncoder(false),
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mUseMetadataOnEncoderOutput(false),
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mShutdownInProgress(false),
36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mIsConfiguredForAdaptivePlayback(false),
3697dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten      mEncoderDelay(0),
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mEncoderPadding(0),
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mChannelMaskPresent(false),
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mChannelMask(0),
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mDequeueCounter(0),
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mStoreMetaDataInOutputBuffers(false),
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mMetaDataBuffersToSubmit(0),
37644deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten      mRepeatFrameDelayUs(-1ll),
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mMaxPtsGapUs(-1l),
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mCreateInputBuffersSuspended(false) {
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mUninitializedState = new UninitializedState(this);
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLoadedState = new LoadedState(this);
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLoadedToIdleState = new LoadedToIdleState(this);
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mIdleToExecutingState = new IdleToExecutingState(this);
38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mExecutingState = new ExecutingState(this);
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mOutputPortSettingsChangedState =
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        new OutputPortSettingsChangedState(this);
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mExecutingToIdleState = new ExecutingToIdleState(this);
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mIdleToLoadedState = new IdleToLoadedState(this);
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mFlushingState = new FlushingState(this);
39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mInputEOSResult = OK;
39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    changeState(mUninitializedState);
39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianACodec::~ACodec() {
39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mNotify = msg;
40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::initiateSetup(const sp<AMessage> &msg) {
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setWhat(kWhatSetup);
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setTarget(id());
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->post();
409799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
410799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
411a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentvoid ACodec::signalSetParameters(const sp<AMessage> &params) {
412799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setMessage("params", params);
41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->post();
41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setWhat(kWhatAllocateComponent);
41998ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    msg->setTarget(id());
42098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    msg->post();
42198ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten}
42298ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten
42398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kastenvoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
42498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    msg->setWhat(kWhatConfigureComponent);
42598ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    msg->setTarget(id());
42698ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    msg->post();
42798ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten}
42898ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten
42998ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kastenvoid ACodec::initiateCreateInputSurface() {
43098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    (new AMessage(kWhatCreateInputSurface, id()))->post();
43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::signalEndOfInputStream() {
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
437fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenvoid ACodec::initiateStart() {
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    (new AMessage(kWhatStart, id()))->post();
43958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten}
4400d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::signalFlush() {
442a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten    ALOGV("[%s] signalFlush", mComponentName.c_str());
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    (new AMessage(kWhatFlush, id()))->post();
44472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten}
4453acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::signalResume() {
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    (new AMessage(kWhatResume, id()))->post();
44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::initiateShutdown(bool keepComponentAllocated) {
45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->post();
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
455263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten
456263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kastenvoid ACodec::signalRequestIDRFrame() {
457263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    (new AMessage(kWhatRequestIDRFrame, id()))->post();
45829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block}
45965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Some codecs may return input buffers before having them processed.
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// This causes a halt if we already signaled an EOS on the input
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// port.  For now keep submitting an output buffer if there was an
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// EOS on the input port, but not yet on the output port.
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
46639e94f8f723d445447fdee0822291e664b631f60Eric Laurent    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mMetaDataBuffersToSubmit > 0) {
46829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
47398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    CHECK(mDealer[portIndex] == NULL);
476fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    CHECK(mBuffers[portIndex].isEmpty());
477de070137f11d346fba77605bd76a44c040a618fcEric Laurent
47839e94f8f723d445447fdee0822291e664b631f60Eric Laurent    status_t err;
47939e94f8f723d445447fdee0822291e664b631f60Eric Laurent    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
48039e94f8f723d445447fdee0822291e664b631f60Eric Laurent        if (mStoreMetaDataInOutputBuffers) {
48139e94f8f723d445447fdee0822291e664b631f60Eric Laurent            err = allocateOutputMetaDataBuffers();
48239e94f8f723d445447fdee0822291e664b631f60Eric Laurent        } else {
48329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            err = allocateOutputBuffersFromNativeWindow();
48439e94f8f723d445447fdee0822291e664b631f60Eric Laurent        }
48539e94f8f723d445447fdee0822291e664b631f60Eric Laurent    } else {
48639e94f8f723d445447fdee0822291e664b631f60Eric Laurent        OMX_PARAM_PORTDEFINITIONTYPE def;
48739e94f8f723d445447fdee0822291e664b631f60Eric Laurent        InitOMXParams(&def);
48839e94f8f723d445447fdee0822291e664b631f60Eric Laurent        def.nPortIndex = portIndex;
48939e94f8f723d445447fdee0822291e664b631f60Eric Laurent
49039e94f8f723d445447fdee0822291e664b631f60Eric Laurent        err = mOMX->getParameter(
491de070137f11d346fba77605bd76a44c040a618fcEric Laurent                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
492de070137f11d346fba77605bd76a44c040a618fcEric Laurent
49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err == OK) {
49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
495de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    mComponentName.c_str(),
4967c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                    def.nBufferCountActual, def.nBufferSize,
49765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    portIndex == kPortIndexInput ? "input" : "output");
49865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
50065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
5013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
50265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
50365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5043acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                CHECK(mem.get() != NULL);
50539e94f8f723d445447fdee0822291e664b631f60Eric Laurent
50639e94f8f723d445447fdee0822291e664b631f60Eric Laurent                BufferInfo info;
50739e94f8f723d445447fdee0822291e664b631f60Eric Laurent                info.mStatus = BufferInfo::OWNED_BY_US;
50839e94f8f723d445447fdee0822291e664b631f60Eric Laurent
50939e94f8f723d445447fdee0822291e664b631f60Eric Laurent                uint32_t requiresAllocateBufferBit =
51039e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    (portIndex == kPortIndexInput)
51139e94f8f723d445447fdee0822291e664b631f60Eric Laurent                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
51239e94f8f723d445447fdee0822291e664b631f60Eric Laurent                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
513a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
514a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
515a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                        || mUseMetadataOnEncoderOutput) {
516a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    mem.clear();
517a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
518a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    void *ptr;
519a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    err = mOMX->allocateBuffer(
520a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
521a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                            &ptr);
522a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
523a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
52465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
52565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
52665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    info.mData = new ABuffer(ptr, bufSize);
52765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                } else if (mQuirks & requiresAllocateBufferBit) {
52865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    err = mOMX->allocateBufferWithBackup(
52965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mNode, portIndex, mem, &info.mBufferID);
53065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                } else {
53165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
53265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
53365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
53465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (mem != NULL) {
535e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
53865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mBuffers[portIndex].push(info);
53965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
54065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
54172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    }
54265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
5465ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block
54765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> notify = mNotify->dup();
54865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
54965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->setInt32("portIndex", portIndex);
55165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    sp<PortDescription> desc = new PortDescription;
55365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const BufferInfo &info = mBuffers[portIndex][i];
55665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5575ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        desc->addBuffer(info.mBufferID, info.mData);
55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->setObject("portDesc", desc);
56165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->post();
56265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    return OK;
56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::configureOutputBuffersFromNativeWindow(
56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
5685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        OMX_U32 *minUndequeuedBuffers) {
56958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten    OMX_PARAM_PORTDEFINITIONTYPE def;
57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    InitOMXParams(&def);
57165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    def.nPortIndex = kPortIndexOutput;
57265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
57365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = mOMX->getParameter(
57472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
57565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
57665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
57765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
5795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block
58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = native_window_set_buffers_geometry(
58165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNativeWindow.get(),
58258912562617941964939a4182cda71eaeb153d4bGlenn Kasten            def.format.video.nFrameWidth,
58358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            def.format.video.nFrameHeight,
58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            def.format.video.eColorFormat);
58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != 0) {
58772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                strerror(-err), -err);
58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5925ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    // Set up the native window.
59365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_U32 usage = 0;
59465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
59565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != 0) {
59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGW("querying usage flags from OMX IL component failed: %d", err);
59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // XXX: Currently this error is logged, but not fatal.
59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usage = 0;
59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
600a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
601a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (mFlags & kFlagIsSecure) {
602a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        usage |= GRALLOC_USAGE_PROTECTED;
603a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
604a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
60565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Make sure to check whether either Stagefright or the video decoder
60665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // requested protected buffers.
60765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (usage & GRALLOC_USAGE_PROTECTED) {
60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Verify that the ANativeWindow sends images directly to
60965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // SurfaceFlinger.
6104ff14bae91075eb274eb1c2975982358946e7e63John Grossman        int queuesToNativeWindow = 0;
6114ff14bae91075eb274eb1c2975982358946e7e63John Grossman        err = mNativeWindow->query(
612a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
613a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                &queuesToNativeWindow);
61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != 0) {
6154ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGE("error authenticating native window: %d", err);
6164ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return err;
6174ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
618a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        if (queuesToNativeWindow != 1) {
6194ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGE("native window could not be authenticated");
6204ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return PERMISSION_DENIED;
6214ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
6224ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
6234ff14bae91075eb274eb1c2975982358946e7e63John Grossman
6244ff14bae91075eb274eb1c2975982358946e7e63John Grossman    err = native_window_set_usage(
625935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent            mNativeWindow.get(),
6264ff14bae91075eb274eb1c2975982358946e7e63John Grossman            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
6274ff14bae91075eb274eb1c2975982358946e7e63John Grossman
62865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != 0) {
62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
6304ff14bae91075eb274eb1c2975982358946e7e63John Grossman        return err;
6314ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
6328d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten
633e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    *minUndequeuedBuffers = 0;
63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = mNativeWindow->query(
63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (int *)minUndequeuedBuffers);
63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
638f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kasten    if (err != 0) {
63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
640a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent                strerror(-err), -err);
641a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return err;
642a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
643a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // buffer counts refer to - how do they account for the renderer holding on
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // to buffers?
64765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
649930f4caa1e311ef7ff538c421a324396157eb24fGlenn Kasten        def.nBufferCountActual = newBufferCount;
6505ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        err = mOMX->setParameter(
65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
65265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != OK) {
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mComponentName.c_str(), newBufferCount, err);
65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return err;
657799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = native_window_set_buffer_count(
66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNativeWindow.get(), def.nBufferCountActual);
66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != 0) {
6648d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
665e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                -err);
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    *bufferCount = def.nBufferCountActual;
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    *bufferSize =  def.nBufferSize;
67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return err;
67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
673a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
674a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurentstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
675a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
676a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t err = configureOutputBuffersFromNativeWindow(
677a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent            &bufferCount, &bufferSize, &minUndequeuedBuffers);
67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != 0)
67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian         "output port",
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian         mComponentName.c_str(), bufferCount, bufferSize);
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
685a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    // Dequeue buffers and send them to OMX
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (OMX_U32 i = 0; i < bufferCount; i++) {
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ANativeWindowBuffer *buf;
68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
68965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != 0) {
69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
692a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        }
693a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
694a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
695a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        BufferInfo info;
696a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        info.mStatus = BufferInfo::OWNED_BY_US;
697fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
6982b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten        info.mGraphicBuffer = graphicBuffer;
69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mBuffers[kPortIndexOutput].push(info);
700799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
70165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        IOMX::buffer_id bufferId;
70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                &bufferId);
70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != 0) {
70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                 "%d", i, err);
70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
712935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
71399e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten             mComponentName.c_str(),
71465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             bufferId, graphicBuffer.get());
7158d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    }
716e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
71765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_U32 cancelStart;
71865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_U32 cancelEnd;
71965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
72065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != 0) {
72165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // If an error occurred while dequeuing we need to cancel any buffers
72265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // that were dequeued.
7239806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten        cancelStart = 0;
7249806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten        cancelEnd = mBuffers[kPortIndexOutput].size();
72565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
72665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Return the required minimum undequeued buffers to the native window.
7274ff14bae91075eb274eb1c2975982358946e7e63John Grossman        cancelStart = bufferCount - minUndequeuedBuffers;
7284ff14bae91075eb274eb1c2975982358946e7e63John Grossman        cancelEnd = bufferCount;
7294ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
7304ff14bae91075eb274eb1c2975982358946e7e63John Grossman
7314ff14bae91075eb274eb1c2975982358946e7e63John Grossman    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
7324ff14bae91075eb274eb1c2975982358946e7e63John Grossman        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
73365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        cancelBufferToNativeWindow(info);
73465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
7359806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten
7369806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return err;
73765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
73865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7394ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t ACodec::allocateOutputMetaDataBuffers() {
7404ff14bae91075eb274eb1c2975982358946e7e63John Grossman    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
7414ff14bae91075eb274eb1c2975982358946e7e63John Grossman    status_t err = configureOutputBuffersFromNativeWindow(
7424ff14bae91075eb274eb1c2975982358946e7e63John Grossman            &bufferCount, &bufferSize, &minUndequeuedBuffers);
7434ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (err != 0)
7444ff14bae91075eb274eb1c2975982358946e7e63John Grossman        return err;
7454ff14bae91075eb274eb1c2975982358946e7e63John Grossman
7465798d4ebf236357a4b13246f40e52b90a34d09a4Glenn Kasten    ALOGV("[%s] Allocating %lu meta buffers on output port",
7475798d4ebf236357a4b13246f40e52b90a34d09a4Glenn Kasten         mComponentName.c_str(), bufferCount);
7485798d4ebf236357a4b13246f40e52b90a34d09a4Glenn Kasten
7494ff14bae91075eb274eb1c2975982358946e7e63John Grossman    size_t totalSize = bufferCount * 8;
7504ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
7514ff14bae91075eb274eb1c2975982358946e7e63John Grossman
7524ff14bae91075eb274eb1c2975982358946e7e63John Grossman    // Dequeue buffers and send them to OMX
7534ff14bae91075eb274eb1c2975982358946e7e63John Grossman    for (OMX_U32 i = 0; i < bufferCount; i++) {
7544ff14bae91075eb274eb1c2975982358946e7e63John Grossman        BufferInfo info;
7554ff14bae91075eb274eb1c2975982358946e7e63John Grossman        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
7564ff14bae91075eb274eb1c2975982358946e7e63John Grossman        info.mGraphicBuffer = NULL;
7574ff14bae91075eb274eb1c2975982358946e7e63John Grossman        info.mDequeuedAt = mDequeueCounter;
75872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten
75972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
76065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sizeof(struct VideoDecoderOutputMetaData));
76165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK(mem.get() != NULL);
76265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        info.mData = new ABuffer(mem->pointer(), mem->size());
76365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
76465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // we use useBuffer for metadata regardless of quirks
76565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = mOMX->useBuffer(
766263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten                mNode, kPortIndexOutput, mem, &info.mBufferID);
76729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mBuffers[kPortIndexOutput].push(info);
76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             mComponentName.c_str(), info.mBufferID, mem->pointer());
77265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
77365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
77565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return err;
77665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
77765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::submitOutputMetaDataBuffer() {
77965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(mStoreMetaDataInOutputBuffers);
78065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mMetaDataBuffersToSubmit == 0)
78165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return OK;
78265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7838d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    BufferInfo *info = dequeueBufferFromNativeWindow();
784e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (info == NULL)
78565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return ERROR_IO;
78665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
78865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
78965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    --mMetaDataBuffersToSubmit;
79165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
79265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             (status_t)OK);
793fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten
79465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
79565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
79965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
800263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten
801fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    ALOGV("[%s] Calling cancelBuffer on buffer %p",
80229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block         mComponentName.c_str(), info->mBufferID);
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int err = mNativeWindow->cancelBuffer(
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
806935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ(err, 0);
80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
809e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ANativeWindowBuffer *buf;
816263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    int fenceFd = -1;
81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(mNativeWindow.get() != NULL);
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGE("dequeueBuffer failed.");
82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
82165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
82265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    BufferInfo *oldest = NULL;
82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        BufferInfo *info =
82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            &mBuffers[kPortIndexOutput].editItemAt(i);
82765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (info->mGraphicBuffer != NULL &&
8296637baae4244aec731c4014da72418d330636ae1Glenn Kasten            info->mGraphicBuffer->handle == buf->handle) {
83065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK_EQ((int)info->mStatus,
83165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
83265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            info->mStatus = BufferInfo::OWNED_BY_US;
83465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
835fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten            return info;
83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
837263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (oldest == NULL ||
84065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             // avoid potential issues from counter rolling over
8416637baae4244aec731c4014da72418d330636ae1Glenn Kasten             mDequeueCounter - info->mDequeuedAt >
8426637baae4244aec731c4014da72418d330636ae1Glenn Kasten                    mDequeueCounter - oldest->mDequeuedAt)) {
84365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            oldest = info;
84465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
84572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    }
84665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84723d82a9bc9a43b49ba684ba40875b91db310d3b9Glenn Kasten    if (oldest) {
84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK(mStoreMetaDataInOutputBuffers);
84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // discard buffer in LRU info and replace with new buffer
85165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        oldest->mStatus = BufferInfo::OWNED_BY_US;
85365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mOMX->updateGraphicBufferInMeta(
85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
856a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                oldest->mBufferID);
857799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
8588abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        VideoDecoderOutputMetaData *metaData =
859a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            reinterpret_cast<VideoDecoderOutputMetaData *>(
860a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                    oldest->mData->base());
861a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
862a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
863a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
864a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                oldest - &mBuffers[kPortIndexOutput][0],
865a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                mDequeueCounter - oldest->mDequeuedAt,
866a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                metaData->pHandle,
8678abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten                oldest->mGraphicBuffer->handle, oldest->mData->base());
86859bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent
86959bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        return oldest;
87059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    }
87159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent
872bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent    TRESPASS();
873bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent
87459bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    return NULL;
87559bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent}
87659bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent
87759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurentstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
87859bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
87959bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
880bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent    }
88159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent
88259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    mDealer[portIndex].clear();
88359bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent
88459bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    return OK;
88559bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent}
88659bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent
88759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurentstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
88859bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
889bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent        BufferInfo *info =
89059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent            &mBuffers[kPortIndexOutput].editItemAt(i);
89159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent
892799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        // At this time some buffers may still be with the component
89365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // or being drained.
89465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9037fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kastenstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
9047c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
9057c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
9067c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
90789d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
90889d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent
9097c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
9107c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            && info->mStatus == BufferInfo::OWNED_BY_US) {
9117c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
9127c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ(mOMX->freeBuffer(
9157378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten                mNode, portIndex, info->mBufferID),
9167378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten             (status_t)OK);
91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mBuffers[portIndex].removeAt(i);
91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
92065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
92172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten}
92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
92323d82a9bc9a43b49ba684ba40875b91db310d3b9Glenn KastenACodec::BufferInfo *ACodec::findBufferByID(
92465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t portIndex, IOMX::buffer_id bufferID,
92565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ssize_t *index) {
926a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
927a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
929fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (info->mBufferID == bufferID) {
930fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            if (index != NULL) {
931799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                *index = i;
9328abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            }
9338abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            return info;
9348abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        }
9358abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    }
936a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
9378abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    TRESPASS();
9388abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten
9398abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    return NULL;
940ef7740be67a4d7b6b033ebed59c3d4a9c74a2c18John Grossman}
941799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
942799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinstatus_t ACodec::setComponentRole(
943fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        bool isEncoder, const char *mime) {
94465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    struct MimeToRole {
94565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const char *mime;
94665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const char *decoderRole;
94765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const char *encoderRole;
94865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    };
94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    static const MimeToRole kMimeToRole[] = {
95165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_AUDIO_MPEG,
95265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "audio_decoder.mp3", "audio_encoder.mp3" },
95365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
95465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "audio_decoder.mp1", "audio_encoder.mp1" },
95565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "audio_decoder.mp2", "audio_encoder.mp2" },
957f587ba5b991c7cd91e4df093d0d796bd419e5d67Glenn Kasten        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "audio_decoder.amrnb", "audio_encoder.amrnb" },
959a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
960a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent            "audio_decoder.amrwb", "audio_encoder.amrwb" },
961a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        { MEDIA_MIMETYPE_AUDIO_AAC,
962a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent            "audio_decoder.aac", "audio_encoder.aac" },
963a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        { MEDIA_MIMETYPE_AUDIO_VORBIS,
9642b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten            "audio_decoder.vorbis", "audio_encoder.vorbis" },
9652b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten        { MEDIA_MIMETYPE_AUDIO_OPUS,
966f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            "audio_decoder.opus", "audio_encoder.opus" },
967f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
968f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
969f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
970f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
971f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        { MEDIA_MIMETYPE_VIDEO_AVC,
9722b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten            "video_decoder.avc", "video_encoder.avc" },
9732b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten        { MEDIA_MIMETYPE_VIDEO_MPEG4,
97465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "video_decoder.mpeg4", "video_encoder.mpeg4" },
97565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_VIDEO_H263,
97672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten            "video_decoder.h263", "video_encoder.h263" },
97765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_VIDEO_VP8,
97865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "video_decoder.vp8", "video_encoder.vp8" },
97965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_VIDEO_VP9,
98065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "video_decoder.vp9", "video_encoder.vp9" },
98165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_AUDIO_RAW,
98265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "audio_decoder.raw", "audio_encoder.raw" },
98365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_AUDIO_FLAC,
98465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "audio_decoder.flac", "audio_encoder.flac" },
98565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_AUDIO_MSGSM,
98665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "audio_decoder.gsm", "audio_encoder.gsm" },
98765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_VIDEO_MPEG2,
98865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "video_decoder.mpeg2", "video_encoder.mpeg2" },
98965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { MEDIA_MIMETYPE_AUDIO_AC3,
99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "audio_decoder.ac3", "audio_encoder.ac3" },
99165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    };
99265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
993a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    static const size_t kNumMimeToRole =
994a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
995a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
996a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    size_t i;
997a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    for (i = 0; i < kNumMimeToRole; ++i) {
99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
100365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (i == kNumMimeToRole) {
10048abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        return ERROR_UNSUPPORTED;
1005a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const char *role =
100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        isEncoder ? kMimeToRole[i].encoderRole
100965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  : kMimeToRole[i].decoderRole;
101065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    if (role != NULL) {
101272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        OMX_PARAM_COMPONENTROLETYPE roleParams;
101365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        InitOMXParams(&roleParams);
101465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        strncpy((char *)roleParams.cRole,
101665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                role, OMX_MAX_STRINGNAME_SIZE - 1);
101765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
101965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t err = mOMX->setParameter(
102165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mNode, OMX_IndexParamStandardComponentRole,
102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                &roleParams, sizeof(roleParams));
102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != OK) {
102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGW("[%s] Failed to set standard component role '%s'.",
102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                 mComponentName.c_str(), role);
102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return err;
102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1031bb001926447d0b7dc71ca8bb3c9856f3136d8f4cGlenn Kasten
103265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::configureCodec(
10363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        const char *mime, const sp<AMessage> &msg) {
103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t encoder;
103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!msg->findInt32("encoder", &encoder)) {
103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        encoder = false;
104065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
104165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mIsEncoder = encoder;
104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = setComponentRole(encoder /* isEncoder */, mime);
104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t bitRate = 0;
105165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // FLAC encoder doesn't need a bitrate, other encoders do
105265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
105365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            && !msg->findInt32("bitrate", &bitRate)) {
105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return INVALID_OPERATION;
105565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t storeMeta;
105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (encoder
1059a3b09254d44cd8d66ec947abe547538c4cfeaa89Glenn Kasten            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
10603a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            && storeMeta != 0) {
10613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
10628d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten
10633a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        if (err != OK) {
10648d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
10653a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                    mComponentName.c_str(), err);
1066012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten
1067012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten              return err;
1068012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten          }
10693a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen      }
10703a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
10713a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    int32_t prependSPSPPS = 0;
10723a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    if (encoder
10738d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10748d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten            && prependSPSPPS != 0) {
10753a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        OMX_INDEXTYPE index;
10763a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        err = mOMX->getExtensionIndex(
10773a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                mNode,
10783a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10793a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                &index);
108065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
108165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err == OK) {
108265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            PrependSPSPPSToIDRFramesParams params;
1083b81cc8c6f3eec9edb255ea99b6a6f243585b1e38Glenn Kasten            InitOMXParams(&params);
108465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            params.bEnable = OMX_TRUE;
108565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
108665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = mOMX->setParameter(
108784afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten                    mNode, index, &params, sizeof(params));
108884afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        }
108965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
109065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != OK) {
109165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("Encoder could not be configured to emit SPS/PPS before "
109265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  "IDR frames. (err %d)", err);
109365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
109465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return err;
10953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        }
109665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
109765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
109865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Only enable metadata mode on encoder output if encoder can prepend
109965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // sps/pps to idr frames, since in metadata mode the bitstream is in an
110065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // opaque handle, to which we don't have access.
110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t video = !strncasecmp(mime, "video/", 6);
110272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    if (encoder && video) {
110372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
110465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
110523bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten            && storeMeta != 0);
110658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
110784afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
110884afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten
110984afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        if (err != OK) {
111084afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1111b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten                mComponentName.c_str(), err);
111284afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten            mUseMetadataOnEncoderOutput = 0;
111384afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        } else {
111465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mUseMetadataOnEncoderOutput = enable;
111565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
111665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
111765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!msg->findInt64(
111865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    "repeat-previous-frame-after",
111965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    &mRepeatFrameDelayUs)) {
1120feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            mRepeatFrameDelayUs = -1ll;
1121feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
11229d18ec574f5d847a86a21594ac39394ef5b108fcEric Laurent
11239d18ec574f5d847a86a21594ac39394ef5b108fcEric Laurent        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11249d18ec574f5d847a86a21594ac39394ef5b108fcEric Laurent            mMaxPtsGapUs = -1l;
11259d18ec574f5d847a86a21594ac39394ef5b108fcEric Laurent        }
112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!msg->findInt32(
112865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    "create-input-buffers-suspended",
112965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    (int32_t*)&mCreateInputBuffersSuspended)) {
11303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            mCreateInputBuffersSuspended = false;
113165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
1132b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    }
1133b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten
1134b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    // Always try to enable dynamic output buffers on native surface
1135b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    sp<RefBase> obj;
1136b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1137b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten            obj != NULL;
1138b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    mStoreMetaDataInOutputBuffers = false;
1139b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    mIsConfiguredForAdaptivePlayback = false;
1140b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    if (!encoder && video && haveNativeWindow) {
1141a7d8d6fc5e102a08b262a1b78aa1abeeb097d9e4Glenn Kasten        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
114265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != OK) {
114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
114465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  mComponentName.c_str(), err);
1145b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten
1146b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten            // if adaptive playback has been requested, try JB fallback
114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
114865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // LARGE MEMORY REQUIREMENT
114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // we will not do adaptive playback on software accessed
115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // surfaces as they never had to respond to changes in the
115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // crop window, and we don't trust that they will be able to.
115365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int usageBits = 0;
11543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            bool canDoAdaptivePlayback;
115565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<NativeWindowWrapper> windowWrapper(
115765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    static_cast<NativeWindowWrapper *>(obj.get()));
115865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
115965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (nativeWindow->query(
11617dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten                    nativeWindow.get(),
116265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
116365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    &usageBits) != OK) {
116465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                canDoAdaptivePlayback = false;
116565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                canDoAdaptivePlayback =
116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    (usageBits &
116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            (GRALLOC_USAGE_SW_READ_MASK |
116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int32_t maxWidth = 0, maxHeight = 0;
117365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (canDoAdaptivePlayback &&
117465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                msg->findInt32("max-width", &maxWidth) &&
117565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                msg->findInt32("max-height", &maxHeight)) {
117665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
117765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                      mComponentName.c_str(), maxWidth, maxHeight);
117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1179f3990f2cc8fd824ae52a880a7b22248e1bdfb192Glenn Kasten                err = mOMX->prepareForAdaptivePlayback(
1180f3990f2cc8fd824ae52a880a7b22248e1bdfb192Glenn Kasten                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1181f3990f2cc8fd824ae52a880a7b22248e1bdfb192Glenn Kasten                ALOGW_IF(err != OK,
118265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
11833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                        mComponentName.c_str(), err);
118465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mIsConfiguredForAdaptivePlayback = (err == OK);
118565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
118665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // allow failure
118765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = OK;
118865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
118965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1190e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mStoreMetaDataInOutputBuffers = true;
11913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            mIsConfiguredForAdaptivePlayback = true;
1192f3990f2cc8fd824ae52a880a7b22248e1bdfb192Glenn Kasten        }
119365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t push;
119565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
119665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                && push != 0) {
119765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1198f3990f2cc8fd824ae52a880a7b22248e1bdfb192Glenn Kasten        }
119965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
120065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (video) {
120265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (encoder) {
120365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = setupVideoEncoder(mime, msg);
120465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
120565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int32_t width, height;
120665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!msg->findInt32("width", &width)
120765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    || !msg->findInt32("height", &height)) {
120865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                err = INVALID_OPERATION;
120965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
121065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                err = setupVideoDecoder(mime, width, height);
121165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
121265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
121365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
121465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t numChannels, sampleRate;
121565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!msg->findInt32("channel-count", &numChannels)
121665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                || !msg->findInt32("sample-rate", &sampleRate)) {
1217612bbb57c59397a540e96f06bdd16e437a583af5Eric Laurent            // Since we did not always check for these, leave them optional
1218612bbb57c59397a540e96f06bdd16e437a583af5Eric Laurent            // and have the decoder figure it all out.
1219612bbb57c59397a540e96f06bdd16e437a583af5Eric Laurent            err = OK;
1220612bbb57c59397a540e96f06bdd16e437a583af5Eric Laurent        } else {
122165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = setupRawAudioFormat(
122265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    encoder ? kPortIndexInput : kPortIndexOutput,
122365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    sampleRate,
122465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    numChannels);
122558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
122658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
122758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        int32_t numChannels, sampleRate;
122865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!msg->findInt32("channel-count", &numChannels)
122965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                || !msg->findInt32("sample-rate", &sampleRate)) {
123065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = INVALID_OPERATION;
12310d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        } else {
12320d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            int32_t isADTS, aacProfile;
123365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!msg->findInt32("is-adts", &isADTS)) {
123465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                isADTS = 0;
1235b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kasten            }
123665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!msg->findInt32("aac-profile", &aacProfile)) {
123765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                aacProfile = OMX_AUDIO_AACObjectNull;
123865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
123965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
124065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = setupAACCodec(
124165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    encoder, numChannels, sampleRate, bitRate, aacProfile,
124265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    isADTS != 0);
124365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
124465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
124565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
124665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
124765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
124865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
124965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
125065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // These are PCM-like formats with a fixed sample rate but
125165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // a variable number of channels.
1252f3990f2cc8fd824ae52a880a7b22248e1bdfb192Glenn Kasten
125365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t numChannels;
125465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!msg->findInt32("channel-count", &numChannels)) {
125565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = INVALID_OPERATION;
125665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
125765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = setupG711Codec(encoder, numChannels);
125865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
126065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t numChannels, sampleRate, compressionLevel = -1;
126165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (encoder &&
126265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                (!msg->findInt32("channel-count", &numChannels)
126365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        || !msg->findInt32("sample-rate", &sampleRate))) {
126465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("missing channel count or sample rate for FLAC encoder");
12651d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent            err = INVALID_OPERATION;
12661d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        } else {
12671d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent            if (encoder) {
12681d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                if (!msg->findInt32(
12691d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                            "flac-compression-level", &compressionLevel)) {
12701d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                    compressionLevel = 5;// default FLAC compression level
12711d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                } else if (compressionLevel < 0) {
12721d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                    ALOGW("compression level %d outside [0..8] range, "
12731d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                          "using 0",
12741d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                          compressionLevel);
12751d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                    compressionLevel = 0;
12761d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                } else if (compressionLevel > 8) {
12771d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                    ALOGW("compression level %d outside [0..8] range, "
12781d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                          "using 8",
12791d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                          compressionLevel);
12801d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                    compressionLevel = 8;
12811d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent                }
12821d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent            }
1283feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            err = setupFlacCodec(
1284feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                    encoder, numChannels, sampleRate, compressionLevel);
1285feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1286feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1287feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        int32_t numChannels, sampleRate;
1288feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (encoder
1289feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                || !msg->findInt32("channel-count", &numChannels)
1290feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                || !msg->findInt32("sample-rate", &sampleRate)) {
1291feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            err = INVALID_OPERATION;
1292feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        } else {
1293feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1294feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1295feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
12965ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        int32_t numChannels;
1297feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        int32_t sampleRate;
1298feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (!msg->findInt32("channel-count", &numChannels)
1299feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                || !msg->findInt32("sample-rate", &sampleRate)) {
1300feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            err = INVALID_OPERATION;
1301feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        } else {
1302feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            err = setupAC3Codec(encoder, numChannels, sampleRate);
1303feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1304feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1305feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1306feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (err != OK) {
1307feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        return err;
1308feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1309feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
13103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
1311feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        mEncoderDelay = 0;
1312feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1313feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1314feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
1315feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        mEncoderPadding = 0;
1316feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
13176dbe883644940badc684957cfc381bfd115f205eEric Laurent
1318feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (msg->findInt32("channel-mask", &mChannelMask)) {
1319feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        mChannelMaskPresent = true;
1320feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    } else {
1321feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        mChannelMaskPresent = false;
1322feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
13233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1324feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    int32_t maxInputSize;
1325feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (msg->findInt32("max-input-size", &maxInputSize)) {
1326feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1327feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
1328feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1329feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1330feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1331feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    return err;
1332feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1333feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1334feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1335feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    OMX_PARAM_PORTDEFINITIONTYPE def;
1336feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    InitOMXParams(&def);
1337feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    def.nPortIndex = portIndex;
1338feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1339feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    status_t err = mOMX->getParameter(
1340feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1341feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1342feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (err != OK) {
1343feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        return err;
13445ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    }
1345feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
13461d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    if (def.nBufferSize >= size) {
134759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        return OK;
134859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
134959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
135059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    def.nBufferSize = size;
135159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
135259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    err = mOMX->setParameter(
135359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
135459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
135559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (err != OK) {
135659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        return err;
1357090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    }
135859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
135959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    err = mOMX->getParameter(
136059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
136159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
136259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (err != OK) {
136359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        return err;
136459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
136559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
136659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    CHECK(def.nBufferSize >= size);
136759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
136859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    return OK;
136959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
137059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
13718d6a2449a91f5116d7243ab039393195ebd663feGlenn Kastenstatus_t ACodec::selectAudioPortFormat(
137259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
137359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
137459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    InitOMXParams(&format);
137559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
137659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    format.nPortIndex = portIndex;
137759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    for (OMX_U32 index = 0;; ++index) {
137859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        format.nIndex = index;
137959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
1380e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        status_t err = mOMX->getParameter(
138159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                mNode, OMX_IndexParamAudioPortFormat,
138259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                &format, sizeof(format));
138359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
138459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (err != OK) {
13853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            return err;
1386e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        }
138759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
138859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (format.eEncoding == desiredFormat) {
138959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            break;
139059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
139159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
139259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
139359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    return mOMX->setParameter(
139459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
139559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
139659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
13978d6a2449a91f5116d7243ab039393195ebd663feGlenn Kastenstatus_t ACodec::setupAACCodec(
139859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        bool encoder, int32_t numChannels, int32_t sampleRate,
139959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        int32_t bitRate, int32_t aacProfile, bool isADTS) {
140059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (encoder && isADTS) {
140159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        return -EINVAL;
140259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
140359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
140459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    status_t err = setupRawAudioFormat(
140559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            encoder ? kPortIndexInput : kPortIndexOutput,
140659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            sampleRate,
140759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            numChannels);
140859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
140959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (err != OK) {
141059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        return err;
141159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
141259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
141359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (encoder) {
141459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
141559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
141659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (err != OK) {
141759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return err;
141859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
141959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
142059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        OMX_PARAM_PORTDEFINITIONTYPE def;
1421e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        InitOMXParams(&def);
142259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        def.nPortIndex = kPortIndexOutput;
142359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
142459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        err = mOMX->getParameter(
142559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
142659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
142759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (err != OK) {
142859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return err;
142959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
143059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
14313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
143259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
143359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
143459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        err = mOMX->setParameter(
143559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
143659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
143759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (err != OK) {
143859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return err;
143959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
14403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
144159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
144259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        InitOMXParams(&profile);
14433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        profile.nPortIndex = kPortIndexOutput;
144459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
144559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        err = mOMX->getParameter(
144659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
144759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
144859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (err != OK) {
144959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return err;
145059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
145159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
145259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        profile.nChannels = numChannels;
145359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
145459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        profile.eChannelMode =
145559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            (numChannels == 1)
145659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
145759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
145859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        profile.nSampleRate = sampleRate;
1459a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent        profile.nBitRate = bitRate;
1460a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent        profile.nAudioBandWidth = 0;
146159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        profile.nFrameLength = 0;
1462a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent        profile.nAACtools = OMX_AUDIO_AACToolAll;
1463a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent        profile.nAACERtools = OMX_AUDIO_AACERNone;
1464a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
1465a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1466db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent
1467db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        err = mOMX->setParameter(
1468db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1469db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent
1470808e7d16504cbe5b28bb88c31afb2542ab488965Eric Laurent        if (err != OK) {
1471808e7d16504cbe5b28bb88c31afb2542ab488965Eric Laurent            return err;
1472808e7d16504cbe5b28bb88c31afb2542ab488965Eric Laurent        }
1473db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent
1474db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        return err;
1475db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    }
147659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
147759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
147859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    InitOMXParams(&profile);
147959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    profile.nPortIndex = kPortIndexInput;
148059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
148159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    err = mOMX->getParameter(
148259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
148365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
148465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
14857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return err;
14867c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
148772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten
148823bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten    profile.nChannels = numChannels;
148923bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten    profile.nSampleRate = sampleRate;
149023bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten
149184afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    profile.eAACStreamFormat =
149284afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        isADTS
149384afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten            ? OMX_AUDIO_AACStreamFormatMP4ADTS
149484afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten            : OMX_AUDIO_AACStreamFormatMP4FF;
149584afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten
149684afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    return mOMX->setParameter(
149784afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
149884afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten}
14994ff14bae91075eb274eb1c2975982358946e7e63John Grossman
1500fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kastenstatus_t ACodec::setupAC3Codec(
1501aa4397f07c43bd83bc3100b749401dc3d15e7622Glenn Kasten        bool encoder, int32_t numChannels, int32_t sampleRate) {
1502810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten    status_t err = setupRawAudioFormat(
150358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
1504288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
1505288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (err != OK) {
150665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
1507480b46802bef1371d5caa16ad5454fce04769c57Glenn Kasten    }
1508feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
150965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (encoder) {
151065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGW("AC3 encoding is not supported.");
1511263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten        return INVALID_OPERATION;
1512fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    }
1513fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten
1514fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
15156637baae4244aec731c4014da72418d330636ae1Glenn Kasten    InitOMXParams(&def);
15166637baae4244aec731c4014da72418d330636ae1Glenn Kasten    def.nPortIndex = kPortIndexInput;
151765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
15186637baae4244aec731c4014da72418d330636ae1Glenn Kasten    err = mOMX->getParameter(
15196637baae4244aec731c4014da72418d330636ae1Glenn Kasten            mNode,
152065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
152165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            &def,
152265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sizeof(def));
152365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
152465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
152565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
152665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
152765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
152865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    def.nChannels = numChannels;
152965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    def.nSampleRate = sampleRate;
153065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
153165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mOMX->setParameter(
153265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNode,
153365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
153465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            &def,
153565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sizeof(def));
153665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
153765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
153865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
153965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool isAMRWB, int32_t bps) {
154065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (isAMRWB) {
154158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (bps <= 6600) {
154258912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return OMX_AUDIO_AMRBandModeWB0;
154358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else if (bps <= 8850) {
154458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return OMX_AUDIO_AMRBandModeWB1;
154558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else if (bps <= 12650) {
154658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return OMX_AUDIO_AMRBandModeWB2;
154758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else if (bps <= 14250) {
154858912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return OMX_AUDIO_AMRBandModeWB3;
154958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else if (bps <= 15850) {
155058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return OMX_AUDIO_AMRBandModeWB4;
155158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else if (bps <= 18250) {
155258912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return OMX_AUDIO_AMRBandModeWB5;
155358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else if (bps <= 19850) {
155458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return OMX_AUDIO_AMRBandModeWB6;
155558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else if (bps <= 23050) {
155665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return OMX_AUDIO_AMRBandModeWB7;
155765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
1558288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
155965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // 23850 bps
156065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return OMX_AUDIO_AMRBandModeWB8;
156165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {  // AMRNB
156265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (bps <= 4750) {
156365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return OMX_AUDIO_AMRBandModeNB0;
156465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else if (bps <= 5150) {
156565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return OMX_AUDIO_AMRBandModeNB1;
156665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else if (bps <= 5900) {
156765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return OMX_AUDIO_AMRBandModeNB2;
156865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else if (bps <= 6700) {
1569288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            return OMX_AUDIO_AMRBandModeNB3;
157065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else if (bps <= 7400) {
157177c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            return OMX_AUDIO_AMRBandModeNB4;
157277c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        } else if (bps <= 7950) {
157377c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            return OMX_AUDIO_AMRBandModeNB5;
157477c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        } else if (bps <= 10200) {
157565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return OMX_AUDIO_AMRBandModeNB6;
157665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
157765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
157865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // 12200 bps
157965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return OMX_AUDIO_AMRBandModeNB7;
158065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
158165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
158265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
158365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
158465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_AUDIO_PARAM_AMRTYPE def;
158565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    InitOMXParams(&def);
158665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
158765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
158865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err =
158965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
159065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
159165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
159265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
159365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
159465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
159565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
159665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
159765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
159865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = mOMX->setParameter(
159965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
160065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
160165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
160265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
160365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
160465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
160565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return setupRawAudioFormat(
160665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            encoder ? kPortIndexInput : kPortIndexOutput,
160765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            isWAMR ? 16000 : 8000 /* sampleRate */,
160865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            1 /* numChannels */);
160965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
161065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1611b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurentstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
1612b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    CHECK(!encoder);  // XXX TODO
1613df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block
1614b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    return setupRawAudioFormat(
161529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            kPortIndexInput, 8000 /* sampleRate */, numChannels);
161665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
1617b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
161865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::setupFlacCodec(
161965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
162065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
162165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (encoder) {
1622feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        OMX_AUDIO_PARAM_FLACTYPE def;
162365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        InitOMXParams(&def);
162465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        def.nPortIndex = kPortIndexOutput;
162565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1626ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        // configure compression level
162765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
1628fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        if (err != OK) {
162965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
163058f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten            return err;
16310d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        }
163265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        def.nCompressionLevel = compressionLevel;
163365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
163465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != OK) {
163573d227557ba5192735356bacab9f77b44980793bGlenn Kasten            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16363acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten            return err;
163765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
163865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
163965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
164065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return setupRawAudioFormat(
164165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            encoder ? kPortIndexInput : kPortIndexOutput,
164273d227557ba5192735356bacab9f77b44980793bGlenn Kasten            sampleRate,
164373d227557ba5192735356bacab9f77b44980793bGlenn Kasten            numChannels);
164473d227557ba5192735356bacab9f77b44980793bGlenn Kasten}
1645e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
1646e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kastenstatus_t ACodec::setupRawAudioFormat(
164773d227557ba5192735356bacab9f77b44980793bGlenn Kasten        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
164873d227557ba5192735356bacab9f77b44980793bGlenn Kasten    OMX_PARAM_PORTDEFINITIONTYPE def;
164973d227557ba5192735356bacab9f77b44980793bGlenn Kasten    InitOMXParams(&def);
165073d227557ba5192735356bacab9f77b44980793bGlenn Kasten    def.nPortIndex = portIndex;
165173d227557ba5192735356bacab9f77b44980793bGlenn Kasten
165273d227557ba5192735356bacab9f77b44980793bGlenn Kasten    status_t err = mOMX->getParameter(
165373d227557ba5192735356bacab9f77b44980793bGlenn Kasten            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
165473d227557ba5192735356bacab9f77b44980793bGlenn Kasten
1655e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    if (err != OK) {
165673d227557ba5192735356bacab9f77b44980793bGlenn Kasten        return err;
16573acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    }
1658e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
1659300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
166073d227557ba5192735356bacab9f77b44980793bGlenn Kasten
166173d227557ba5192735356bacab9f77b44980793bGlenn Kasten    err = mOMX->setParameter(
166273d227557ba5192735356bacab9f77b44980793bGlenn Kasten            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
166373d227557ba5192735356bacab9f77b44980793bGlenn Kasten
166473d227557ba5192735356bacab9f77b44980793bGlenn Kasten    if (err != OK) {
166573d227557ba5192735356bacab9f77b44980793bGlenn Kasten        return err;
166673d227557ba5192735356bacab9f77b44980793bGlenn Kasten    }
166758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
166873d227557ba5192735356bacab9f77b44980793bGlenn Kasten    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
166958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    InitOMXParams(&pcmParams);
167058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    pcmParams.nPortIndex = portIndex;
167158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
167258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    err = mOMX->getParameter(
167358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
167458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
167573d227557ba5192735356bacab9f77b44980793bGlenn Kasten    if (err != OK) {
167673d227557ba5192735356bacab9f77b44980793bGlenn Kasten        return err;
1677e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    }
1678e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
1679e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    pcmParams.nChannels = numChannels;
1680300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    pcmParams.eNumData = OMX_NumericalDataSigned;
1681e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    pcmParams.bInterleaved = OMX_TRUE;
168231dfd1db7a4d2228d9642008af6f3dd744368eb6Glenn Kasten    pcmParams.nBitPerSample = 16;
1683300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    pcmParams.nSamplingRate = sampleRate;
1684e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1685e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
168658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
168758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return OMX_ErrorNone;
168858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
168958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
169058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    return mOMX->setParameter(
169173d227557ba5192735356bacab9f77b44980793bGlenn Kasten            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1692e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten}
1693e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
1694e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kastenstatus_t ACodec::setVideoPortFormatType(
1695e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        OMX_U32 portIndex,
1696e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        OMX_VIDEO_CODINGTYPE compressionFormat,
1697e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        OMX_COLOR_FORMATTYPE colorFormat) {
1698e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1699e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    InitOMXParams(&format);
1700e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    format.nPortIndex = portIndex;
1701e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    format.nIndex = 0;
1702e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    bool found = false;
1703e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
170458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    OMX_U32 index = 0;
1705e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    for (;;) {
170673d227557ba5192735356bacab9f77b44980793bGlenn Kasten        format.nIndex = index;
170773d227557ba5192735356bacab9f77b44980793bGlenn Kasten        status_t err = mOMX->getParameter(
170865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mNode, OMX_IndexParamVideoPortFormat,
17090d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                &format, sizeof(format));
17100d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
171129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        if (err != OK) {
17120d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            return err;
17130d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        }
17140d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
17150d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        // The following assertion is violated by TI's video decoder.
17160d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        // CHECK_EQ(format.nIndex, index);
171765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
171865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
171965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (portIndex == kPortIndexInput
172065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    && colorFormat == format.eColorFormat) {
172129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                // eCompressionFormat does not seem right.
172265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                found = true;
172365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
172465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
172565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (portIndex == kPortIndexOutput
172665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    && compressionFormat == format.eCompressionFormat) {
17277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                // eColorFormat does not seem right.
17287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                found = true;
172929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                break;
173065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
173165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
173265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
173365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (format.eCompressionFormat == compressionFormat
173465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            && format.eColorFormat == colorFormat) {
1735de070137f11d346fba77605bd76a44c040a618fcEric Laurent            found = true;
1736de070137f11d346fba77605bd76a44c040a618fcEric Laurent            break;
1737de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
1738de070137f11d346fba77605bd76a44c040a618fcEric Laurent
173902bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten        ++index;
1740de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
1741de070137f11d346fba77605bd76a44c040a618fcEric Laurent
1742639dbee79140956c43926344c23af765f6e0c9a5Glenn Kasten    if (!found) {
174302bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten        return UNKNOWN_ERROR;
1744d879601ace079e3c0aed79cf3fa5fb4db6ad4a9fGlenn Kasten    }
174529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
1746d879601ace079e3c0aed79cf3fa5fb4db6ad4a9fGlenn Kasten    status_t err = mOMX->setParameter(
1747de070137f11d346fba77605bd76a44c040a618fcEric Laurent            mNode, OMX_IndexParamVideoPortFormat,
1748de070137f11d346fba77605bd76a44c040a618fcEric Laurent            &format, sizeof(format));
1749de070137f11d346fba77605bd76a44c040a618fcEric Laurent
1750de070137f11d346fba77605bd76a44c040a618fcEric Laurent    return err;
1751de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
1752de070137f11d346fba77605bd76a44c040a618fcEric Laurent
17534ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t ACodec::setSupportedOutputFormat() {
17544ff14bae91075eb274eb1c2975982358946e7e63John Grossman    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
175573d227557ba5192735356bacab9f77b44980793bGlenn Kasten    InitOMXParams(&format);
17564ff14bae91075eb274eb1c2975982358946e7e63John Grossman    format.nPortIndex = kPortIndexOutput;
17574ff14bae91075eb274eb1c2975982358946e7e63John Grossman    format.nIndex = 0;
17584ff14bae91075eb274eb1c2975982358946e7e63John Grossman
17594ff14bae91075eb274eb1c2975982358946e7e63John Grossman    status_t err = mOMX->getParameter(
17604ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mNode, OMX_IndexParamVideoPortFormat,
176165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            &format, sizeof(format));
176265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ(err, (status_t)OK);
176365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
176465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
176565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mOMX->setParameter(
176665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNode, OMX_IndexParamVideoPortFormat,
176765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            &format, sizeof(format));
17683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block}
176965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
177002bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kastenstatic const struct VideoCodingMapEntry {
1771b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    const char *mMime;
177265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_VIDEO_CODINGTYPE mVideoCodingType;
177365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} kVideoCodingMapEntry[] = {
17743acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
17753acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
17763acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
17773acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
17783acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
17793acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
17803acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten};
17813acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
17823acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kastenstatic status_t GetVideoCodingTypeFromMime(
17833acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
17843acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    for (size_t i = 0;
17853acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
17863acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten         ++i) {
17873acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
178865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
178965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return OK;
179065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
1791e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
179265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
179365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    *codingType = OMX_VIDEO_CodingUnused;
179465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
179565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ERROR_UNSUPPORTED;
179665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
179765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
179865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic status_t GetMimeTypeForVideoCoding(
1799b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1800b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    for (size_t i = 0;
1801799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1802b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent         ++i) {
180365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
180465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            *mime = kVideoCodingMapEntry[i].mMime;
180565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return OK;
180665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
18076637baae4244aec731c4014da72418d330636ae1Glenn Kasten    }
180865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
18096637baae4244aec731c4014da72418d330636ae1Glenn Kasten    mime->clear();
181065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
181165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ERROR_UNSUPPORTED;
181265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
18136637baae4244aec731c4014da72418d330636ae1Glenn Kasten
181465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::setupVideoDecoder(
18156637baae4244aec731c4014da72418d330636ae1Glenn Kasten        const char *mime, int32_t width, int32_t height) {
18166637baae4244aec731c4014da72418d330636ae1Glenn Kasten    OMX_VIDEO_CODINGTYPE compressionFormat;
181765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
181865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
18196637baae4244aec731c4014da72418d330636ae1Glenn Kasten    if (err != OK) {
182065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
18216637baae4244aec731c4014da72418d330636ae1Glenn Kasten    }
182265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
182365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = setVideoPortFormatType(
182465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
18256637baae4244aec731c4014da72418d330636ae1Glenn Kasten
182665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
18276637baae4244aec731c4014da72418d330636ae1Glenn Kasten        return err;
182865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
182965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
183065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = setSupportedOutputFormat();
1831fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten
183265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
18336637baae4244aec731c4014da72418d330636ae1Glenn Kasten        return err;
183465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
183565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
183665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = setVideoFormatOnPort(
183765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            kPortIndexInput, width, height, compressionFormat);
183865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
183965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
184065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
184165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
184265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
184365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = setVideoFormatOnPort(
184465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
184565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
184665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
184765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
184865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
184965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
185065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
185165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
185265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
185365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    int32_t tmp;
1855b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    if (!msg->findInt32("color-format", &tmp)) {
185665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return INVALID_OPERATION;
185765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
185865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
185965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_COLOR_FORMATTYPE colorFormat =
186065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
186165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
18623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    status_t err = setVideoPortFormatType(
186365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
186465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
186565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
186665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGE("[%s] does not support color format %d",
186765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              mComponentName.c_str(), colorFormat);
186865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
186965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
187065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
187165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1872288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    /* Input port configuration */
187365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1874b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    OMX_PARAM_PORTDEFINITIONTYPE def;
1875b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    InitOMXParams(&def);
1876b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
1877b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1878b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
1879b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    def.nPortIndex = kPortIndexInput;
1880b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
1881b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    err = mOMX->getParameter(
1882288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1883288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
1884288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (err != OK) {
1885288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        return err;
1886288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
1887288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
1888288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    int32_t width, height, bitrate;
1889288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (!msg->findInt32("width", &width)
1890288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            || !msg->findInt32("height", &height)
1891288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            || !msg->findInt32("bitrate", &bitrate)) {
1892b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent        return INVALID_OPERATION;
1893b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    }
1894b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
189565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    video_def->nFrameWidth = width;
189665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    video_def->nFrameHeight = height;
189765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
189865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t stride;
189965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!msg->findInt32("stride", &stride)) {
1900b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        stride = width;
1901fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
1902fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1903b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    video_def->nStride = stride;
1904b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
1905b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    int32_t sliceHeight;
1906b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (!msg->findInt32("slice-height", &sliceHeight)) {
1907b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        sliceHeight = height;
1908799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    }
1909fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1910fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    video_def->nSliceHeight = sliceHeight;
1911fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
191265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
191365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1914b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    float frameRate;
191565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!msg->findFloat("frame-rate", &frameRate)) {
191665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t tmp;
1917a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten        if (!msg->findInt32("frame-rate", &tmp)) {
191865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return INVALID_OPERATION;
19193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        }
192065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        frameRate = (float)tmp;
192165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
192265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
192365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19240d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
192565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    video_def->eColorFormat = colorFormat;
192665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
192758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    err = mOMX->setParameter(
192865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
192965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
193065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
193165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGE("[%s] failed to set input port definition parameters.",
193265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              mComponentName.c_str());
193365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
193465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
193565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
193665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
193765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    /* Output port configuration */
193865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
193965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_VIDEO_CODINGTYPE compressionFormat;
194065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
194165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
194265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
1943799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return err;
19440d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    }
19450d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
1946799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    err = setVideoPortFormatType(
1947b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kasten            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
1948799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
194958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (err != OK) {
195058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOGE("[%s] does not support compression format %d",
195158912562617941964939a4182cda71eaeb153d4bGlenn Kasten             mComponentName.c_str(), compressionFormat);
195258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
195358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return err;
1954300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
19554adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
1956300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    def.nPortIndex = kPortIndexOutput;
195758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
19584adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    err = mOMX->getParameter(
19594adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19604adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
19614adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    if (err != OK) {
19624adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        return err;
19634adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    }
19644adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
19654adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    video_def->nFrameWidth = width;
19664adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    video_def->nFrameHeight = height;
19674adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    video_def->xFramerate = 0;
19684adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    video_def->nBitrate = bitrate;
19694adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    video_def->eCompressionFormat = compressionFormat;
19704adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19714adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
19724adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    err = mOMX->setParameter(
19734adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19744adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
19754adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    if (err != OK) {
19764adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        ALOGE("[%s] failed to set output port definition parameters.",
19774adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten              mComponentName.c_str());
19784adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
19794adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        return err;
19804adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    }
19814adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
19824adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    switch (compressionFormat) {
19834adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        case OMX_VIDEO_CodingMPEG4:
19844adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            err = setupMPEG4EncoderParameters(msg);
19854adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            break;
198658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
198758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        case OMX_VIDEO_CodingH263:
19884adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            err = setupH263EncoderParameters(msg);
19894adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            break;
19904adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten
199158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        case OMX_VIDEO_CodingAVC:
199265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            err = setupAVCEncoderParameters(msg);
199365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
199465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1995e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten        case OMX_VIDEO_CodingVP8:
199658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        case OMX_VIDEO_CodingVP9:
199758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            err = setupVPXEncoderParameters(msg);
199865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
1999de070137f11d346fba77605bd76a44c040a618fcEric Laurent
2000de070137f11d346fba77605bd76a44c040a618fcEric Laurent        default:
2001de070137f11d346fba77605bd76a44c040a618fcEric Laurent            break;
2002de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
2003de070137f11d346fba77605bd76a44c040a618fcEric Laurent
2004de070137f11d346fba77605bd76a44c040a618fcEric Laurent    ALOGI("setupVideoEncoder succeeded");
2005de070137f11d346fba77605bd76a44c040a618fcEric Laurent
2006de070137f11d346fba77605bd76a44c040a618fcEric Laurent    return err;
200739e94f8f723d445447fdee0822291e664b631f60Eric Laurent}
2008de070137f11d346fba77605bd76a44c040a618fcEric Laurent
200965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
201065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
201165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    InitOMXParams(&params);
201265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    params.nPortIndex = kPortIndexOutput;
2013a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten
201465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
201565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2016b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20177c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
201865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t mbs;
201965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
2020799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            return INVALID_OPERATION;
202165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
2022799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        params.nCirMBs = mbs;
202365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
202465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
202539e94f8f723d445447fdee0822291e664b631f60Eric Laurent    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
202665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
202765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t mbs;
202839e94f8f723d445447fdee0822291e664b631f60Eric Laurent        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
202965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return INVALID_OPERATION;
203039e94f8f723d445447fdee0822291e664b631f60Eric Laurent        }
203165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        params.nAirMBs = mbs;
203265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
203365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t ref;
203465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
2035de070137f11d346fba77605bd76a44c040a618fcEric Laurent            return INVALID_OPERATION;
2036de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
203739e94f8f723d445447fdee0822291e664b631f60Eric Laurent        params.nAirRef = ref;
203839e94f8f723d445447fdee0822291e664b631f60Eric Laurent    }
203965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
204065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = mOMX->setParameter(
204165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNode, OMX_IndexParamVideoIntraRefresh,
204239e94f8f723d445447fdee0822291e664b631f60Eric Laurent            &params, sizeof(params));
204365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return err;
204465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
2045de070137f11d346fba77605bd76a44c040a618fcEric Laurent
2046de070137f11d346fba77605bd76a44c040a618fcEric Laurentstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
2047fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (iFramesInterval < 0) {
2048de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return 0xFFFFFFFF;
2049fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    } else if (iFramesInterval == 0) {
2050fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return 0;
2051de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
2052de070137f11d346fba77605bd76a44c040a618fcEric Laurent    OMX_U32 ret = frameRate * iFramesInterval;
2053de070137f11d346fba77605bd76a44c040a618fcEric Laurent    CHECK(ret > 1);
2054de070137f11d346fba77605bd76a44c040a618fcEric Laurent    return ret;
2055de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
205602bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten
2057de070137f11d346fba77605bd76a44c040a618fcEric Laurentstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
2058de070137f11d346fba77605bd76a44c040a618fcEric Laurent    int32_t tmp;
2059fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (!msg->findInt32("bitrate-mode", &tmp)) {
2060de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return OMX_Video_ControlRateVariable;
2061de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
206265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2063aed850d0d3b3c8cf3feaf1438076f33db2a60946Glenn Kasten    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
2064b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
2065b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
2066b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurentstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
2067b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    int32_t bitrate, iFrameInterval;
2068b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (!msg->findInt32("bitrate", &bitrate)
2069b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2070b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        return INVALID_OPERATION;
2071b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
2072b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
2073b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
207458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
207558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    float frameRate;
207658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (!msg->findFloat("frame-rate", &frameRate)) {
207758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        int32_t tmp;
207858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (!msg->findInt32("frame-rate", &tmp)) {
2079b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            return INVALID_OPERATION;
2080b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        }
2081b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        frameRate = (float)tmp;
2082b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
20830bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kasten
2084b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
2085b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    InitOMXParams(&mpeg4type);
2086b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    mpeg4type.nPortIndex = kPortIndexOutput;
2087b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
2088b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    status_t err = mOMX->getParameter(
2089b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
2090b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
20910bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kasten    if (err != OK) {
2092162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent        return err;
2093162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent    }
2094162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent
2095162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent    mpeg4type.nSliceHeaderSpacing = 0;
2096162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent    mpeg4type.bSVH = OMX_FALSE;
209758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mpeg4type.bGov = OMX_FALSE;
2098162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent
2099162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent    mpeg4type.nAllowedPictureTypes =
2100162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
2101162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent
2102162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
2103a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (mpeg4type.nPFrames == 0) {
2104a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
2105a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
2106a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mpeg4type.nBFrames = 0;
2107a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mpeg4type.nIDCVLCThreshold = 0;
2108a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mpeg4type.bACPred = OMX_TRUE;
2109a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mpeg4type.nMaxPacketSize = 256;
2110a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mpeg4type.nTimeIncRes = 1000;
2111a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mpeg4type.nHeaderExtension = 0;
2112a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mpeg4type.bReversibleVLC = OMX_FALSE;
2113a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2114a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    int32_t profile;
2115a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (msg->findInt32("profile", &profile)) {
2116a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        int32_t level;
2117a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        if (!msg->findInt32("level", &level)) {
2118a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            return INVALID_OPERATION;
2119a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
2120a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2121a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        err = verifySupportForProfileAndLevel(profile, level);
2122a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2123a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        if (err != OK) {
2124a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            return err;
2125a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
2126a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2127a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
2128a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
2129a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
2130a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2131a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    err = mOMX->setParameter(
2132a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
213365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
213465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
213523bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten        return err;
213672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    }
213758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
213858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    err = configureBitrate(bitrate, bitrateMode);
213958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
214058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (err != OK) {
214158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return err;
214258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
214358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
214458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    return setupErrorCorrectionParameters();
214558912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
214658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
214758912562617941964939a4182cda71eaeb153d4bGlenn Kastenstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
214858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    int32_t bitrate, iFrameInterval;
214958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (!msg->findInt32("bitrate", &bitrate)
215058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
215158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return INVALID_OPERATION;
215258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
215358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
215458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
215565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
215665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    float frameRate;
215729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    if (!msg->findFloat("frame-rate", &frameRate)) {
215865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t tmp;
215958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (!msg->findInt32("frame-rate", &tmp)) {
216058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return INVALID_OPERATION;
216158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
216258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        frameRate = (float)tmp;
216358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
216458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
216558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    OMX_VIDEO_PARAM_H263TYPE h263type;
216658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    InitOMXParams(&h263type);
2167300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    h263type.nPortIndex = kPortIndexOutput;
2168300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
2169300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    status_t err = mOMX->getParameter(
2170300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
2171300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
2172300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    if (err != OK) {
2173300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        return err;
2174300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
2175300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
2176300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    h263type.nAllowedPictureTypes =
2177300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
2178300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
2179300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
2180300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    if (h263type.nPFrames == 0) {
2181300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
218258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
218358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    h263type.nBFrames = 0;
218458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
218558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    int32_t profile;
218658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (msg->findInt32("profile", &profile)) {
218758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        int32_t level;
218858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (!msg->findInt32("level", &level)) {
218958912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return INVALID_OPERATION;
219058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
219158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
219258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        err = verifySupportForProfileAndLevel(profile, level);
219358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
219458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (err != OK) {
219558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return err;
219658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
219758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
219858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
219958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
220058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
220158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
220258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
220358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    h263type.bForceRoundingTypeToZero = OMX_FALSE;
220458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    h263type.nPictureHeaderRepetition = 0;
220558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    h263type.nGOBHeaderInterval = 0;
220658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
220758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    err = mOMX->setParameter(
220858912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
220958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
221058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (err != OK) {
221158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return err;
221258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
221358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
221458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    err = configureBitrate(bitrate, bitrateMode);
221558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
221658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (err != OK) {
221758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return err;
221858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
221958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
222058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    return setupErrorCorrectionParameters();
222158912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
222258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
222358912562617941964939a4182cda71eaeb153d4bGlenn Kastenstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
222458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    int32_t bitrate, iFrameInterval;
222558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (!msg->findInt32("bitrate", &bitrate)
222658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
222758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return INVALID_OPERATION;
222858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
222958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
223058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
223158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
223258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    float frameRate;
223358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (!msg->findFloat("frame-rate", &frameRate)) {
223458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        int32_t tmp;
223558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (!msg->findInt32("frame-rate", &tmp)) {
223658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return INVALID_OPERATION;
223758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
223858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        frameRate = (float)tmp;
2239300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
2240300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
2241300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    status_t err = OK;
2242300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    int32_t intraRefreshMode = 0;
2243300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
2244300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
2245300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        if (err != OK) {
2246300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
2247300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                    err, intraRefreshMode);
2248300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            return err;
2249300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        }
2250300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
2251300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
225265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    OMX_VIDEO_PARAM_AVCTYPE h264type;
225365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    InitOMXParams(&h264type);
225465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    h264type.nPortIndex = kPortIndexOutput;
225565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
225658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    err = mOMX->getParameter(
225758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
225858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
225958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (err != OK) {
226058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return err;
226158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
226258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
226358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    h264type.nAllowedPictureTypes =
226458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
226558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
226658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    int32_t profile;
226758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (msg->findInt32("profile", &profile)) {
226858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        int32_t level;
226958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (!msg->findInt32("level", &level)) {
227058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return INVALID_OPERATION;
227158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
227258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
227358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        err = verifySupportForProfileAndLevel(profile, level);
227458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
227558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (err != OK) {
227658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            return err;
227758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
227858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
227958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
228058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
228158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
228258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
228358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // XXX
228458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
228558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOGW("Use baseline profile instead of %d for AVC recording",
228665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            h264type.eProfile);
228765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
228865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
228983efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
229083efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
2291190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        h264type.nSliceHeaderSpacing = 0;
2292190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        h264type.bUseHadamard = OMX_TRUE;
229383efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        h264type.nRefFrames = 1;
229483efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        h264type.nBFrames = 0;
2295190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
2296190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        if (h264type.nPFrames == 0) {
2297190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
2298190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        }
2299190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        h264type.nRefIdx10ActiveMinus1 = 0;
2300190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        h264type.nRefIdx11ActiveMinus1 = 0;
2301190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        h264type.bEntropyCodingCABAC = OMX_FALSE;
230283efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        h264type.bWeightedPPrediction = OMX_FALSE;
230383efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        h264type.bconstIpred = OMX_FALSE;
230483efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        h264type.bDirect8x8Inference = OMX_FALSE;
2305190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        h264type.bDirectSpatialTemporal = OMX_FALSE;
230683efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        h264type.nCabacInitIdc = 0;
2307190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2308190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2309190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    if (h264type.nBFrames != 0) {
2310190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
2311190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2312190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2313190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    h264type.bEnableUEP = OMX_FALSE;
2314190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    h264type.bEnableFMO = OMX_FALSE;
2315190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    h264type.bEnableASO = OMX_FALSE;
2316190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    h264type.bEnableRS = OMX_FALSE;
2317190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    h264type.bFrameMBsOnly = OMX_TRUE;
2318190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    h264type.bMBAFF = OMX_FALSE;
2319190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
2320190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2321190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    err = mOMX->setParameter(
2322190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
2323190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2324190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    if (err != OK) {
2325190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        return err;
2326190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2327190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2328190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    return configureBitrate(bitrate, bitrateMode);
2329190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten}
2330190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2331190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kastenstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
2332190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    int32_t bitrate;
2333190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    if (!msg->findInt32("bitrate", &bitrate)) {
2334190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        return INVALID_OPERATION;
2335190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2336190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2337190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2338190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2339190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    return configureBitrate(bitrate, bitrateMode);
2340190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten}
2341190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2342190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kastenstatus_t ACodec::verifySupportForProfileAndLevel(
2343190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        int32_t profile, int32_t level) {
2344190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
234583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    InitOMXParams(&params);
2346190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    params.nPortIndex = kPortIndexOutput;
234783efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
234883efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
234983efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        status_t err = mOMX->getParameter(
2350190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                mNode,
2351190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                OMX_IndexParamVideoProfileLevelQuerySupported,
2352190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                &params,
2353190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                sizeof(params));
2354190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2355190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        if (err != OK) {
2356190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            return err;
2357190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        }
2358190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2359190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
2360190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
2361190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2362190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        if (profile == supportedProfile && level <= supportedLevel) {
2363190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            return OK;
2364190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        }
2365190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2366190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten}
2367190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
236883efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kastenstatus_t ACodec::configureBitrate(
236983efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
237083efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
237183efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    InitOMXParams(&bitrateType);
237283efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    bitrateType.nPortIndex = kPortIndexOutput;
237383efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
237483efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    status_t err = mOMX->getParameter(
237583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten            mNode, OMX_IndexParamVideoBitrate,
2376190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            &bitrateType, sizeof(bitrateType));
2377190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2378190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    if (err != OK) {
2379190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        return err;
2380190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2381190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
238283efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    bitrateType.eControlRate = bitrateMode;
238383efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    bitrateType.nTargetBitrate = bitrate;
238483efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
238583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    return mOMX->setParameter(
238683efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten            mNode, OMX_IndexParamVideoBitrate,
238737d825e72a6c606553a745da1212590a425996d3Glenn Kasten            &bitrateType, sizeof(bitrateType));
238837d825e72a6c606553a745da1212590a425996d3Glenn Kasten}
238937d825e72a6c606553a745da1212590a425996d3Glenn Kasten
239037d825e72a6c606553a745da1212590a425996d3Glenn Kastenstatus_t ACodec::setupErrorCorrectionParameters() {
239137d825e72a6c606553a745da1212590a425996d3Glenn Kasten    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
239237d825e72a6c606553a745da1212590a425996d3Glenn Kasten    InitOMXParams(&errorCorrectionType);
239337d825e72a6c606553a745da1212590a425996d3Glenn Kasten    errorCorrectionType.nPortIndex = kPortIndexOutput;
239437d825e72a6c606553a745da1212590a425996d3Glenn Kasten
239537d825e72a6c606553a745da1212590a425996d3Glenn Kasten    status_t err = mOMX->getParameter(
239637d825e72a6c606553a745da1212590a425996d3Glenn Kasten            mNode, OMX_IndexParamVideoErrorCorrection,
239737d825e72a6c606553a745da1212590a425996d3Glenn Kasten            &errorCorrectionType, sizeof(errorCorrectionType));
239837d825e72a6c606553a745da1212590a425996d3Glenn Kasten
239937d825e72a6c606553a745da1212590a425996d3Glenn Kasten    if (err != OK) {
240037d825e72a6c606553a745da1212590a425996d3Glenn Kasten        return OK;  // Optional feature. Ignore this failure
240137d825e72a6c606553a745da1212590a425996d3Glenn Kasten    }
240237d825e72a6c606553a745da1212590a425996d3Glenn Kasten
240337d825e72a6c606553a745da1212590a425996d3Glenn Kasten    errorCorrectionType.bEnableHEC = OMX_FALSE;
2404000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    errorCorrectionType.bEnableResync = OMX_TRUE;
240565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    errorCorrectionType.nResynchMarkerSpacing = 256;
240665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
2407688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten    errorCorrectionType.bEnableRVLC = OMX_FALSE;
2408000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2409000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    return mOMX->setParameter(
2410000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            mNode, OMX_IndexParamVideoErrorCorrection,
241165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            &errorCorrectionType, sizeof(errorCorrectionType));
2412000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
2413000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2414000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenstatus_t ACodec::setVideoFormatOnPort(
2415688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten        OMX_U32 portIndex,
2416000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2417000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    OMX_PARAM_PORTDEFINITIONTYPE def;
2418000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    InitOMXParams(&def);
2419688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten    def.nPortIndex = portIndex;
242066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
2421000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2422000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2423000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    status_t err = mOMX->getParameter(
2424000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2425000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2426000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    CHECK_EQ(err, (status_t)OK);
242783efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
2428190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    if (portIndex == kPortIndexInput) {
242965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // XXX Need a (much) better heuristic to compute input buffer sizes.
2430feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        const size_t X = 64 * 1024;
2431feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (def.nBufferSize < X) {
243265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            def.nBufferSize = X;
243365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
2434190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2435688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
243673ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
243773ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten
243865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    video_def->nFrameWidth = width;
243965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    video_def->nFrameHeight = height;
244065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
244165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (portIndex == kPortIndexInput) {
244265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        video_def->eCompressionFormat = compressionFormat;
244365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        video_def->eColorFormat = OMX_COLOR_FormatUnused;
244465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
244566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
244665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = mOMX->setParameter(
244765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2448fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten
2449000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    return err;
245065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
24513e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten
2452c455fe9727d361076b7cead3efdac2d32a1a1d6dGlenn Kastenstatus_t ACodec::initNativeWindow() {
245365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mNativeWindow != NULL) {
2454000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2455000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    }
2456000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
245765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
245865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
245965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
246065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
24613e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kastensize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
246265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t n = 0;
246365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
246465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2465fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2466000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
246765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
246865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ++n;
2469feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
247065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
2471190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
247265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return n;
2473190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten}
2474feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
247565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansize_t ACodec::countBuffersOwnedByNativeWindow() const {
2476da747447c1d4b5205469b4e94485b8769df57a97Eric Laurent    size_t n = 0;
2477810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten
2478000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
247937d825e72a6c606553a745da1212590a425996d3Glenn Kasten        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
248065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2481000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
248265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ++n;
248366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        }
248466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    }
248566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
2486000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    return n;
248765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
248865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
248965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
249065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mNativeWindow == NULL) {
2491810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten        return;
2492da747447c1d4b5205469b4e94485b8769df57a97Eric Laurent    }
249365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
249465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int minUndequeuedBufs = 0;
249565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = mNativeWindow->query(
249665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
2497de070137f11d346fba77605bd76a44c040a618fcEric Laurent            &minUndequeuedBufs);
2498c5ac4cb3a5124860ccfc7e4ff66251c55a5595caGlenn Kasten
249965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
2500fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
2501000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                mComponentName.c_str(), strerror(-err), -err);
250265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2503000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        minUndequeuedBufs = 0;
250465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
250565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2506c455fe9727d361076b7cead3efdac2d32a1a1d6dGlenn Kasten    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
250725cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent            && dequeueBufferFromNativeWindow() != NULL) {
250865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // these buffers will be submitted as regular buffers; account for this
250904743e99e71c0da012508c7119f414027654ee94Glenn Kasten        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
251004743e99e71c0da012508c7119f414027654ee94Glenn Kasten            --mMetaDataBuffersToSubmit;
251165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
2512c5ac4cb3a5124860ccfc7e4ff66251c55a5595caGlenn Kasten    }
2513c5ac4cb3a5124860ccfc7e4ff66251c55a5595caGlenn Kasten}
2514c5ac4cb3a5124860ccfc7e4ff66251c55a5595caGlenn Kasten
251504743e99e71c0da012508c7119f414027654ee94Glenn Kastenbool ACodec::allYourBuffersAreBelongToUs(
251604743e99e71c0da012508c7119f414027654ee94Glenn Kasten        OMX_U32 portIndex) {
251704743e99e71c0da012508c7119f414027654ee94Glenn Kasten    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
251804743e99e71c0da012508c7119f414027654ee94Glenn Kasten        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
251904743e99e71c0da012508c7119f414027654ee94Glenn Kasten
252004743e99e71c0da012508c7119f414027654ee94Glenn Kasten        if (info->mStatus != BufferInfo::OWNED_BY_US
252104743e99e71c0da012508c7119f414027654ee94Glenn Kasten                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2522688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2523000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    mComponentName.c_str(),
2524000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    info->mBufferID, portIndex, info->mStatus);
2525000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            return false;
2526000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        }
252765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
252865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25295c4e818c39ac2d2739675fe907904a874f7623c5Eric Laurent    return true;
253065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
25317dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten
2532d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kastenbool ACodec::allYourBuffersAreBelongToUs() {
25335ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    return allYourBuffersAreBelongToUs(kPortIndexInput)
253465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        && allYourBuffersAreBelongToUs(kPortIndexOutput);
253565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
253665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2537000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid ACodec::deferMessage(const sp<AMessage> &msg) {
2538000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    bool wasEmptyBefore = mDeferredQueue.empty();
253965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mDeferredQueue.push_back(msg);
254065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
254165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
254265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::processDeferredMessages() {
2543000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    List<sp<AMessage> > queue = mDeferredQueue;
2544688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten    mDeferredQueue.clear();
254565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
254665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    List<sp<AMessage> >::iterator it = queue.begin();
254765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (it != queue.end()) {
254865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        onMessageReceived(*it++);
254965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
255058912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
255165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
255258912562617941964939a4182cda71eaeb153d4bGlenn Kastenvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
255358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    sp<AMessage> notify = mNotify->dup();
25541465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten    notify->setInt32("what", kWhatOutputFormatChanged);
2555000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2556fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    OMX_PARAM_PORTDEFINITIONTYPE def;
2557fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    InitOMXParams(&def);
2558fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    def.nPortIndex = kPortIndexOutput;
2559fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten
256065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ(mOMX->getParameter(
256165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
256265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             (status_t)OK);
256365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
256473ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
256573ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten
256673ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten    switch (def.eDomain) {
256765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case OMX_PortDomainVideo:
256865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
2569000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2570688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
257165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            AString mime;
2572799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            if (!mIsEncoder) {
257365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2574000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            } else if (GetMimeTypeForVideoCoding(
2575000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                        videoDef->eCompressionFormat, &mime) != OK) {
2576000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                notify->setString("mime", "application/octet-stream");
2577000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            } else {
257865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                notify->setString("mime", mime.c_str());
2579feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            }
2580feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
2581c0b52836d07f823732f0ff98ca5ca9d7f5730cb8Glenn Kasten            notify->setInt32("width", videoDef->nFrameWidth);
258265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            notify->setInt32("height", videoDef->nFrameHeight);
258365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
258465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!mIsEncoder) {
2585288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                notify->setInt32("stride", videoDef->nStride);
258658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                notify->setInt32("slice-height", videoDef->nSliceHeight);
258758912562617941964939a4182cda71eaeb153d4bGlenn Kasten                notify->setInt32("color-format", videoDef->eColorFormat);
258858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
258958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                OMX_CONFIG_RECTTYPE rect;
259058912562617941964939a4182cda71eaeb153d4bGlenn Kasten                InitOMXParams(&rect);
259158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                rect.nPortIndex = kPortIndexOutput;
259258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
259358912562617941964939a4182cda71eaeb153d4bGlenn Kasten                if (mOMX->getConfig(
259458912562617941964939a4182cda71eaeb153d4bGlenn Kasten                            mNode, OMX_IndexConfigCommonOutputCrop,
259558912562617941964939a4182cda71eaeb153d4bGlenn Kasten                            &rect, sizeof(rect)) != OK) {
259658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    rect.nLeft = 0;
259758912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    rect.nTop = 0;
2598300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                    rect.nWidth = videoDef->nFrameWidth;
2599300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                    rect.nHeight = videoDef->nFrameHeight;
260058912562617941964939a4182cda71eaeb153d4bGlenn Kasten                }
260158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
260258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                CHECK_GE(rect.nLeft, 0);
260358912562617941964939a4182cda71eaeb153d4bGlenn Kasten                CHECK_GE(rect.nTop, 0);
260458912562617941964939a4182cda71eaeb153d4bGlenn Kasten                CHECK_GE(rect.nWidth, 0u);
260558912562617941964939a4182cda71eaeb153d4bGlenn Kasten                CHECK_GE(rect.nHeight, 0u);
260658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
260758912562617941964939a4182cda71eaeb153d4bGlenn Kasten                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
260858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2609300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                notify->setRect(
2610300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                        "crop",
2611300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                        rect.nLeft,
261258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                        rect.nTop,
261358912562617941964939a4182cda71eaeb153d4bGlenn Kasten                        rect.nLeft + rect.nWidth - 1,
261458912562617941964939a4182cda71eaeb153d4bGlenn Kasten                        rect.nTop + rect.nHeight - 1);
261558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
261658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                if (mNativeWindow != NULL) {
261758912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    reply->setRect(
261858912562617941964939a4182cda71eaeb153d4bGlenn Kasten                            "crop",
2619000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                            rect.nLeft,
2620000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                            rect.nTop,
2621000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                            rect.nLeft + rect.nWidth,
2622952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                            rect.nTop + rect.nHeight);
2623952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                }
2624952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            }
262558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            break;
262658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
2627300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
2628d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten        case OMX_PortDomainAudio:
2629300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        {
2630d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2631300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
2632300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            switch ((int)audioDef->eEncoding) {
2633300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                case OMX_AUDIO_CodingPCM:
263458912562617941964939a4182cda71eaeb153d4bGlenn Kasten                {
263558912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2636952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    InitOMXParams(&params);
2637952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    params.nPortIndex = kPortIndexOutput;
2638000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2639000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    CHECK_EQ(mOMX->getParameter(
264058912562617941964939a4182cda71eaeb153d4bGlenn Kasten                                mNode, OMX_IndexParamAudioPcm,
264158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                                &params, sizeof(params)),
264258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                             (status_t)OK);
264358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
264458912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    CHECK_GT(params.nChannels, 0);
264558912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    CHECK(params.nChannels == 1 || params.bInterleaved);
264658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    CHECK_EQ(params.nBitPerSample, 16u);
264758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
264858912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    CHECK_EQ((int)params.eNumData,
264958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                             (int)OMX_NumericalDataSigned);
265058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
265158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    CHECK_EQ((int)params.ePCMMode,
265258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                             (int)OMX_AUDIO_PCMModeLinear);
265358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2654300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2655300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                    notify->setInt32("channel-count", params.nChannels);
2656300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                    notify->setInt32("sample-rate", params.nSamplingRate);
265758912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    if (mEncoderDelay + mEncoderPadding) {
265858912562617941964939a4182cda71eaeb153d4bGlenn Kasten                        size_t frameSize = params.nChannels * sizeof(int16_t);
265958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                        if (mSkipCutBuffer != NULL) {
266058912562617941964939a4182cda71eaeb153d4bGlenn Kasten                            size_t prevbufsize = mSkipCutBuffer->size();
266158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                            if (prevbufsize != 0) {
266258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                                ALOGW("Replacing SkipCutBuffer holding %d "
266358912562617941964939a4182cda71eaeb153d4bGlenn Kasten                                      "bytes",
2664000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                                      prevbufsize);
2665000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                            }
2666000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                        }
2667952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                        mSkipCutBuffer = new SkipCutBuffer(
2668952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                                mEncoderDelay * frameSize,
2669000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                                mEncoderPadding * frameSize);
2670000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    }
2671000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2672000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    if (mChannelMaskPresent) {
2673952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                        notify->setInt32("channel-mask", mChannelMask);
2674952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    }
2675952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    break;
2676000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                }
2677952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
2678952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                case OMX_AUDIO_CodingAAC:
2679952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                {
2680952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2681000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    InitOMXParams(&params);
2682952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    params.nPortIndex = kPortIndexOutput;
2683952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
2684952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    CHECK_EQ(mOMX->getParameter(
2685000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                                mNode, OMX_IndexParamAudioAac,
2686952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                                &params, sizeof(params)),
2687952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                             (status_t)OK);
2688952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
2689952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2690952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    notify->setInt32("channel-count", params.nChannels);
2691952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    notify->setInt32("sample-rate", params.nSampleRate);
2692952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    break;
2693952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                }
2694952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
2695952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                case OMX_AUDIO_CodingAMR:
269666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                {
2697952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    OMX_AUDIO_PARAM_AMRTYPE params;
2698000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    InitOMXParams(&params);
2699000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    params.nPortIndex = kPortIndexOutput;
2700000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2701000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    CHECK_EQ(mOMX->getParameter(
2702952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                                mNode, OMX_IndexParamAudioAmr,
2703952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                                &params, sizeof(params)),
2704952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                             (status_t)OK);
2705fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten
2706952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    notify->setInt32("channel-count", 1);
2707952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2708952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                        notify->setString(
2709000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2710952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
2711952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                        notify->setInt32("sample-rate", 16000);
2712952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    } else {
2713952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                        notify->setString(
2714952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2715952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
2716952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                        notify->setInt32("sample-rate", 8000);
2717952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    }
2718952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    break;
2719952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                }
2720952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
2721fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten                case OMX_AUDIO_CodingFLAC:
2722952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                {
2723952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    OMX_AUDIO_PARAM_FLACTYPE params;
2724fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten                    InitOMXParams(&params);
2725952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    params.nPortIndex = kPortIndexOutput;
2726952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
2727000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    CHECK_EQ(mOMX->getParameter(
2728000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                                mNode, OMX_IndexParamAudioFlac,
272965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                &params, sizeof(params)),
273029c23c3aee5ae799b3480dc6876a46c46b019710Glenn Kasten                             (status_t)OK);
27313e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten
273265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
273365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    notify->setInt32("channel-count", params.nChannels);
273429c23c3aee5ae799b3480dc6876a46c46b019710Glenn Kasten                    notify->setInt32("sample-rate", params.nSampleRate);
273565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    break;
27363e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten                }
273765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
273865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case OMX_AUDIO_CodingAndroidAC3:
2739288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                {
274058912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
2741288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    InitOMXParams(&params);
274265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    params.nPortIndex = kPortIndexOutput;
274365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2744ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten                    CHECK_EQ((status_t)OK, mOMX->getParameter(
274565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mNode,
2746571d49c1c316f5e07b74ed7b5df6bdec7cbc1a14Eric Laurent                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
2747571d49c1c316f5e07b74ed7b5df6bdec7cbc1a14Eric Laurent                            &params,
2748571d49c1c316f5e07b74ed7b5df6bdec7cbc1a14Eric Laurent                            sizeof(params)));
274965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2750fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
275165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    notify->setInt32("channel-count", params.nChannels);
2752571d49c1c316f5e07b74ed7b5df6bdec7cbc1a14Eric Laurent                    notify->setInt32("sample-rate", params.nSampleRate);
2753cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent                    break;
275465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
275565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
275665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                default:
275765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    TRESPASS();
2758288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
2759288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            break;
2760288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
2761288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2762288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        default:
2763288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            TRESPASS();
2764288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
2765288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2766288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    notify->post();
2767288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
276865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSentFormat = true;
27693e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten}
277065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
277165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
27729c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten    sp<AMessage> notify = mNotify->dup();
277365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->setInt32("what", ACodec::kWhatError);
277458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    notify->setInt32("omx-error", error);
2775288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    notify->setInt32("err", internalError);
277658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    notify->post();
2777288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten}
2778288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2779288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kastenstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2780288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    status_t err = NO_ERROR;
2781288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    ANativeWindowBuffer* anb = NULL;
2782288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    int numBufs = 0;
2783288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    int minUndequeuedBufs = 0;
2784288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2785288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2786288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // no frames get dropped by SurfaceFlinger assuming that these are video
2787288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // frames.
2788288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    err = native_window_api_disconnect(mNativeWindow.get(),
278909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            NATIVE_WINDOW_API_MEDIA);
279009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    if (err != NO_ERROR) {
279109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
279209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                strerror(-err), -err);
279309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        return err;
279409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    }
279509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten
279609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    err = native_window_api_connect(mNativeWindow.get(),
279709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            NATIVE_WINDOW_API_CPU);
2798288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (err != NO_ERROR) {
2799d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2800d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                strerror(-err), -err);
2801288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        return err;
2802288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
2803288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2804d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2805288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            HAL_PIXEL_FORMAT_RGBX_8888);
2806d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    if (err != NO_ERROR) {
2807d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2808d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                strerror(-err), -err);
2809d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        goto error;
2810d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    }
2811d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
2812d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    err = native_window_set_scaling_mode(mNativeWindow.get(),
2813d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
2814d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    if (err != NO_ERROR) {
2815288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
2816288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten              strerror(-err), -err);
2817d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        goto error;
2818d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    }
2819288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2820288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    err = native_window_set_usage(mNativeWindow.get(),
2821d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            GRALLOC_USAGE_SW_WRITE_OFTEN);
2822d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    if (err != NO_ERROR) {
282309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
282409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                strerror(-err), -err);
282509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        goto error;
282609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    }
282709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten
282809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    err = mNativeWindow->query(mNativeWindow.get(),
282909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
283009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    if (err != NO_ERROR) {
283109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
283209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                "failed: %s (%d)", strerror(-err), -err);
283309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        goto error;
283409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    }
283509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten
283609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    numBufs = minUndequeuedBufs + 1;
283709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
283809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    if (err != NO_ERROR) {
283909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
284009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                strerror(-err), -err);
284109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        goto error;
284209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    }
284309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten
284409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
284509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    // buffer twice.  This should guarantee that the buffer has been displayed
284609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    // on the screen and then been replaced, so an previous video frames are
2847d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    // guaranteed NOT to be currently displayed.
2848d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    for (int i = 0; i < numBufs + 1; i++) {
2849d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        int fenceFd = -1;
2850d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2851d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        if (err != NO_ERROR) {
2852d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2853d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    strerror(-err), -err);
2854d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            goto error;
2855d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        }
2856d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
2857d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2858d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
2859d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2860d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        uint32_t* img = NULL;
2861d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2862d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        if (err != NO_ERROR) {
2863d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2864d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    strerror(-err), -err);
2865d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            goto error;
2866d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        }
2867d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
2868d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        *img = 0;
2869d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
2870d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        err = buf->unlock();
2871d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        if (err != NO_ERROR) {
2872d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2873d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    strerror(-err), -err);
2874d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            goto error;
2875d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        }
2876d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
2877d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
2878d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                buf->getNativeBuffer(), -1);
2879d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        if (err != NO_ERROR) {
2880d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2881288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    strerror(-err), -err);
2882288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            goto error;
2883288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
2884288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2885288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        anb = NULL;
2886288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
2887288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2888288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kastenerror:
2889288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2890288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (err != NO_ERROR) {
2891288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        // Clean up after an error.
2892288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        if (anb != NULL) {
2893288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2894288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
2895288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2896288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        native_window_api_disconnect(mNativeWindow.get(),
2897288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                NATIVE_WINDOW_API_CPU);
2898288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        native_window_api_connect(mNativeWindow.get(),
2899288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                NATIVE_WINDOW_API_MEDIA);
2900288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2901288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        return err;
2902288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    } else {
2903288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        // Clean up after success.
2904288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        err = native_window_api_disconnect(mNativeWindow.get(),
2905288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                NATIVE_WINDOW_API_CPU);
2906288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        if (err != NO_ERROR) {
2907288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2908288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    strerror(-err), -err);
2909288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            return err;
2910288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
2911288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2912d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        err = native_window_api_connect(mNativeWindow.get(),
2913d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                NATIVE_WINDOW_API_MEDIA);
2914288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        if (err != NO_ERROR) {
2915d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2916288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    strerror(-err), -err);
291709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            return err;
291858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
291958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
292058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        return NO_ERROR;
292158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
292258912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
292358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
292465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
292565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
292665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianACodec::PortDescription::PortDescription() {
292765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
29289c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten
2929a47b69c6f7c6fe0044ebcb2d0790ce3548de56fdEric Laurentstatus_t ACodec::requestIDRFrame() {
2930a47b69c6f7c6fe0044ebcb2d0790ce3548de56fdEric Laurent    if (!mIsEncoder) {
2931a47b69c6f7c6fe0044ebcb2d0790ce3548de56fdEric Laurent        return ERROR_UNSUPPORTED;
2932da747447c1d4b5205469b4e94485b8769df57a97Eric Laurent    }
2933a47b69c6f7c6fe0044ebcb2d0790ce3548de56fdEric Laurent
29343dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
293583faee053cfd4251dbb591b62039f563ffdac399Eric Laurent    InitOMXParams(&params);
2936810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten
29373dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent    params.nPortIndex = kPortIndexOutput;
293858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    params.IntraRefreshVOP = OMX_TRUE;
29393dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent
2940071ccd5a9702500f3f7d62ef881300914926184dEric Laurent    return mOMX->setConfig(
294158912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mNode,
2942071ccd5a9702500f3f7d62ef881300914926184dEric Laurent            OMX_IndexConfigVideoIntraVOPRefresh,
2943ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten            &params,
2944071ccd5a9702500f3f7d62ef881300914926184dEric Laurent            sizeof(params));
2945071ccd5a9702500f3f7d62ef881300914926184dEric Laurent}
2946071ccd5a9702500f3f7d62ef881300914926184dEric Laurent
2947071ccd5a9702500f3f7d62ef881300914926184dEric Laurentvoid ACodec::PortDescription::addBuffer(
2948c1dc1cb1d1eaf84e88669f1a5f22579a0d9237c2Steve Block        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
29493dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent    mBufferIDs.push_back(id);
29503dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent    mBuffers.push_back(buffer);
29514ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
295265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
295365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansize_t ACodec::PortDescription::countBuffers() {
29549c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten    return mBufferIDs.size();
295565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
295665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
295765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
295865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mBufferIDs.itemAt(index);
295965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
296065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
296165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
296265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mBuffers.itemAt(index);
296365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
296465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
296565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
296665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
29675ff1dd576bb93c45b44088a51544a18fc43ebf58Steve BlockACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
29689c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten    : AState(parentState),
296965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mCodec(codec) {
297065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
297165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
297265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
297365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        OMX_U32 /* portIndex */) {
297465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return KEEP_BUFFERS;
297565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
297665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
297765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
297865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (msg->what()) {
297965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatInputBufferFilled:
298065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
29819c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten            onInputBufferFilled(msg);
298265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
298365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
298465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
298565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatOutputBufferDrained:
298665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
298765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            onOutputBufferDrained(msg);
298865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
2989e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        }
29908569f0d3bf4c6787707e348a7cf73b9c4199cb32Eric Laurent
299102bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten        case ACodec::kWhatOMXMessage:
2992e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        {
299365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return onOMXMessage(msg);
299465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
299565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
299665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case ACodec::kWhatCreateInputSurface:
2997e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        case ACodec::kWhatSignalEndOfInputStream:
299865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
299902bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten            ALOGE("Message 0x%x was not handled", msg->what());
300065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
300183d86538c4c479a9225c75ab27938e8f05abb9c8Glenn Kasten            return true;
3002b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten        }
3003b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten
3004b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten        case ACodec::kWhatOMXDied:
3005b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten        {
3006b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten            ALOGE("OMX/mediaserver died, signalling error!");
3007b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3008b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten            break;
3009b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten        }
3010b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten
3011b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten        default:
3012b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten            return false;
3013b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten    }
3014b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten
3015b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten    return true;
3016b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten}
3017b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten
301865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
301905632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten    int32_t type;
302005632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten    CHECK(msg->findInt32("type", &type));
30213b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten
302205632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten    IOMX::node_id nodeID;
3023b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten    CHECK(msg->findPointer("node", &nodeID));
302405632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten    CHECK_EQ(nodeID, mCodec->mNode);
302505632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten
3026e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    switch (type) {
3027e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        case omx_message::EVENT:
3028e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        {
3029e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            int32_t event, data1, data2;
3030e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            CHECK(msg->findInt32("event", &event));
3031e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            CHECK(msg->findInt32("data1", &data1));
3032e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            CHECK(msg->findInt32("data2", &data2));
3033e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
3034e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            if (event == OMX_EventCmdComplete
3035e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                    && data1 == OMX_CommandFlush
303665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    && data2 == (int32_t)OMX_ALL) {
303765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // Use of this notification is not consistent across
3038e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                // implementations. We'll drop this notification and rely
303965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // on flush-complete notifications on the individual port
304065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // indices instead.
3041e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
3042b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                return true;
30433b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            }
30443b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten
30453b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            return onOMXEvent(
30463b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten                    static_cast<OMX_EVENTTYPE>(event),
3047e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                    static_cast<OMX_U32>(data1),
30483b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten                    static_cast<OMX_U32>(data2));
3049e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        }
305065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30519c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten        case omx_message::EMPTY_BUFFER_DONE:
30529c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten        {
305365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IOMX::buffer_id bufferID;
30543b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            CHECK(msg->findPointer("buffer", &bufferID));
30553b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten
30563b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            return onOMXEmptyBufferDone(bufferID);
305765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
30589c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten
305965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case omx_message::FILL_BUFFER_DONE:
306065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
306165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IOMX::buffer_id bufferID;
30629c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten            CHECK(msg->findPointer("buffer", &bufferID));
306365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30640d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            int32_t rangeOffset, rangeLength, flags;
306565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int64_t timeUs;
30669c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten            void *platformPrivate;
306765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            void *dataPtr;
306865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
306965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK(msg->findInt32("range_offset", &rangeOffset));
307065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK(msg->findInt32("range_length", &rangeLength));
30719c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten            CHECK(msg->findInt32("flags", &flags));
307265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK(msg->findInt64("timestamp", &timeUs));
307365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK(msg->findPointer("platform_private", &platformPrivate));
307465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK(msg->findPointer("data_ptr", &dataPtr));
30759c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten
307665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return onOMXFillBufferDone(
307765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    bufferID,
307865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    (size_t)rangeOffset, (size_t)rangeLength,
307965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    (OMX_U32)flags,
308065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    timeUs,
3081ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten                    platformPrivate,
30822774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent                    dataPtr);
30832774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent        }
30842774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent
3085810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten        default:
30862774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent            TRESPASS();
30872774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent            break;
30882774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent    }
308965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30909c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten
309165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ACodec::BaseState::onOMXEvent(
309265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
309365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (event != OMX_EventError) {
309483faee053cfd4251dbb591b62039f563ffdac399Eric Laurent        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
309583faee053cfd4251dbb591b62039f563ffdac399Eric Laurent             mCodec->mComponentName.c_str(), event, data1, data2);
309665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
309765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return false;
3098a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
3099a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
3100a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3101a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
3102a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mCodec->signalError((OMX_ERRORTYPE)data1);
3103a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
3104a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    return true;
3105a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
3106a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
310765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
310865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("[%s] onOMXEmptyBufferDone %p",
310965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian         mCodec->mComponentName.c_str(), bufferID);
311065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31119c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten    BufferInfo *info =
311265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->findBufferByID(kPortIndexInput, bufferID);
3113288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3114288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
311538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent    info->mStatus = BufferInfo::OWNED_BY_US;
31162774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent
31172774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent    const sp<AMessage> &bufferMeta = info->mData->meta();
31182774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent    void *mediaBuffer;
3119810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
31202774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent            && mediaBuffer != NULL) {
312165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // We're in "store-metadata-in-buffers" mode, the underlying
312265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // OMX component had access to data that's implicitly refcounted
312365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // by this "mediaBuffer" object. Now that the OMX component has
31249c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten        // told us that it's done with the input buffer, we can decrement
312565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the mediaBuffer's reference count.
312658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
312758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOGV("releasing mbuf %p", mediaBuffer);
312858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
312958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ((MediaBuffer *)mediaBuffer)->release();
313065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mediaBuffer = NULL;
313165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3132288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        bufferMeta->setPointer("mediaBuffer", NULL);
3133288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
3134288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3135288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    PortMode mode = getPortMode(kPortIndexInput);
3136288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3137288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    switch (mode) {
3138288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        case KEEP_BUFFERS:
3139288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            break;
3140288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3141288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        case RESUBMIT_BUFFERS:
3142288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            postFillThisBuffer(info);
3143288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            break;
3144288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3145288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        default:
3146288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        {
3147288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3148288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            TRESPASS();  // Not currently used
3149288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            break;
3150288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
3151288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
3152288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3153288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    return true;
3154288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten}
3155288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3156288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kastenvoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3157288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (mCodec->mPortEOS[kPortIndexInput]) {
3158288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        return;
3159288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
3160288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3161288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3162288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3163288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    sp<AMessage> notify = mCodec->mNotify->dup();
3164288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3165288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    notify->setPointer("buffer-id", info->mBufferID);
3166288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
316758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    info->mData->meta()->clear();
316865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->setBuffer("buffer", info->mData);
316965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3170f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
317165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    reply->setPointer("buffer-id", info->mBufferID);
317265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
317365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->setMessage("reply", reply);
317465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
317565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->post();
317665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3178b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent}
317965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
318065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
318165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    IOMX::buffer_id bufferID;
3182b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    CHECK(msg->findPointer("buffer-id", &bufferID));
318365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
318465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ABuffer> buffer;
318565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t err = OK;
318665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool eos = false;
318765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PortMode mode = getPortMode(kPortIndexInput);
318865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
318965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!msg->findBuffer("buffer", &buffer)) {
319058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        /* these are unfilled buffers returned by client */
319158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        CHECK(msg->findInt32("err", &err));
319258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
319365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err == OK) {
319465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            /* buffers with no errors are returned on MediaCodec.flush */
319558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mode = KEEP_BUFFERS;
3196810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten        } else {
319758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            ALOGV("[%s] saw error %d instead of an input buffer",
319858912562617941964939a4182cda71eaeb153d4bGlenn Kasten                 mCodec->mComponentName.c_str(), err);
319958912562617941964939a4182cda71eaeb153d4bGlenn Kasten            eos = true;
320065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
320165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
320265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        buffer.clear();
320366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    }
320466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
320566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    int32_t tmp;
320666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
320766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        eos = true;
320866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        err = ERROR_END_OF_STREAM;
320966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    }
321066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
321166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
321266fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
321366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
321466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    info->mStatus = BufferInfo::OWNED_BY_US;
321566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
321666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    switch (mode) {
321766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        case KEEP_BUFFERS:
321866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        {
321966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten            if (eos) {
322066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                if (!mCodec->mPortEOS[kPortIndexInput]) {
322166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                    mCodec->mPortEOS[kPortIndexInput] = true;
322266fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                    mCodec->mInputEOSResult = err;
322366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                }
322458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
322566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten            break;
322666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        }
322766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
322866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        case RESUBMIT_BUFFERS:
3229fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        {
323065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
32313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                int64_t timeUs;
3232de070137f11d346fba77605bd76a44c040a618fcEric Laurent                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
323365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3234de070137f11d346fba77605bd76a44c040a618fcEric Laurent                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
323565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
323665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                int32_t isCSD;
323765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
323802bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
323938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                }
324065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
324165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (eos) {
324265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    flags |= OMX_BUFFERFLAG_EOS;
324365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
324465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
324565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (buffer != info->mData) {
32467d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
324765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         mCodec->mComponentName.c_str(),
32489bd23229fdec1657398abc682ccccfce1c95f8aaJean-Michel Trivi                         bufferID,
324965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         buffer.get(), info->mData.get());
325065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
325165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    CHECK_LE(buffer->size(), info->mData->capacity());
325265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    memcpy(info->mData->data(), buffer->data(), buffer->size());
325365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
32543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
325565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
325665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
325765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         mCodec->mComponentName.c_str(), bufferID);
325865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                } else if (flags & OMX_BUFFERFLAG_EOS) {
325965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
326065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         mCodec->mComponentName.c_str(), bufferID);
326158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                } else {
326258912562617941964939a4182cda71eaeb153d4bGlenn Kasten#if TRACK_BUFFER_TIMING
326365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
326465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         mCodec->mComponentName.c_str(), bufferID, timeUs);
326565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#else
326658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
326758912562617941964939a4182cda71eaeb153d4bGlenn Kasten                         mCodec->mComponentName.c_str(), bufferID, timeUs);
326858912562617941964939a4182cda71eaeb153d4bGlenn Kasten#endif
326958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                }
327058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
327158912562617941964939a4182cda71eaeb153d4bGlenn Kasten#if TRACK_BUFFER_TIMING
327258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                ACodec::BufferStats stats;
327358912562617941964939a4182cda71eaeb153d4bGlenn Kasten                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
327458912562617941964939a4182cda71eaeb153d4bGlenn Kasten                stats.mFillBufferDoneTimeUs = -1ll;
327558912562617941964939a4182cda71eaeb153d4bGlenn Kasten                mCodec->mBufferStats.add(timeUs, stats);
327658912562617941964939a4182cda71eaeb153d4bGlenn Kasten#endif
327758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
327858912562617941964939a4182cda71eaeb153d4bGlenn Kasten                if (mCodec->mStoreMetaDataInOutputBuffers) {
327958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    // try to submit an output buffer for each input buffer
328065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    PortMode outputMode = getPortMode(kPortIndexOutput);
328165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
328265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
328365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mCodec->mMetaDataBuffersToSubmit,
328465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            (outputMode == FREE_BUFFERS ? "FREE" :
328565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
328665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (outputMode == RESUBMIT_BUFFERS) {
328765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
328865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                (status_t)OK);
328958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten                    }
329065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
329165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
329265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                CHECK_EQ(mCodec->mOMX->emptyBuffer(
329365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mCodec->mNode,
329465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            bufferID,
329565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            0,
3296fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                            buffer->size(),
329765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            flags,
329865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            timeUs),
329965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         (status_t)OK);
330065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
330165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
330265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
330365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (!eos) {
3304362c4e697d8e9c034e964ac7b40227e054491547Glenn Kasten                    getMoreInputDataIfPossible();
330565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                } else {
330665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ALOGV("[%s] Signalled EOS on the input port",
330765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         mCodec->mComponentName.c_str());
330865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
330965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mCodec->mPortEOS[kPortIndexInput] = true;
331065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mCodec->mInputEOSResult = err;
331165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
331265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3313d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten                if (err != ERROR_END_OF_STREAM) {
33149ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    ALOGV("[%s] Signalling EOS on the input port "
33159ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                         "due to error %d",
3316b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                         mCodec->mComponentName.c_str(), err);
33179ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                } else {
33189ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    ALOGV("[%s] Signalling EOS on the input port",
3319fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                         mCodec->mComponentName.c_str());
33209ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                }
33219ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
33229ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
33239ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                     mCodec->mComponentName.c_str(), bufferID);
3324fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
33259ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                CHECK_EQ(mCodec->mOMX->emptyBuffer(
33269ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                            mCodec->mNode,
33279ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                            bufferID,
33289ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                            0,
33299ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                            0,
33309ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                            OMX_BUFFERFLAG_EOS,
33319ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                            0),
33329ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                         (status_t)OK);
33339ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
3334d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
33359ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
333665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mPortEOS[kPortIndexInput] = true;
333765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mInputEOSResult = err;
333865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
333965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
3340cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent        }
334165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
334265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
334365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
334465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
3345799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    }
3346fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
334765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3348e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kastenvoid ACodec::BaseState::getMoreInputDataIfPossible() {
3349e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (mCodec->mPortEOS[kPortIndexInput]) {
3350e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        return;
3351e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
3352fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
335365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    BufferInfo *eligible = NULL;
335465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
335565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3356e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3357e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten
335865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#if 0
335958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
336065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // There's already a "read" pending.
33617d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi            return;
336265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
336365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#endif
336465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
336565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (info->mStatus == BufferInfo::OWNED_BY_US) {
336665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            eligible = info;
336765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
336865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
336965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
337065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (eligible == NULL) {
337165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
337265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
337365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
337465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    postFillThisBuffer(eligible);
337565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
337665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
337760cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurentbool ACodec::BaseState::onOMXFillBufferDone(
337860cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent        IOMX::buffer_id bufferID,
33797dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        size_t rangeOffset, size_t rangeLength,
338065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        OMX_U32 flags,
338158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        int64_t timeUs,
338258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        void * /* platformPrivate */,
338358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        void * /* dataPtr */) {
338458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
338558912562617941964939a4182cda71eaeb153d4bGlenn Kasten         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
338658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
338758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    ssize_t index;
338858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
338958912562617941964939a4182cda71eaeb153d4bGlenn Kasten#if TRACK_BUFFER_TIMING
339058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    index = mCodec->mBufferStats.indexOfKey(timeUs);
339158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (index >= 0) {
339265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
339365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
339465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
339565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGI("frame PTS %lld: %lld",
339665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                timeUs,
339765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
339865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
339965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->mBufferStats.removeItemsAt(index);
340065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        stats = NULL;
340165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
340265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#endif
340365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
340465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    BufferInfo *info =
340565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
340658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
340758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
340858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
340958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    info->mDequeuedAt = ++mCodec->mDequeueCounter;
341058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    info->mStatus = BufferInfo::OWNED_BY_US;
341165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
341265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PortMode mode = getPortMode(kPortIndexOutput);
341365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34140bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kasten    switch (mode) {
341565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case KEEP_BUFFERS:
341658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            break;
341765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
341865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case RESUBMIT_BUFFERS:
34190bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kasten        {
342025cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
342158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                ALOGV("[%s] calling fillBuffer %p",
342225cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent                     mCodec->mComponentName.c_str(), info->mBufferID);
342325cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent
342466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                CHECK_EQ(mCodec->mOMX->fillBuffer(
342566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                            mCodec->mNode, info->mBufferID),
342666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                         (status_t)OK);
342766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
342866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
342966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                break;
343066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten            }
343166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
343258912562617941964939a4182cda71eaeb153d4bGlenn Kasten            sp<AMessage> reply =
343366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                new AMessage(kWhatOutputBufferDrained, mCodec->id());
343466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
343565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!mCodec->mSentFormat && rangeLength > 0) {
343672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                mCodec->sendFormatChange(reply);
343772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten            }
343823bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten
343984afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten            if (mCodec->mUseMetadataOnEncoderOutput) {
344084afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten                native_handle_t* handle =
344165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        *(native_handle_t**)(info->mData->data() + 4);
344265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                info->mData->meta()->setPointer("handle", handle);
344365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
344465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                info->mData->meta()->setInt32("rangeLength", rangeLength);
344565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
344665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                info->mData->setRange(rangeOffset, rangeLength);
344765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
34481465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten#if 0
34491465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten            if (mCodec->mNativeWindow == NULL) {
3450000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                if (IsIDR(info->mData)) {
345165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ALOGI("IDR frame");
34521465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten                }
34531465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten            }
3454fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten#endif
345565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3456952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (mCodec->mSkipCutBuffer != NULL) {
3457952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                mCodec->mSkipCutBuffer->submit(info->mData);
3458952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            }
3459fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten            info->mData->meta()->setInt64("timeUs", timeUs);
3460fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten
346165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<AMessage> notify = mCodec->mNotify->dup();
3462952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
3463952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            notify->setPointer("buffer-id", info->mBufferID);
3464952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            notify->setBuffer("buffer", info->mData);
3465952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            notify->setInt32("flags", flags);
3466952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3467952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            reply->setPointer("buffer-id", info->mBufferID);
3468952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3469952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            notify->setMessage("reply", reply);
3470952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3471952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            notify->post();
3472952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3473952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3474952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3475952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (flags & OMX_BUFFERFLAG_EOS) {
3476952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
3477952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3478952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                sp<AMessage> notify = mCodec->mNotify->dup();
3479952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                notify->setInt32("what", ACodec::kWhatEOS);
3480952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                notify->setInt32("err", mCodec->mInputEOSResult);
3481952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                notify->post();
3482952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3483952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                mCodec->mPortEOS[kPortIndexOutput] = true;
3484952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            }
3485952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            break;
3486952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3487952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3488952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        default:
3489952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        {
3490952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3491952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
349265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK_EQ((status_t)OK,
3493952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                     mCodec->freeBuffer(kPortIndexOutput, index));
3494952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            break;
3495952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3496952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
3497952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3498952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    return true;
3499952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten}
3500952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3501952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kastenvoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3502952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    IOMX::buffer_id bufferID;
350365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->findPointer("buffer-id", &bufferID));
350465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3505952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    ssize_t index;
3506952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    BufferInfo *info =
3507952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3508952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3509952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3510952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    android_native_rect_t crop;
3511952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (msg->findRect("crop",
3512952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3513952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        CHECK_EQ(0, native_window_set_crop(
3514952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                mCodec->mNativeWindow.get(), &crop));
3515952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
3516952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3517952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    int32_t render;
3518952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (mCodec->mNativeWindow != NULL
3519952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            && msg->findInt32("render", &render) && render != 0
3520952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            && info->mData != NULL && info->mData->size() != 0) {
3521952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        // The client wants this buffer to be rendered.
3522952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3523000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        status_t err;
3524952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        if ((err = mCodec->mNativeWindow->queueBuffer(
3525952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    mCodec->mNativeWindow.get(),
3526952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    info->mGraphicBuffer.get(), -1)) == OK) {
3527952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
352865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
3529952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            mCodec->signalError(OMX_ErrorUndefined, err);
3530952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            info->mStatus = BufferInfo::OWNED_BY_US;
3531952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3532952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    } else {
3533952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        info->mStatus = BufferInfo::OWNED_BY_US;
3534952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
3535952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3536952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    PortMode mode = getPortMode(kPortIndexOutput);
3537952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3538952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    switch (mode) {
3539952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        case KEEP_BUFFERS:
3540952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        {
3541952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3542952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3543952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3544952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // We cannot resubmit the buffer we just rendered, dequeue
3545b071e9bc248865ef87a339044c0c5cbabfac175cGlenn Kasten                // the spare instead.
3546fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten
3547952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                info = mCodec->dequeueBufferFromNativeWindow();
3548952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            }
3549952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            break;
3550952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3551952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3552952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        case RESUBMIT_BUFFERS:
3553952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        {
3554952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3555a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3556a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    // We cannot resubmit the buffer we just rendered, dequeue
3557a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    // the spare instead.
3558a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
3559a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    info = mCodec->dequeueBufferFromNativeWindow();
3560a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                }
3561a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
3562a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                if (info != NULL) {
3563952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    ALOGV("[%s] calling fillBuffer %p",
3564952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                         mCodec->mComponentName.c_str(), info->mBufferID);
3565952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3566952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3567952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                             (status_t)OK);
3568952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3569952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3570fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten                }
357165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
357265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
3573952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3574952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3575952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        default:
35761465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten        {
3577952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3578952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
35791465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten            CHECK_EQ((status_t)OK,
3580952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                     mCodec->freeBuffer(kPortIndexOutput, index));
3581952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            break;
35825798d4ebf236357a4b13246f40e52b90a34d09a4Glenn Kasten        }
3583952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
3584952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten}
3585952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3586952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten////////////////////////////////////////////////////////////////////////////////
3587952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3588952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn KastenACodec::UninitializedState::UninitializedState(ACodec *codec)
3589952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    : BaseState(codec) {
359065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
3591fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten
3592000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid ACodec::UninitializedState::stateEntered() {
359365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("Now uninitialized");
3594000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
3595000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    if (mDeathNotifier != NULL) {
3596952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3597952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        mDeathNotifier.clear();
3598952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
3599952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3600952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mCodec->mNativeWindow.clear();
3601952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mCodec->mNode = NULL;
3602b071e9bc248865ef87a339044c0c5cbabfac175cGlenn Kasten    mCodec->mOMX.clear();
3603952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mCodec->mQuirks = 0;
3604952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mCodec->mFlags = 0;
3605952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mCodec->mUseMetadataOnEncoderOutput = 0;
3606952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mCodec->mComponentName.clear();
3607952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten}
3608952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3609952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kastenbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3610b071e9bc248865ef87a339044c0c5cbabfac175cGlenn Kasten    bool handled = false;
3611952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3612952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    switch (msg->what()) {
3613952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        case ACodec::kWhatSetup:
3614b071e9bc248865ef87a339044c0c5cbabfac175cGlenn Kasten        {
361573f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            onSetup(msg);
361673f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
361773f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            handled = true;
361873f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            break;
361973f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        }
362073f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
362173f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        case ACodec::kWhatAllocateComponent:
362273f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        {
362373f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            onAllocateComponent(msg);
362473f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            handled = true;
362573f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            break;
362673f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        }
362773f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
3628e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        case ACodec::kWhatShutdown:
362973f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        {
363073f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            int32_t keepComponentAllocated;
363173f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            CHECK(msg->findInt32(
363273f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten                        "keepComponentAllocated", &keepComponentAllocated));
363373f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            CHECK(!keepComponentAllocated);
363473f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
363573f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            sp<AMessage> notify = mCodec->mNotify->dup();
363673f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
363773f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            notify->post();
363873f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
363973f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            handled = true;
364073f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            break;
364173f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        }
364273f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
364373f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        case ACodec::kWhatFlush:
364473f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        {
364573f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            sp<AMessage> notify = mCodec->mNotify->dup();
364673f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            notify->setInt32("what", ACodec::kWhatFlushCompleted);
364773f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            notify->post();
364873f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
364973f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            handled = true;
365073f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            break;
365173f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        }
365273f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
365373f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        default:
365473f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            return BaseState::onMessageReceived(msg);
365573f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    }
365673f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
365773f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    return handled;
365873f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten}
365973f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
366073f4bc33e0d458933460250a47c64aa868c05f97Glenn Kastenvoid ACodec::UninitializedState::onSetup(
366173f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        const sp<AMessage> &msg) {
366273f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    if (onAllocateComponent(msg)
366373f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten            && mCodec->mLoadedState->onConfigureComponent(msg)) {
366473f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        mCodec->mLoadedState->onStart();
366573f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    }
366673f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten}
366773f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
366873f4bc33e0d458933460250a47c64aa868c05f97Glenn Kastenbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
366973f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    ALOGV("onAllocateComponent");
367073f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
367173f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    CHECK(mCodec->mNode == NULL);
367273f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
367373f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    OMXClient client;
367473f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    CHECK_EQ(client.connect(), (status_t)OK);
367573f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
367673f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    sp<IOMX> omx = client.interface();
367773f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
367873f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
367973f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
368073f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    mDeathNotifier = new DeathNotifier(notify);
3681e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
368273f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        // This was a local binder, if it dies so do we, we won't care
368373f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        // about any notifications in the afterlife.
368473f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten        mDeathNotifier.clear();
368573f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    }
368673f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
368773f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
3688000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
3689000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    AString mime;
3690000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
3691000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    AString componentName;
3692952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    uint32_t quirks = 0;
3693fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten    if (msg->findString("componentName", &componentName)) {
3694952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        ssize_t index = matchingCodecs.add();
3695952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3696952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        entry->mName = String8(componentName.c_str());
3697952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3698952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        if (!OMXCodec::findCodecQuirks(
369958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    componentName.c_str(), &entry->mQuirks)) {
3700952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            entry->mQuirks = 0;
3701952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
370265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
370365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK(msg->findString("mime", &mime));
370465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37057d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi        int32_t encoder;
370665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!msg->findInt32("encoder", &encoder)) {
370765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            encoder = false;
370865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
370965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
371065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        OMXCodec::findMatchingCodecs(
371165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mime.c_str(),
371265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                encoder, // createEncoder
371365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                NULL,  // matchComponentName
371465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                0,     // flags
371565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                &matchingCodecs);
371665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
371765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
371865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<CodecObserver> observer = new CodecObserver;
371965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    IOMX::node_id node = NULL;
372065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
372165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
372265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ++matchIndex) {
372365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
372465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
372565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
372665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        pid_t tid = androidGetTid();
372765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int prevPriority = androidGetThreadPriority(tid);
372865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
372965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
373065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        androidSetThreadPriority(tid, prevPriority);
373165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
373265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err == OK) {
373365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
373465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
373565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
373665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        node = NULL;
3737799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    }
3738fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
373965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (node == NULL) {
3740e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        if (!mime.empty()) {
3741e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            ALOGE("Unable to instantiate a decoder for type '%s'.",
3742e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                 mime.c_str());
3743e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        } else {
3744fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
374565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
374665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
374765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->signalError(OMX_ErrorComponentNotFound);
374865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return false;
374965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
375065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
375165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify = new AMessage(kWhatOMXMessage, mCodec->id());
375265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    observer->setNotificationMessage(notify);
375365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
375465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCodec->mComponentName = componentName;
375565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCodec->mFlags = 0;
375660cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent
375760cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent    if (componentName.endsWith(".secure")) {
37587dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        mCodec->mFlags |= kFlagIsSecure;
375965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
376065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
376165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
376265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCodec->mQuirks = quirks;
37630bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kasten    mCodec->mOMX = omx;
376465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCodec->mNode = node;
376565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3766fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    {
3767162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent        sp<AMessage> notify = mCodec->mNotify->dup();
376865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->setInt32("what", ACodec::kWhatComponentAllocated);
376965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->setString("componentName", mCodec->mComponentName.c_str());
377065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->post();
377165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
377265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
377365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCodec->changeState(mCodec->mLoadedState);
37740bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kasten
377565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return true;
377665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
3777fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
377860e182437228312cc28469a5b0dfde77ac848e1aEric Laurent////////////////////////////////////////////////////////////////////////////////
377965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
378065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianACodec::LoadedState::LoadedState(ACodec *codec)
378165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BaseState(codec) {
378265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
378365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
378465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::LoadedState::stateEntered() {
37850bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kasten    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
378625cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent
378725cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    mCodec->mPortEOS[kPortIndexInput] =
3788fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        mCodec->mPortEOS[kPortIndexOutput] = false;
378925cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent
379025cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    mCodec->mInputEOSResult = OK;
379125cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent
379225cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    mCodec->mDequeueCounter = 0;
379325cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    mCodec->mMetaDataBuffersToSubmit = 0;
379425cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    mCodec->mRepeatFrameDelayUs = -1ll;
379525cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    mCodec->mIsConfiguredForAdaptivePlayback = false;
379666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
379766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    if (mCodec->mShutdownInProgress) {
379866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
379966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
380066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        mCodec->mShutdownInProgress = false;
380166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        mCodec->mKeepComponentAllocated = false;
380266fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
380366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        onShutdown(keepComponentAllocated);
380425cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    }
380565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
380665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
380723bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kastenvoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
380872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    if (!keepComponentAllocated) {
380923bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
381023bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten
381165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->changeState(mCodec->mUninitializedState);
381265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
381365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
381465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> notify = mCodec->mNotify->dup();
381565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
381665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->post();
381765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
381865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
381965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
382065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool handled = false;
382165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3822000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    switch (msg->what()) {
382365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case ACodec::kWhatConfigureComponent:
3824952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        {
3825952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            onConfigureComponent(msg);
3826952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            handled = true;
3827952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            break;
3828952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3829952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3830952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        case ACodec::kWhatCreateInputSurface:
383158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        {
3832000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            onCreateInputSurface(msg);
3833000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            handled = true;
3834000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            break;
3835000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        }
3836952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3837fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten        case ACodec::kWhatStart:
3838952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        {
3839952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            onStart();
3840952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            handled = true;
3841952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            break;
3842952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3843952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3844952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        case ACodec::kWhatShutdown:
3845952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        {
3846952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            int32_t keepComponentAllocated;
3847952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            CHECK(msg->findInt32(
3848952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                        "keepComponentAllocated", &keepComponentAllocated));
3849952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
385065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            onShutdown(keepComponentAllocated);
3851952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3852952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            handled = true;
3853000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            break;
385465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
3855000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
3856000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        case ACodec::kWhatFlush:
385766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        {
3858952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            sp<AMessage> notify = mCodec->mNotify->dup();
3859952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3860952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            notify->post();
3861952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3862000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            handled = true;
3863688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten            break;
3864000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten        }
3865000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
3866952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        default:
3867952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            return BaseState::onMessageReceived(msg);
3868952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
3869952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
387065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return handled;
387165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
3872fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten
3873fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kastenbool ACodec::LoadedState::onConfigureComponent(
3874fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten        const sp<AMessage> &msg) {
3875fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    ALOGV("onConfigureComponent");
3876fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten
3877fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    CHECK(mCodec->mNode != NULL);
3878fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten
3879fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    AString mime;
3880fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    CHECK(msg->findString("mime", &mime));
3881fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten
388265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = mCodec->configureCodec(mime.c_str(), msg);
388365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3884b6b740629c9f11535086e744465bada03f26df11Glenn Kasten    if (err != OK) {
388599e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten        ALOGE("[%s] configureCodec returning error %d",
388658912562617941964939a4182cda71eaeb153d4bGlenn Kasten              mCodec->mComponentName.c_str(), err);
38879eaa55756c5b245970447019250ce852f5189525Glenn Kasten
388865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->signalError(OMX_ErrorUndefined, err);
388965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return false;
389065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
38910d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
389265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<RefBase> obj;
389365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (msg->findObject("native-window", &obj)
3894fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
389565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<NativeWindowWrapper> nativeWindow(
38963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                static_cast<NativeWindowWrapper *>(obj.get()));
3897438b036deaf4413503567a75a2861c000d21da5bGlenn Kasten        CHECK(nativeWindow != NULL);
389865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
389965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
390065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        native_window_set_scaling_mode(
390165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mNativeWindow.get(),
390265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
390365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
390465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3905a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten
390665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
390765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> notify = mCodec->mNotify->dup();
3908438b036deaf4413503567a75a2861c000d21da5bGlenn Kasten        notify->setInt32("what", ACodec::kWhatComponentConfigured);
390965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->post();
391065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
391165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    return true;
391365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
391465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3915438b036deaf4413503567a75a2861c000d21da5bGlenn Kastenvoid ACodec::LoadedState::onCreateInputSurface(
3916438b036deaf4413503567a75a2861c000d21da5bGlenn Kasten        const sp<AMessage> & /* msg */) {
391765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("onCreateInputSurface");
391865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
391965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> notify = mCodec->mNotify->dup();
392065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
39217378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten
392265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<IGraphicBufferProducer> bufferProducer;
392365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err;
392465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
392565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
392665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            &bufferProducer);
392765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
392865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
392965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = mCodec->mOMX->setInternalOption(
393065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mNode,
393102fe1bf923bbe5789202dbd5810e2c04794562e6Glenn Kasten                kPortIndexInput,
393265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
393365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                &mCodec->mRepeatFrameDelayUs,
3934e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                sizeof(mCodec->mRepeatFrameDelayUs));
393565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39365ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        if (err != OK) {
393765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("[%s] Unable to configure option to repeat previous "
393865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  "frames (err %d)",
393965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  mCodec->mComponentName.c_str(),
394065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  err);
39413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        }
394265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
394365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
394465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err == OK && mCodec->mMaxPtsGapUs > 0l) {
394565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = mCodec->mOMX->setInternalOption(
394665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mNode,
394765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                kPortIndexInput,
39480bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kasten                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
394965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                &mCodec->mMaxPtsGapUs,
395065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sizeof(mCodec->mMaxPtsGapUs));
395165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
395265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != OK) {
395366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
395466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                    mCodec->mComponentName.c_str(),
395566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                    err);
395666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten          }
395766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten      }
395866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
395966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
396066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten        bool suspend = true;
396165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        err = mCodec->mOMX->setInternalOption(
396265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mNode,
396365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                kPortIndexInput,
396465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                IOMX::INTERNAL_OPTION_SUSPEND,
39659eaa55756c5b245970447019250ce852f5189525Glenn Kasten                &suspend,
396665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sizeof(suspend));
396765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
396858f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        if (err != OK) {
39690d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            ALOGE("[%s] Unable to configure option to suspend (err %d)",
397065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  mCodec->mComponentName.c_str(),
397165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  err);
397265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
397365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
397465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
397565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err == OK) {
397684afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        notify->setObject("input-surface",
397784afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten                new BufferProducerWrapper(bufferProducer));
397884afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    } else {
397965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Can't use mCodec->signalError() here -- MediaCodec won't forward
398065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the error through because it's in the "configured" state.  We
398158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // send a kWhatInputSurfaceCreated with an error value instead.
398265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGE("[%s] onCreateInputSurface returning error %d",
39835cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten                mCodec->mComponentName.c_str(), err);
398465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->setInt32("err", err);
398584afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    }
398684afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    notify->post();
398765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
39883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
398965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::LoadedState::onStart() {
3990b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGV("onStart");
3991e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
3992e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    CHECK_EQ(mCodec->mOMX->sendCommand(
3993e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3994e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten             (status_t)OK);
3995e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
3996e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    mCodec->changeState(mCodec->mLoadedToIdleState);
3997e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten}
3998e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
399965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
400065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
400165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4002a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    : BaseState(codec) {
400365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
400465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
400565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::LoadedToIdleState::stateEntered() {
400665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4007a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen
4008a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen    status_t err;
4009a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen    if ((err = allocateBuffers()) != OK) {
4010a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4011a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen             "(error 0x%08x)",
40120d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi             err);
40130d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
401465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->signalError(OMX_ErrorUndefined, err);
401565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
401665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCodec->changeState(mCodec->mLoadedState);
401765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
401844d9848d6656777a18019223e0d35f2fcc67719aEric Laurent}
401965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
402065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
402165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
402265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
402365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
402465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return err;
402565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
402629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
402765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
402865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
402965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4030e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kastenbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4031e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    switch (msg->what()) {
4032ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        case kWhatSetParameters:
4033ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        case kWhatShutdown:
4034ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        {
4035ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten            mCodec->deferMessage(msg);
4036ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten            return true;
4037a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen        }
4038a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen
4039a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen        case kWhatSignalEndOfInputStream:
4040a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen        {
4041a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen            mCodec->onSignalEndOfInputStream();
4042ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten            return true;
4043ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        }
4044ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten
4045ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        case kWhatResume:
4046ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        {
4047ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten            // We'll be active soon enough.
4048ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten            return true;
4049ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        }
4050e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
405165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatFlush:
405265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
405365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // We haven't even started yet, so we're flushed alright...
405465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<AMessage> notify = mCodec->mNotify->dup();
4055a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten            notify->setInt32("what", ACodec::kWhatFlushCompleted);
40561a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten            notify->post();
405765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return true;
40581a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten        }
40591a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten
406065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
406165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BaseState::onMessageReceived(msg);
4062dbfafaffe2e97eaf8d74ec6b6c468418a1ad2443Glenn Kasten    }
40637378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten}
406484afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten
406565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ACodec::LoadedToIdleState::onOMXEvent(
40667378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
40677378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    switch (event) {
40687378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        case OMX_EventCmdComplete:
406965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
407065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
407165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
407265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
407301c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten            CHECK_EQ(mCodec->mOMX->sendCommand(
407401c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
407501c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten                     (status_t)OK);
407665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
407765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCodec->changeState(mCodec->mIdleToExecutingState);
4078e0feee3da22beeffbd9357540e265f13b2119cbbGlenn Kasten
407965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return true;
4080288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
408101c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten
408265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
408365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BaseState::onOMXEvent(event, data1, data2);
408465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
408565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
408665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
408765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
408865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
408965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
409065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BaseState(codec) {
40913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block}
40925cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten
409365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::IdleToExecutingState::stateEntered() {
409465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
409565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
409665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
409765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
409865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (msg->what()) {
409965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatSetParameters:
410065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatShutdown:
410165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
410265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCodec->deferMessage(msg);
410365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return true;
41045cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten        }
41053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
410665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatResume:
410765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
410865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // We'll be active soon enough.
410965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return true;
411065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
411165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
411265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatFlush:
411365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
4114b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kasten            // We haven't even started yet, so we're flushed alright...
4115b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kasten            sp<AMessage> notify = mCodec->mNotify->dup();
4116b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kasten            notify->setInt32("what", ACodec::kWhatFlushCompleted);
411765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            notify->post();
411865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4119acb86cccbd9d245439a04cef0bcefa589addaa4cJean-Michel Trivi            return true;
4120acb86cccbd9d245439a04cef0bcefa589addaa4cJean-Michel Trivi        }
4121acb86cccbd9d245439a04cef0bcefa589addaa4cJean-Michel Trivi
4122acb86cccbd9d245439a04cef0bcefa589addaa4cJean-Michel Trivi        case kWhatSignalEndOfInputStream:
412365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
4124acb86cccbd9d245439a04cef0bcefa589addaa4cJean-Michel Trivi            mCodec->onSignalEndOfInputStream();
412565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return true;
412665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
412765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
412865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
4129a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            return BaseState::onMessageReceived(msg);
4130a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
4131a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
4132a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4133a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentbool ACodec::IdleToExecutingState::onOMXEvent(
4134a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
413565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (event) {
413665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case OMX_EventCmdComplete:
413765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
413865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
41399eaa55756c5b245970447019250ce852f5189525Glenn Kasten            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
414065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4141fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten            mCodec->mExecutingState->resume();
414265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCodec->changeState(mCodec->mExecutingState);
414358f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten
41440d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            return true;
414565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
414665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
414773d227557ba5192735356bacab9f77b44980793bGlenn Kasten        default:
414873d227557ba5192735356bacab9f77b44980793bGlenn Kasten            return BaseState::onOMXEvent(event, data1, data2);
41495cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten    }
4150f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten}
415158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
4152f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten////////////////////////////////////////////////////////////////////////////////
4153f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten
4154f99590187e2e3f1cf6f093063170edec269cac5dGlenn KastenACodec::ExecutingState::ExecutingState(ACodec *codec)
4155f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten    : BaseState(codec),
4156f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten      mActive(false) {
4157f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten}
4158a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
415973d227557ba5192735356bacab9f77b44980793bGlenn KastenACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
416058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        OMX_U32 /* portIndex */) {
416158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    return RESUBMIT_BUFFERS;
4162288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten}
416358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
416465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
416565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // submit as many buffers as there are input buffers with the codec
416665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // in case we are in port reconfiguring
416765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4168edc15ad8fcde12dc4f642d80d077239b1532eecaEric Laurent        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
416958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
417058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
417158912562617941964939a4182cda71eaeb153d4bGlenn Kasten            if (mCodec->submitOutputMetaDataBuffer() != OK)
417258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                break;
417358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
4174288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
4175288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4176288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4177288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
417858912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
4179288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
418009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kastenvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
418158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
418258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4183f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten
41847d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi        if (mCodec->mNativeWindow != NULL) {
4185f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4186f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4187288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4188288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4189288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                continue;
4190f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten            }
419165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
4192f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
419365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
419465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
419565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGV("[%s] calling fillBuffer %p",
419665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             mCodec->mComponentName.c_str(), info->mBufferID);
41973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
419865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
419965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                 (status_t)OK);
420065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
420165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
420265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
420365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
420465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
420565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::ExecutingState::submitOutputBuffers() {
420665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    submitRegularOutputBuffers();
420765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mCodec->mStoreMetaDataInOutputBuffers) {
420865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        submitOutputMetaBuffers();
420999e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten    }
421065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
421165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
421265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::ExecutingState::resume() {
421365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mActive) {
421465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGV("[%s] We're already active, no need to resume.",
421565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             mCodec->mComponentName.c_str());
421665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
421765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
421865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
421965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
422065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    submitOutputBuffers();
422102bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten
42229ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    // Post the first input buffer.
4223d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
42249ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
42259ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
4226d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten    postFillThisBuffer(info);
422765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
422865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mActive = true;
422965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
423065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
423165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::ExecutingState::stateEntered() {
423265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
423365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
423465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCodec->processDeferredMessages();
423565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
423665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4237288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kastenbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4238288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    bool handled = false;
4239e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten
4240e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten    switch (msg->what()) {
4241288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        case kWhatShutdown:
4242288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        {
424365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int32_t keepComponentAllocated;
424465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK(msg->findInt32(
424583d86538c4c479a9225c75ab27938e8f05abb9c8Glenn Kasten                        "keepComponentAllocated", &keepComponentAllocated));
424658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
4247288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            mCodec->mShutdownInProgress = true;
424858912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mCodec->mKeepComponentAllocated = keepComponentAllocated;
424958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
425058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mActive = false;
4251288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4252288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            CHECK_EQ(mCodec->mOMX->sendCommand(
4253288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4254288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                     (status_t)OK);
4255288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4256288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            mCodec->changeState(mCodec->mExecutingToIdleState);
4257288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4258288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            handled = true;
4259288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            break;
4260d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        }
4261d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
4262d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        case kWhatFlush:
4263d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        {
4264d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            ALOGV("[%s] ExecutingState flushing now "
4265d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                 "(codec owns %d/%d input, %d/%d output).",
4266288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    mCodec->mComponentName.c_str(),
4267288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4268288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    mCodec->mBuffers[kPortIndexInput].size(),
4269288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4270288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    mCodec->mBuffers[kPortIndexOutput].size());
4271288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4272288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            mActive = false;
4273288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4274288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            CHECK_EQ(mCodec->mOMX->sendCommand(
4275288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4276288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                     (status_t)OK);
4277288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4278288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            mCodec->changeState(mCodec->mFlushingState);
4279288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            handled = true;
4280288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            break;
4281288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
4282288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4283288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        case kWhatResume:
4284288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        {
428509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            resume();
428609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten
428709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            handled = true;
428809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            break;
428909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        }
429009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten
429109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        case kWhatRequestIDRFrame:
429209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        {
429309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            status_t err = mCodec->requestIDRFrame();
429409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            if (err != OK) {
429509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                ALOGW("Requesting an IDR frame failed.");
429609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            }
429709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten
429809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            handled = true;
429909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            break;
4300e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten        }
4301e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten
430244deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten        case kWhatSetParameters:
430365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
430465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<AMessage> params;
43050d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            CHECK(msg->findMessage("params", &params));
430665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
430765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            status_t err = mCodec->setParameters(params);
4308e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten
4309288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            sp<AMessage> reply;
431065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (msg->findMessage("reply", &reply)) {
431165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                reply->setInt32("err", err);
431265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                reply->post();
431358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
431458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
431565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            handled = true;
431665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
431765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
4318288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4319e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten        case ACodec::kWhatSignalEndOfInputStream:
4320288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        {
432109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            mCodec->onSignalEndOfInputStream();
432265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            handled = true;
432365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
432401c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten        }
43254ff14bae91075eb274eb1c2975982358946e7e63John Grossman
4326e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
432765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatSubmitOutputMetaDataBufferIfEOS:
4328e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        {
4329e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            if (mCodec->mPortEOS[kPortIndexInput] &&
4330e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    !mCodec->mPortEOS[kPortIndexOutput]) {
433165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status_t err = mCodec->submitOutputMetaDataBuffer();
4332e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                if (err == OK) {
4333e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4334288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                }
4335288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
4336288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            return true;
4337288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
4338288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4339288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        default:
4340288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            handled = BaseState::onMessageReceived(msg);
4341e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            break;
4342e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
4343e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
4344e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    return handled;
434565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
4346288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4347e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kastenstatus_t ACodec::setParameters(const sp<AMessage> &params) {
434865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t videoBitrate;
4349e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (params->findInt32("video-bitrate", &videoBitrate)) {
435065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
435165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        InitOMXParams(&configParams);
435265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        configParams.nPortIndex = kPortIndexOutput;
435365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        configParams.nEncodeBitrate = videoBitrate;
435465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
435565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t err = mOMX->setConfig(
435665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mNode,
4357a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen                OMX_IndexConfigVideoBitrate,
435865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                &configParams,
435965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sizeof(configParams));
436065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4361e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        if (err != OK) {
4362e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
436365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                   videoBitrate, err);
4364e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
436565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return err;
4366e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        }
436765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
436865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4369e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    int64_t skipFramesBeforeUs;
4370e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
4371e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        status_t err =
4372e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mOMX->setInternalOption(
437365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                     mNode,
437465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                     kPortIndexInput,
4375288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                     IOMX::INTERNAL_OPTION_START_TIME,
4376288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                     &skipFramesBeforeUs,
4377288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                     sizeof(skipFramesBeforeUs));
4378288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
4379288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        if (err != OK) {
4380288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
4381288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            return err;
4382288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
4383288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
43844ff14bae91075eb274eb1c2975982358946e7e63John Grossman
43854ff14bae91075eb274eb1c2975982358946e7e63John Grossman    int32_t dropInputFrames;
43864ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4387288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        bool suspend = dropInputFrames != 0;
438865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4389af59ce2407fa4e6e5d8f1664a4df2daf1badd407Eric Laurent        status_t err =
439065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mOMX->setInternalOption(
43914ff14bae91075eb274eb1c2975982358946e7e63John Grossman                     mNode,
439265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                     kPortIndexInput,
439365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                     IOMX::INTERNAL_OPTION_SUSPEND,
439438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                     &suspend,
439565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                     sizeof(suspend));
439665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
439765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != OK) {
439865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
439965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return err;
44003acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        }
4401a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
440265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
440365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t dummy;
440458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (params->findInt32("request-sync", &dummy)) {
440558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        status_t err = requestIDRFrame();
44063acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
440765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err != OK) {
440865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("Requesting a sync frame failed w/ err %d", err);
440965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return err;
4410b853e986caf43408ad95b9014f194aadff385e3cGlenn Kasten        }
441165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
441265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
441365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
441465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
44153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
441665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::onSignalEndOfInputStream() {
441765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> notify = mNotify->dup();
44183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
441965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
442065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = mOMX->signalEndOfInputStream(mNode);
442165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
442265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->setInt32("err", err);
442302bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten    }
442465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notify->post();
44259ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang}
4426d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten
44279ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wangbool ACodec::ExecutingState::onOMXEvent(
44289ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
44299ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    switch (event) {
44309ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        case OMX_EventPortSettingsChanged:
4431d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten        {
443265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
443365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
443465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
443565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mMetaDataBuffersToSubmit = 0;
443665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                CHECK_EQ(mCodec->mOMX->sendCommand(
443765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mCodec->mNode,
443865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            OMX_CommandPortDisable, kPortIndexOutput),
443965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         (status_t)OK);
444065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
444165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->freeOutputBuffersNotOwnedByComponent();
444265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
444365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
444465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
444565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mSentFormat = false;
444665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
444723d82a9bc9a43b49ba684ba40875b91db310d3b9Glenn Kasten                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
444865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                     mCodec->mComponentName.c_str(), data2);
444965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
445065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4451b853e986caf43408ad95b9014f194aadff385e3cGlenn Kasten            return true;
4452d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        }
445365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
445465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case OMX_EventBufferFlag:
445565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
445665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return true;
4457d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        }
4458d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
4459d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        default:
4460d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            return BaseState::onOMXEvent(event, data1, data2);
4461d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    }
4462d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten}
4463d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
446465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian////////////////////////////////////////////////////////////////////////////////
4465d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten
446665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
446765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ACodec *codec)
446865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BaseState(codec) {
446902bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten}
447065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44719ee159b79022b2e1a050acb3890ce948e99e9ccbGloria WangACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4472d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten        OMX_U32 portIndex) {
44739ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    if (portIndex == kPortIndexOutput) {
44749ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        return FREE_BUFFERS;
4475d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten    }
447665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
447765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
447865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
447965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return RESUBMIT_BUFFERS;
448065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
448165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
448223d82a9bc9a43b49ba684ba40875b91db310d3b9Glenn Kastenbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
448365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<AMessage> &msg) {
448465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool handled = false;
448565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
448665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (msg->what()) {
448765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatFlush:
44883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        case kWhatShutdown:
448965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case kWhatResume:
449065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
449102bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten            if (msg->what() == kWhatResume) {
449265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
44939ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            }
4494d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten
44959ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            mCodec->deferMessage(msg);
44969ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            handled = true;
4497d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten            break;
449865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
449965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
450065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
450165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            handled = BaseState::onMessageReceived(msg);
450265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
450365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
450465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    return handled;
450665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
450765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
450865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid ACodec::OutputPortSettingsChangedState::stateEntered() {
4509d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    ALOGV("[%s] Now handling output port settings change",
4510d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten         mCodec->mComponentName.c_str());
451165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
451265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
451365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
451465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
451565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (event) {
451638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        case OMX_EventCmdComplete:
451738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        {
4518d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4519d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
452038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent
452138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                ALOGV("[%s] Output port now disabled.",
452238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                        mCodec->mComponentName.c_str());
452338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent
452465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
452565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->mDealer[kPortIndexOutput].clear();
452665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
452765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                CHECK_EQ(mCodec->mOMX->sendCommand(
452865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
452965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         (status_t)OK);
453065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
453165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status_t err;
453265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if ((err = mCodec->allocateBuffersOnPort(
453365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                kPortIndexOutput)) != OK) {
453465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ALOGE("Failed to allocate output port buffers after "
453538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                         "port reconfiguration (error 0x%08x)",
453638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                         err);
453765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
453865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mCodec->signalError(OMX_ErrorUndefined, err);
4539a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
454065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // This is technically not correct, but appears to be
454165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // the only way to free the component instance.
454265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // Controlled transitioning from excecuting->idle
454365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // and idle->loaded seem impossible probably because
454465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // the output port never finishes re-enabling.
454565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mCodec->mShutdownInProgress = true;
454665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mCodec->mKeepComponentAllocated = false;
454765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mCodec->changeState(mCodec->mLoadedState);
454865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
454965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
455065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                return true;
455165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
455265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4553e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
4554e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                mCodec->mSentFormat = false;
455565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
455665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                ALOGV("[%s] Output port now reenabled.",
455765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mCodec->mComponentName.c_str());
455865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
455965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (mCodec->mExecutingState->active()) {
456065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mCodec->mExecutingState->submitOutputBuffers();
456165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
456265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
456365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCodec->changeState(mCodec->mExecutingState);
456465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4565a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                return true;
4566a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            }
4567a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4568a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            return false;
4569a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
4570a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4571a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        default:
4572a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            return false;
4573a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
4574a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
4575a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4576a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent////////////////////////////////////////////////////////////////////////////////
4577a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4578a011e35b22f95f558d81dc9c94b68b1465c4661dEric LaurentACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
4579a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    : BaseState(codec),
4580a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent      mComponentNowIdle(false) {
4581a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
4582a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4583a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4584a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    bool handled = false;
4585a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4586a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    switch (msg->what()) {
4587a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        case kWhatFlush:
4588a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        {
4589a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            // Don't send me a flush request if you previously wanted me
4590a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            // to shutdown.
4591a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            TRESPASS();
4592a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            break;
4593a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
4594a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4595a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        case kWhatShutdown:
4596a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        {
459758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            // We're already doing that...
459858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
459958912562617941964939a4182cda71eaeb153d4bGlenn Kasten            handled = true;
460058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            break;
460158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
460258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
460358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        default:
460458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            handled = BaseState::onMessageReceived(msg);
460558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            break;
460658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
460758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
460858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    return handled;
460958912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
461058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
461158912562617941964939a4182cda71eaeb153d4bGlenn Kastenvoid ACodec::ExecutingToIdleState::stateEntered() {
461258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
461358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
461458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mComponentNowIdle = false;
461558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mCodec->mSentFormat = false;
461658912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
461758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
461858912562617941964939a4182cda71eaeb153d4bGlenn Kastenbool ACodec::ExecutingToIdleState::onOMXEvent(
461958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
462058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    switch (event) {
462158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        case OMX_EventCmdComplete:
462258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        {
4623a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
46244ff14bae91075eb274eb1c2975982358946e7e63John Grossman            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
46254ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46264ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mComponentNowIdle = true;
46274ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46289eaa55756c5b245970447019250ce852f5189525Glenn Kasten            changeStateIfWeOwnAllBuffers();
46294ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46304ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return true;
46314ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
46324ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46334ff14bae91075eb274eb1c2975982358946e7e63John Grossman        case OMX_EventPortSettingsChanged:
46344ff14bae91075eb274eb1c2975982358946e7e63John Grossman        case OMX_EventBufferFlag:
46354ff14bae91075eb274eb1c2975982358946e7e63John Grossman        {
46364ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // We're shutting down and don't care about this anymore.
46374ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return true;
46384ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
46394ff14bae91075eb274eb1c2975982358946e7e63John Grossman
4640a03567676e8766828ff970b87e13bc4c97b23473Glenn Kasten        default:
46414ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return BaseState::onOMXEvent(event, data1, data2);
46424ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
46434ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
46444ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46454ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
46469eaa55756c5b245970447019250ce852f5189525Glenn Kasten    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
46474ff14bae91075eb274eb1c2975982358946e7e63John Grossman        CHECK_EQ(mCodec->mOMX->sendCommand(
46484ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
46494ff14bae91075eb274eb1c2975982358946e7e63John Grossman                 (status_t)OK);
46504ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46514ff14bae91075eb274eb1c2975982358946e7e63John Grossman        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
46524ff14bae91075eb274eb1c2975982358946e7e63John Grossman        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
46534ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46544ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
46554ff14bae91075eb274eb1c2975982358946e7e63John Grossman                && mCodec->mNativeWindow != NULL) {
465673d227557ba5192735356bacab9f77b44980793bGlenn Kasten            // We push enough 1x1 blank buffers to ensure that one of
46579fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            // them has made it to the display.  This allows the OMX
46589fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            // component teardown to zero out any protected buffers
46591c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            // without the risk of scanning out one of those buffers.
46604ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mCodec->pushBlankBuffersToNativeWindow();
46614ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
46624ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46634ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mCodec->changeState(mCodec->mIdleToLoadedState);
46644ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
46654ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
46664ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46674ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid ACodec::ExecutingToIdleState::onInputBufferFilled(
46684ff14bae91075eb274eb1c2975982358946e7e63John Grossman        const sp<AMessage> &msg) {
46694ff14bae91075eb274eb1c2975982358946e7e63John Grossman    BaseState::onInputBufferFilled(msg);
46704ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46714ff14bae91075eb274eb1c2975982358946e7e63John Grossman    changeStateIfWeOwnAllBuffers();
46724ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
46734ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46749fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossmanvoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
46759fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        const sp<AMessage> &msg) {
46769fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    BaseState::onOutputBufferDrained(msg);
46779fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
46789fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    changeStateIfWeOwnAllBuffers();
46799fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman}
46809fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
46814ff14bae91075eb274eb1c2975982358946e7e63John Grossman////////////////////////////////////////////////////////////////////////////////
46824ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46834ff14bae91075eb274eb1c2975982358946e7e63John GrossmanACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
46844ff14bae91075eb274eb1c2975982358946e7e63John Grossman    : BaseState(codec) {
46854ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
46864ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46874ff14bae91075eb274eb1c2975982358946e7e63John Grossmanbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
46884ff14bae91075eb274eb1c2975982358946e7e63John Grossman    bool handled = false;
46894ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46904ff14bae91075eb274eb1c2975982358946e7e63John Grossman    switch (msg->what()) {
46914ff14bae91075eb274eb1c2975982358946e7e63John Grossman        case kWhatShutdown:
46924ff14bae91075eb274eb1c2975982358946e7e63John Grossman        {
46934ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // We're already doing that...
46944ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46954ff14bae91075eb274eb1c2975982358946e7e63John Grossman            handled = true;
46964ff14bae91075eb274eb1c2975982358946e7e63John Grossman            break;
46974ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
46984ff14bae91075eb274eb1c2975982358946e7e63John Grossman
46994ff14bae91075eb274eb1c2975982358946e7e63John Grossman        case kWhatFlush:
47004ff14bae91075eb274eb1c2975982358946e7e63John Grossman        {
47014ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // Don't send me a flush request if you previously wanted me
47024ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // to shutdown.
47034ff14bae91075eb274eb1c2975982358946e7e63John Grossman            TRESPASS();
47044ff14bae91075eb274eb1c2975982358946e7e63John Grossman            break;
47054ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
47064ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47074ff14bae91075eb274eb1c2975982358946e7e63John Grossman        default:
47084ff14bae91075eb274eb1c2975982358946e7e63John Grossman            handled = BaseState::onMessageReceived(msg);
47094ff14bae91075eb274eb1c2975982358946e7e63John Grossman            break;
47104ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
47114ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47124ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return handled;
47134ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
47144ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47154ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid ACodec::IdleToLoadedState::stateEntered() {
47164ff14bae91075eb274eb1c2975982358946e7e63John Grossman    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
47174ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
47184ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47194ff14bae91075eb274eb1c2975982358946e7e63John Grossmanbool ACodec::IdleToLoadedState::onOMXEvent(
47204ff14bae91075eb274eb1c2975982358946e7e63John Grossman        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
47214ff14bae91075eb274eb1c2975982358946e7e63John Grossman    switch (event) {
47224ff14bae91075eb274eb1c2975982358946e7e63John Grossman        case OMX_EventCmdComplete:
47234ff14bae91075eb274eb1c2975982358946e7e63John Grossman        {
47244ff14bae91075eb274eb1c2975982358946e7e63John Grossman            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
47254ff14bae91075eb274eb1c2975982358946e7e63John Grossman            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
47264ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47274ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mCodec->changeState(mCodec->mLoadedState);
47284ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47294ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return true;
47304ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
47314ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47324ff14bae91075eb274eb1c2975982358946e7e63John Grossman        default:
47334ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return BaseState::onOMXEvent(event, data1, data2);
47344ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
47354ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
47364ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47374ff14bae91075eb274eb1c2975982358946e7e63John Grossman////////////////////////////////////////////////////////////////////////////////
47381c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
47391c345196edc61694f29307a1826a64a0d26028dcJohn GrossmanACodec::FlushingState::FlushingState(ACodec *codec)
47409fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    : BaseState(codec) {
47419fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman}
4742c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman
4743c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossmanvoid ACodec::FlushingState::stateEntered() {
4744c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4745c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman
4746c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4747c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman}
4748c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman
4749c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossmanbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4750c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman    bool handled = false;
4751c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman
4752c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman    switch (msg->what()) {
4753c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        case kWhatShutdown:
4754c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        {
4755c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            mCodec->deferMessage(msg);
4756c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            break;
4757c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        }
4758c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman
4759c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        case kWhatFlush:
4760c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        {
4761c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // We're already doing this right now.
4762c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            handled = true;
4763c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            break;
4764c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        }
4765c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman
4766c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        default:
4767c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            handled = BaseState::onMessageReceived(msg);
4768c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            break;
4769c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman    }
4770c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman
47719fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    return handled;
47729fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman}
47739fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
47744ff14bae91075eb274eb1c2975982358946e7e63John Grossmanbool ACodec::FlushingState::onOMXEvent(
47759fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
47769fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
47779fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            mCodec->mComponentName.c_str(), event, data1);
47789fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
47791c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    switch (event) {
47809fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        case OMX_EventCmdComplete:
47819fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        {
47824ff14bae91075eb274eb1c2975982358946e7e63John Grossman            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
47834ff14bae91075eb274eb1c2975982358946e7e63John Grossman
47849fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
47851c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                CHECK(!mFlushComplete[data2]);
47861c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                mFlushComplete[data2] = true;
47871c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
47881c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                if (mFlushComplete[kPortIndexInput]
47891c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                        && mFlushComplete[kPortIndexOutput]) {
47901c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                    changeStateIfWeOwnAllBuffers();
47911c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                }
47921c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            } else {
47934ff14bae91075eb274eb1c2975982358946e7e63John Grossman                CHECK_EQ(data2, OMX_ALL);
47944ff14bae91075eb274eb1c2975982358946e7e63John Grossman                CHECK(mFlushComplete[kPortIndexInput]);
47954ff14bae91075eb274eb1c2975982358946e7e63John Grossman                CHECK(mFlushComplete[kPortIndexOutput]);
47961c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
47971c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                changeStateIfWeOwnAllBuffers();
4798d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman            }
4799d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman
4800d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman            return true;
48011c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        }
48021c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
48031c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        case OMX_EventPortSettingsChanged:
48041c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        {
48051c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
48061c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            msg->setInt32("type", omx_message::EVENT);
48071c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            msg->setPointer("node", mCodec->mNode);
48081c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            msg->setInt32("event", event);
48091c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            msg->setInt32("data1", data1);
48101c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            msg->setInt32("data2", data2);
48111c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
4812b388e531613730572067e193b6b66afb5d042233Eric Laurent            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4813d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                 mCodec->mComponentName.c_str());
4814d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman
4815d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman            mCodec->deferMessage(msg);
4816b388e531613730572067e193b6b66afb5d042233Eric Laurent
48171c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            return true;
48181c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        }
4819d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman
4820d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman        default:
4821d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman            return BaseState::onOMXEvent(event, data1, data2);
4822d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman    }
4823d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman
48241c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    return true;
48251c345196edc61694f29307a1826a64a0d26028dcJohn Grossman}
48261c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
48271c345196edc61694f29307a1826a64a0d26028dcJohn Grossmanvoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
48284ff14bae91075eb274eb1c2975982358946e7e63John Grossman    BaseState::onOutputBufferDrained(msg);
48294ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48304ff14bae91075eb274eb1c2975982358946e7e63John Grossman    changeStateIfWeOwnAllBuffers();
48314ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
48324ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48334ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
48344ff14bae91075eb274eb1c2975982358946e7e63John Grossman    BaseState::onInputBufferFilled(msg);
48354ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48364ff14bae91075eb274eb1c2975982358946e7e63John Grossman    changeStateIfWeOwnAllBuffers();
48374ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
48384ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48391c345196edc61694f29307a1826a64a0d26028dcJohn Grossmanvoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
48401c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    if (mFlushComplete[kPortIndexInput]
48414ff14bae91075eb274eb1c2975982358946e7e63John Grossman            && mFlushComplete[kPortIndexOutput]
48424ff14bae91075eb274eb1c2975982358946e7e63John Grossman            && mCodec->allYourBuffersAreBelongToUs()) {
48434ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // We now own all buffers except possibly those still queued with
48444ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // the native window for rendering. Let's get those back as well.
48454ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
48464ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48474ff14bae91075eb274eb1c2975982358946e7e63John Grossman        sp<AMessage> notify = mCodec->mNotify->dup();
48484ff14bae91075eb274eb1c2975982358946e7e63John Grossman        notify->setInt32("what", ACodec::kWhatFlushCompleted);
48491c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        notify->post();
48501c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
48511c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        mCodec->mPortEOS[kPortIndexInput] =
48524ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mCodec->mPortEOS[kPortIndexOutput] = false;
48534ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48544ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mCodec->mInputEOSResult = OK;
48554ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48564ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (mCodec->mSkipCutBuffer != NULL) {
48574ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mCodec->mSkipCutBuffer->clear();
48584ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
48594ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48604ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mCodec->changeState(mCodec->mExecutingState);
48614ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
48624ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
48634ff14bae91075eb274eb1c2975982358946e7e63John Grossman
48644ff14bae91075eb274eb1c2975982358946e7e63John Grossman}  // namespace android
48654ff14bae91075eb274eb1c2975982358946e7e63John Grossman