ACodec.cpp revision 1ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
4090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar#include <media/stagefright/MediaCodec.h>
41afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
45b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
52777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar#include "include/DataConverter.h"
5673dd808754c641fe798273d356ee38368715fa7bLajos Molnar#include "omx/OMXUtils.h"
57496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
58f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnarenum {
616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar};
636e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
99251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
100251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
101251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
102251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
103251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
105251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
10626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
10726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
10826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
109984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    virtual ~MessageList() {
110984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    }
11126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
11226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
11326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
11426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
11526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
11626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
11726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
1185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnarstatic sp<DataConverter> getCopyConverter() {
1195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
1205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static sp<DataConverter> sCopyConverter;        // zero-inited
1215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
1225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return sCopyConverter;
1235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar}
1245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
13326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
134984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        if (messages.empty()) {
135984a54322f7c70bc75e862d91bdd975814872affLajos Molnar            return;
136984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        }
137984a54322f7c70bc75e862d91bdd975814872affLajos Molnar
138984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        sp<AMessage> notify = mNotify->dup();
13926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        bool first = true;
14026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
14126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
14226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
14326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
14426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            if (first) {
14526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                notify->setInt32("node", omx_msg.node);
146984a54322f7c70bc75e862d91bdd975814872affLajos Molnar                first = false;
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
15026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
15126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
15226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
15326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
15426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
15526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
15626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
15726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
15826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
16126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
16326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
16426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
16526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
16826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
17126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
17326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
17426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
17626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
17726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
17926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
18026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
18126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
18226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
18326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
18526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
18626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
18990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
19090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
19190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
19290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
19390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
19490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
19590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
19690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
19726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
19826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
19926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
20026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
20126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
20226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
20326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
20426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
219090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
24226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
24626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
24726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
24826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
24926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
25026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
25115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
25715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
25815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
26190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
269ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
270090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit DeathNotifier(const sp<AMessage> &notify)
271ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
272ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
273ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
274ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
275ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
276ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
277ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
278ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
279ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
280ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
281ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
282ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
283ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
284ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
285ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
286ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
288090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit UninitializedState(ACodec *codec);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
299ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
306090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedState(ACodec *codec);
307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3178f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
318c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
321d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
322d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
329090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedToIdleState(ACodec *codec);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
345090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToExecutingState(ACodec *codec);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
359090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingState(ACodec *codec);
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
362054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
370349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
371349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
37890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
381349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
382349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
389090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit OutputPortSettingsChangedState(ACodec *codec);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
39790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
406090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingToIdleState(ACodec *codec);
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
428090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToLoadedState(ACodec *codec);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
443090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit FlushingState(ACodec *codec);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
46515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
46615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
46715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
46815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
46915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
47015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
47115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
47215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
47315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
47415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
47515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
47615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
47715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
47815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
47915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
48015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
48315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
48415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
48515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
48615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
48915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
49015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
49115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
49215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
49315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
49415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
49515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
496f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
497b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    : mSampleRate(0),
498b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen      mQuirks(0),
499609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
501e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
502fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
5038db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
504c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
505346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5069806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
50754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
508f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang      mIsLegacyVP9Decoder(false),
5099806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5109806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
511e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
513054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
514054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
515054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mInputMetadataType(kMetadataBufferTypeInvalid),
516054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mOutputMetadataType(kMetadataBufferTypeInvalid),
517011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
518054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
52094ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
52237b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
5232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
524609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
525ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
5268338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
527db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
528db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0) {
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
543dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
545fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
546fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
550f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
553f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5641d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
565a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
566a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
567a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
568a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5695778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5755778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5771d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
5861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
5871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
5891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
5901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
5921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
5931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
5951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
5967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5988f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
599d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
6008f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
601d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
602d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
603d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
604d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6095778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
613f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6147a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6151d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
618f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6231d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
62630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
62730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
62930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
632496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
634496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
635496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6374dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6384dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
641054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
643054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
644054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6464dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6474dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
658e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
677e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
678e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);
6791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
683f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
684e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
685e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
686e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
687e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
688e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
689e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
6921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
6931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
6941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
6991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
7021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
7031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
7041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
7051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
719dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
720dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
721dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
727054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
728011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
730598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa            ALOGV("skipping buffer");
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
745054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
74715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
75115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
75215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
7621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
7631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
765484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
766484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
767484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
768484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
769484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
771e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
783054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()) {
784054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
797054219874873b41f1c815552987c10465c34ba2bLajos Molnar            MetadataBufferType type =
798054219874873b41f1c815552987c10465c34ba2bLajos Molnar                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
7995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
8003e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            if (type == kMetadataBufferTypeANWBuffer) {
801054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
8023e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            } else if (type == kMetadataBufferTypeNativeHandleSource) {
8033e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                bufSize = sizeof(VideoNativeHandleMetadata);
804054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
805054219874873b41f1c815552987c10465c34ba2bLajos Molnar
806054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // If using gralloc or native source input metadata buffers, allocate largest
807054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // metadata size as we prefer to generate native source metadata, but component
8085fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // may require gralloc source. For camera source, allocate at least enough
8095fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // size for native metadata buffers.
8105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t allottedSize = bufSize;
8113e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            if (portIndex == kPortIndexInput && type == kMetadataBufferTypeANWBuffer) {
812054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
8135fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
8145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                bufSize = max(bufSize, sizeof(VideoNativeMetadata));
8155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
8165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
827054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
828054219874873b41f1c815552987c10465c34ba2bLajos Molnar
82928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
83028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            ALOGV("[%s] Allocating %u buffers of size %zu/%zu (from %u using %s) on %s port",
8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
833054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
8375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
83828edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
83928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
84028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
84128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
84228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
84328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
8445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
8455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
84634e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
84734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
84834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
84928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
854054219874873b41f1c815552987c10465c34ba2bLajos Molnar                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
8555581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
856777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
857777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
860ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
86115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
86290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
863a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                info.mNativeHandle = NULL;
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
865afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
866afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
867b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        ? kRequiresAllocateBufferOnInputPorts
868b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        : kRequiresAllocateBufferOnOutputPorts;
8691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
870e33d922fd86699c664a15f09e6d8b2e422736a40Lajos Molnar                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
871ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
872ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
873a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
8741b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    sp<NativeHandle> native_handle;
875a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    err = mOMX->allocateSecureBuffer(
876054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, bufSize, &info.mBufferID,
877a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
878a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
879a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY: this representation is unorthodox, but ACodec requires
880a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // an ABuffer with a proper size to validate range offsets and lengths.
881a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // Since mData is never referenced for secure input, it is used to store
882a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // either the pointer to the secure buffer, or the opaque handle as on
883a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // some devices ptr is actually an opaque handle, not a pointer.
884a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
885a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY2: use native handle as the base of the ABuffer if received one,
886a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // because Widevine source only receives these base addresses.
8871b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    const native_handle_t *native_handle_ptr =
8881b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                        native_handle == NULL ? NULL : native_handle->handle();
8891b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    info.mData = new ABuffer(
8901b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                            ptr != NULL ? ptr : (void *)native_handle_ptr, bufSize);
8911b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    info.mNativeHandle = native_handle;
8925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = info.mData;
893ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
8945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
895054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
897054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
898ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
899ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
900ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
9015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = new ABuffer(mem->pointer(), bufSize);
9025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecRef = mem;
9035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
904054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (type == kMetadataBufferTypeANWBuffer) {
905054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
906054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
9075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
9085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // if we require conversion, allocate conversion buffer for client use;
9095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // otherwise, reuse codec buffer
9105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (mConverter[portIndex] != NULL) {
9115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        CHECK_GT(conversionBufferSize, (size_t)0);
9125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mem = mDealer[portIndex]->allocate(conversionBufferSize);
9135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        if (mem == NULL|| mem->pointer() == NULL) {
9145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            return NO_MEMORY;
9155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        }
9165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = new ABuffer(mem->pointer(), conversionBufferSize);
9175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = mem;
9185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else {
9195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = info.mCodecData;
9205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = info.mCodecRef;
9215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
9251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
9261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
934d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
937eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
938eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
939eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
941eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
942a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        desc->addBuffer(info.mBufferID, info.mData, info.mNativeHandle, info.mMemRef);
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
945eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
951e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
952e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {
9531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
9581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
9611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
9651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
9661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
9671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
9681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
9691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
9701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
9721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
9741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
9751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
977f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
978e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
979b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
980fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
981fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
982fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
9831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
9841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
9851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
9861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
9871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
9881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
9891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
9901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
9911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
9921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
9941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
9951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
9961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
10011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
10021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
1004e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);
10051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
1007e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
10081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
10091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1011ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
1012ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
1013ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
1014ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1015ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1016ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
1017ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
1018ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1019ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1020ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
1021ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
1022ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
1023ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
1024ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1025ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1026054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
1027258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
1028258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1029054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
1030258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1031258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
103229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1033258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
1034258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
1035258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1036258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1037e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
1038e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
10391faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
10401faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1041e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1042e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
1043e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
1044e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1045e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
1046e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
1047e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
10481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
10491faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1050e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
1051e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1052258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1053258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
1054258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1055258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1056e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1057e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1058e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1059e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1060e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1061609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1062e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1063e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1064e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1065258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1066258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1067258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1068258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
107329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1079054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1080054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1081054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1082054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1083054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1084054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1085054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1089e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1091054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
10923298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
10933298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
10943298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10953298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1096609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1098054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
11028ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
110315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
110415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
110629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
111174006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
111274006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
111315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
111415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
111590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
11175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
111874006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
111974006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
112074006804065941841883c4b46ee785070164023fJamie Gennis
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1125609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
112674006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
113174006804065941841883c4b46ee785070164023fJamie Gennis
1132609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
114474006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1146054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1147054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1148054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
11533175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
11543175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
11553175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
11563175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
11573175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
11583fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1161054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
11623298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
11633298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
11643298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
11653298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1169054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1173054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1174054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1175e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1176054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1177e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1178e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1179e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1180054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1181054219874873b41f1c815552987c10465c34ba2bLajos Molnar            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
118228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar    size_t totalSize = bufferCount * align(bufSize, MemoryDealer::getAllocationAlignment());
1183e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1184e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1185e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
1186e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1187e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1188e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
118915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
119090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1191e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1192e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1193e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1194054219874873b41f1c815552987c10465c34ba2bLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
11955581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
1196777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
1197777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1198054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1199054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1200054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1201e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
12025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mMemRef = mem;
12035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
12045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecRef = mem;
1205e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1206e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
1207e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        err = mOMX->useBuffer(
1208cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1209e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1210e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1211e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1212e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1213e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1214e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1215011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1216e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1217011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1218011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1219011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1220011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1221011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1222011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1223011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1224011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1225011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1226e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1227e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1228011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
122915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd;
123015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1231011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1232011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1233011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1234011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1235011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1236011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1237e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            mOMX->updateGraphicBufferInMeta(
1238e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1239e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
124015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1241e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1242011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1243011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1244011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1245011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
12463175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (info->mStatus == BufferInfo::OWNED_BY_US) {
12473175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                status_t error = cancelBufferToNativeWindow(info);
12483175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                if (err == OK) {
12493175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                    err = error;
12503175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                }
1251011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1252011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1253011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1254011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1255011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1256011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1257011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1258054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1262054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1263054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1264054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1265054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1266054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1267054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
12680806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1269054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
12700806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1271054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1272609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1273054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1274054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1275054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
127615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
127715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
127815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1279777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1280777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1281777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1282054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1283777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1284054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1285054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
128615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
128715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
128815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
128915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
129015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
129115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
129215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
129315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
129415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
129515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
12960806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
12970806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
12980806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
12990806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
13000806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
13010806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
13020806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
13030806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
13040806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
13050806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
13060806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13070806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13080806340688c937e7b78c2d89db3809274130df4eLajos Molnar
13090806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
13100806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
13110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
13120806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
13130806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
13140806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
13150806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
13160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
13170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
13180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
13190806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13200806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13210806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1325609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
133015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
133115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13333fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
13343fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
13350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13383fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
134190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
134290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
134390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
134490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
134590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
134690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
134790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
134890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
134990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
135090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
135190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
135290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
135390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
135490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
135590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
135690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
135790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
135890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
135990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = mNotify->dup();
136090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
136190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
136290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
136390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
136490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
136590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
136690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1367604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1368604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1369604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1370604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1371604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1372604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
137390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
137490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
137590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
137690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
137790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->post();
137890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
137990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
138090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1381f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
13828ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1383054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1384ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1385ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1386ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1387ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1388ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1389ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1390ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1391346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1392346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1393346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1394346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1395346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
139615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1397dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
139815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
139915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
140015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1401dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1402dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1404dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1405b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1406b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1407dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1408dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1409dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
141090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1411dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1412dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1413dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1414dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1415dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1416dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1417dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1418dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1419dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1420dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1421dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1422dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
142390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1424dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1425dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
142615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
142790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1428dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1429dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1430dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1432dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1433dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1434dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1435dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1436dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1437054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1438dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1439dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1440dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1441dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1442dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1443dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1445dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1446054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1447dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1448dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1449b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1450b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1451dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1452dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1453054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1454054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1455054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1456054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1457054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1458054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1459054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1460054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1461054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14620806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
14630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
14640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
14650806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1466054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1467054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14680806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
14690806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
14700806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
147115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
147290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
147390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1474d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
14750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    mOMX->updateGraphicBufferInMeta(
14760806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
14770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mBufferID);
1478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1479054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1480054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata *grallocMeta =
1481054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1482054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1483054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1484054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14857c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)grallocMeta->pHandle,
1486054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1487054219874873b41f1c815552987c10465c34ba2bLajos Molnar    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1488054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata *nativeMeta =
1489054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1490054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1491054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1492054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14937c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)nativeMeta->pBuffer,
1494054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1495054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
14980806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1502777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1503938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1504938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1505777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1506777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1507777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1508777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1513777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1516349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1517777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1518938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1519938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15232ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
15242ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
15252ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
15262ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1527777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1528777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1529777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1530777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1534777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
15390806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
154215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    MetadataBufferType type =
154315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
154415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
154515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
154615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
154715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
154815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
154915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
155015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
155115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
155215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
15530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
15540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
15550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
15560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
15570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
15580806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
15610806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
15620806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
15630806340688c937e7b78c2d89db3809274130df4eLajos Molnar
15640806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
15650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
15660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
15670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
157015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
157115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
157215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
157315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1574604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1575604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1576604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1577604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
157890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1579777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1581777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1584f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
15850806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1597777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
16031ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime);
16045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
16055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
16065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
16071ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    status_t err = SetComponentRole(mOMX, mNode, role);
16085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
16095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
16105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
16115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
16125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
16135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
16145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1622b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1623b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1624b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1625e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1628054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mInputMetadataType = kMetadataBufferTypeInvalid;
1629054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mOutputMetadataType = kMetadataBufferTypeInvalid;
16308db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
16382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
16392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
16402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
164496bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    // propagate bitrate to the output so that the muxer has it
164596bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    if (encoder && msg->findInt32("bitrate", &bitRate)) {
164696bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
164796bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
164896bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("bitrate", bitRate);
164996bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("max-bitrate", bitRate);
165096bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    }
165196bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar
1652d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1653d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
16543e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
16553e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && storeMeta != kMetadataBufferTypeInvalid) {
16563e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mInputMetadataType = (MetadataBufferType)storeMeta;
16573e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        err = mOMX->storeMetaDataInBuffers(
16583e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1660054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1661308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1663054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
16643e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        } else if (storeMeta == kMetadataBufferTypeANWBuffer
16653e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                && mInputMetadataType == kMetadataBufferTypeGrallocSource) {
16663e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            // IOMX translates ANWBuffers to gralloc source already.
16673e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mInputMetadataType = (MetadataBufferType)storeMeta;
1668054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1669c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1670c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1671c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mOMX->getParameter(
1672c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1673c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1674c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1675c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1676c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1677054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1679308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
16803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
16813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
16823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
16833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
16843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
16853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
16863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
16873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
16883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
16903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
16913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
16923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
16933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
16953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
16963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
16973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
16993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
17003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
17013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
17033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
17053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1706308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1707308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1708308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1709308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
17108db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1711308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1712308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
17133e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
1714308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1715308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
17163e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mOutputMetadataType = kMetadataBufferTypeNativeHandleSource;
1717054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1718308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1719308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1720308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1721308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1722a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1723a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1724a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1725a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1726a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1727a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
172894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
172994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
17302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
17312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
17322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
173337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
173437b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
173537b2b389139ed638831e49708c947863eef631efRonghua Wu        }
173637b2b389139ed638831e49708c947863eef631efRonghua Wu
17372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
17382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
173994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
174072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
174172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
174272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
174372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
174472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
174572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1746308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1747308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
17483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
17500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
17513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1752b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1753011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1754e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1755e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
17561713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
17571713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
17581713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
17591713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
17601713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
17611713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
17621713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
17631713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
17641713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
17651713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1766a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1767a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        if (mFlags & kFlagIsSecure) {
1768a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            // use native_handles for secure input buffers
1769a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = mOMX->enableNativeBuffers(
1770a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    mNode, kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
1771a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            ALOGI_IF(err != OK, "falling back to non-native_handles");
1772a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = OK; // ignore error for now
1773a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
17753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
17761de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
17771de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
17785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17796597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
17806597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
17816597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
17826597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
17836597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
17846597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
17856597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
17866597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
17876597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
17886597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
17896597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
17906597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
17916597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
17926597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
17936597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
17946597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
17956597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
17966597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
17975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
17985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
17995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
18005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1801ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
18025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
180397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
180497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
18055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
18065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
18085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
180997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
18105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
18115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1812fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1813fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1814d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1815d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1816d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1817d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1818d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1819d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1820d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1821d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1822d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
18233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
18243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1825d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1826d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1827d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1828d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1829d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1830d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
18315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1832ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1833ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1834ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
18353fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
18363fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
18373fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
18383fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
18393fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
18403fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
18413fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
18423fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
18433fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
18445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
18453e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mOutputMetadataType = kMetadataBufferTypeANWBuffer;
18465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
1847054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
18485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
18495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1850fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1851e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
18525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
18535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
18545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
18555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
18575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
18585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
18595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
18605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
18615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
18635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
18645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
18655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
18665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
18675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
18685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
18695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
18705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
18715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
18725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
18735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
18755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
18765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
18775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
18785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
18795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
18805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
18825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
18835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
18845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
18855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
18865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
18875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
18895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
18905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
18915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
18925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
18945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
18955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
18965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
18975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
18985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
1899054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
1900011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1901011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1902011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
19035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1904fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
19050167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
19065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
19075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
19085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
19095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
19105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
19110167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1912e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1913e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1914e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1915e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1916e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1917e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1918e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1919054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1920054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
19215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
19225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
19235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
19245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
1925308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
19263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
19273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
19283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
19293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
19303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
19313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
1934b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1936b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
19403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
19413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
19441de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
19453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19473a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
19483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1949777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1950777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1951777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1952777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
19533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
19553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
19563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
19573a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
19583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1959777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1960777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1961777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1962777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
19643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1965777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1966777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1967777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1968777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
19703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
19711ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                if (!IsFlexibleColorFormat(
19723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
19733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
19743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
19753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
19763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
19773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
1978e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
19793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
19803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
1981054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (storingMetadataInDecodedBuffers()) {
1982054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        err = mOMX->storeMetaDataInBuffers(
1983054219874873b41f1c815552987c10465c34ba2bLajos Molnar                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
1984054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
19853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
19863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
19873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
19883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
1990a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                        err = mOMX->enableNativeBuffers(
1991a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                                mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
19923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
19943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
19953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
19963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
1997b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
1998b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
19993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
20013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
20023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
20053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
20063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
200742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
200842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
200942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
201042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
201142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
201242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
201342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
201442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
201542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
201642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
201742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
201842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
201942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2026aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
2027b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
20288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
20292965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
20308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
2031ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
2032ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
2033ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
2034aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
2035aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
2036aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
2037b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2038b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
2039b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
2040ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20418045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
20428045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
20438045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20442965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
20452965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
20462965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
20472965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
20488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
20498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
20518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
20538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
20558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
20578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
20598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
20618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
20638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
20658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
20678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2069ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
20704471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
20712965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
20722965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2074729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2076729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2078729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2079729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2080729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2081729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2082729de186450f78c099637e1fce743fe531862c52Andreas Huber
2083729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
208717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
208817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
208917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
209017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
209117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2094ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
20952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
20962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
20972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
20982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
20992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
21002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
21012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2102516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2103cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2104cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2105516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2106cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
21072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2108516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2109516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2110516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
21122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2113516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2114516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2115516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
21172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
21182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2119516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2120516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
21212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2122ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2123ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2124ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2125ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2126ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2127ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2128ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
21295b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2130ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
213197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
213297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
213397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
213497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
213597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
213697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
213797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
213897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
213997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
21408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
21418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
21428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
21438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
21448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
21458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
21468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
21478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
21488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2150729de186450f78c099637e1fce743fe531862c52Andreas Huber
21514471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
21524471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
21534471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
21544471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
21558b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
21568b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
21578b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
21589806555d3930be43e11106281dee354820ac1c88Andreas Huber
21598b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
21608b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
21618b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
21628b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
21639806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
21649806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
21659806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
21669806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
21679806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
21689806555d3930be43e11106281dee354820ac1c88Andreas Huber
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21768b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
21778b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
21788b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
21798b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21808b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2181ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2182ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2183ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2184ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2185ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2186ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2187ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2188ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2189ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2190ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2191697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
21924e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2193b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // trigger a kWhatOutputFormatChanged msg on first buffer
2194b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
21954e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2196777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2197777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2198777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2199777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2200777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2201777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2202777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2203777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
22045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // create data converters if needed
22065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!video && err == OK) {
22075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
22085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (encoder) {
22095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
22115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexInput] != NULL) {
22125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
22135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        } else {
22155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
22175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexOutput] != NULL) {
22185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
22195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
22215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
22225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22268b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
22278b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
22288b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
22298b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22308b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
22318b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
22328b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
22338b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
22348b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
22358b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
22368b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
22378b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
22388b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22398b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
22408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
22418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2242ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2243ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2244ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2245ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2246ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2247ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2248ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2249ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2250ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2251ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2252ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2253ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2254ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2255ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2256ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2257ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2258ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2259ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2260ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2261ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
2262ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2263ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2264ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2265ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2266ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2267ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2268ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2269ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2270870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2271870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2272870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2273870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2274870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    status_t err = mOMX->getConfig(
2275870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2276870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2277870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2278870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2279870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2280870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2281870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2282870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2283870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2284870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2285870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2286870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->getParameter(
2287870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2288870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2289870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2290870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2291870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2292870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2293870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2294870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2295870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2296870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2297870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2298870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2299870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->getParameter(
2300870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2301870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2302870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2303870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2304870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2305870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2306870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2307870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2308870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2309870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2310870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2311870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2312870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2313870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2314870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2315870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2316870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2317870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2318870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    status_t err = mOMX->setConfig(
2319870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2320870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2321870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2322870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2323870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2324870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2325870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2326870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2327870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2328870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2329870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2330870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2331870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2332870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2333870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2334870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2335870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2336870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2337870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2338870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2339870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2340870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2341870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2342870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2343870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2344870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2345870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2346870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = mOMX->getParameter(
2347870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2348870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2349870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2350870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2351870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2352870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2353870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2354870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2355870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2356870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2357870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->setParameter(mNode, OMX_IndexParamVideoIntraRefresh,
2358870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                             &refreshParams, sizeof(refreshParams));
2359870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2360870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2361870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2362870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2363870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2364870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2365870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2398777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2399777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2400777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2401777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
24126e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24256e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
24266e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
24276e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
24286e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
24296e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
24306e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
24316e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2439aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
24408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
24412965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
24422965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2443ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2444ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2445ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2446ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2507aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2509b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2510b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2511b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2512b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2513b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2514b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2515b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2516b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2517b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2518b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2519b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2520b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2521b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2522b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2523b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2524b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2525b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2526b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2527b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2528b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2529b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2530b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2531b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2532b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2533b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2534b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2559ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2560ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2561ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2562ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2566dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
25678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
25688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
25698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
25708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
25718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
25728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
25732965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
25748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
25758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
25768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
25778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
25788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
25798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
25808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
25818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
25828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
2583b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    mSampleRate = sampleRate;
25848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
258897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
258997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
259097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
259197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
259297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
259397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
259497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
259597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
259697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
259797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
259897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
259997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
260097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
260197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
260297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
260397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
260497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
260597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
260697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
260797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
260897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
260997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
261097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
261197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
261297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
261397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
261497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
261597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
261697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
261797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
261897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
261997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
262097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
262197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
262297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
262397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
262497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
26258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
26268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
26278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
26288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
26298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
26318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
26328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
26358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
26368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
26378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
26408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
26418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
26428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
26448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
26458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
26468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
26478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
26488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
26508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
26518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
26548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
26558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
26578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
26588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
26598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
26608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
26618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
26628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2709729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2710729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2712729de186450f78c099637e1fce743fe531862c52Andreas Huber
2713729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2714729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2715729de186450f78c099637e1fce743fe531862c52Andreas Huber
2716729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2717729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2718729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2719729de186450f78c099637e1fce743fe531862c52Andreas Huber
2720729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2725729de186450f78c099637e1fce743fe531862c52Andreas Huber
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2729729de186450f78c099637e1fce743fe531862c52Andreas Huber
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2734729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2735729de186450f78c099637e1fce743fe531862c52Andreas Huber
273617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2737777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2738777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2739777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2741729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
274217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2743729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2744729de186450f78c099637e1fce743fe531862c52Andreas Huber
27452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
27462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
27472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
27492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
27502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
27512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
27522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
27542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
27552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
27562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
27572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
27582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
27592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
27602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
27612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
27622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
27632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
27642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
27652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
27662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
27682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
27692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
27702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
27712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
27722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2773729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
27745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
2775729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2776729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2777729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2778729de186450f78c099637e1fce743fe531862c52Andreas Huber
2779729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2780729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2781729de186450f78c099637e1fce743fe531862c52Andreas Huber
2782729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2783729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2784729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2785729de186450f78c099637e1fce743fe531862c52Andreas Huber
2786729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2787729de186450f78c099637e1fce743fe531862c52Andreas Huber
2788729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2789729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2790729de186450f78c099637e1fce743fe531862c52Andreas Huber
2791729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2792729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2793729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2794729de186450f78c099637e1fce743fe531862c52Andreas Huber
2795729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2796729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2797729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2798729de186450f78c099637e1fce743fe531862c52Andreas Huber
2799729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2800729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2801729de186450f78c099637e1fce743fe531862c52Andreas Huber
2802729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2803729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2804729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2805729de186450f78c099637e1fce743fe531862c52Andreas Huber
2806729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
28075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    switch (encoding) {
28085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm8bit:
28095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataUnsigned;
28105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 8;
28115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcmFloat:
28135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataFloat;
28145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 32;
28155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm16bit:
28175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataSigned;
28185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 16;
28195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        default:
28215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            return BAD_VALUE;
28225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
2823729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2824729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2825729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2826729de186450f78c099637e1fce743fe531862c52Andreas Huber
2827c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2828c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2829729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2830729de186450f78c099637e1fce743fe531862c52Andreas Huber
28315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    err = mOMX->setParameter(
2832729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
28335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // if we could not set up raw format to non-16-bit, try with 16-bit
28345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // NOTE: we will also verify this via readback, in case codec ignores these fields
28355b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (err != OK && encoding != kAudioEncodingPcm16bit) {
28365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.eNumData = OMX_NumericalDataSigned;
28375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.nBitPerSample = 16;
28385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        err = mOMX->setParameter(
28395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
28405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
28415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return err;
2842729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2843729de186450f78c099637e1fce743fe531862c52Andreas Huber
28445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
284597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
28465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
28475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
28485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
28495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
28505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
28515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
28525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
28535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
28545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
28555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
28565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
28575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
28585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
28595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
28605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
28615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
28625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
28635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
28645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
28680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
28690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28766e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2886229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2887229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
28880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
28891ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
28900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
28910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2892229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2893229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2894229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2895229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2896229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29216e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
29226e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
29236e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
29246e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
29256e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
29266e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
29410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
29420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
29430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
29440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
29450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
29460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
29470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
29480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
29490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
29500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
29510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
29520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
29530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
29540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
29550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
29600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
29610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
29640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
29650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
29660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
29670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
29680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
29690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
29700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
29710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
29720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
29730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
29740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
29750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
29770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
29780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
29800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
29810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
29830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
29840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
29850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
29860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
29870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
29880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
29890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
29910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
29920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
29931ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
29940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
29950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
29960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
29970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
29980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
3006e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
3007e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3008e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
3009e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
30102472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3011e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3012e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3013e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
301494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
301594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3016a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3017e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
3018e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3021e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3022e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3023e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3024e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3025e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3026e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3027e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3030e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3031e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3032e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3033e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3034e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3035e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3036e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3037e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3038e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3039e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3040e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3042e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3043e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3044e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3045e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3046e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
30495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
30528338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3053b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
305489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
305589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
305689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
305789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
305889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
305989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3067f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    if (compressionFormat == OMX_VIDEO_CodingVP9) {
3068f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3069f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        InitOMXParams(&params);
3070f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nPortIndex = kPortIndexInput;
3071f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        // Check if VP9 decoder advertises supported profiles.
3072f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nProfileIndex = 0;
3073f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        status_t err = mOMX->getParameter(
3074f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                mNode,
3075f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                OMX_IndexParamVideoProfileLevelQuerySupported,
3076f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                &params,
3077f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                sizeof(params));
3078f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        mIsLegacyVP9Decoder = err != OK;
3079f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    }
3080f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
308989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
309089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
309189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
309289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
30930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
309489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
309589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
309689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
30970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
309889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
309989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
31000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
310189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
310878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
310978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
311078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
311178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
311278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
311378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
311478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
311578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
311778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3130b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3131b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3132b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
31338338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
31348338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3135db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3136db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3137db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return err;
3138db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3139db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
31405e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
3141db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
3142db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        err = OK;
3143db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3144b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3145b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3146b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3147b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3148b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = mOMX->getExtensionIndex(
3149b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mNode, "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3150b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3151b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3152b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3153b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3154b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
31558338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3156b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3157b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3158b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3159b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mOMX->setConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
3160b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3161b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3162b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3163b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3164b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3165b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3166b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3167b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3168b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3169b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3170b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3171b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3172b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3173b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3174db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting color aspects failed even though codec advertises support",
3175b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
31768338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
31778338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
31788338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3179b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3180b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3181b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
31828338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
31838338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3184b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
31858338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3186b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3187b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3188b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3189b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3190b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3191b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3192b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
31938338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
31948338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3195b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
31968338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3197b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3198b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3199b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3200b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3201b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3202b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3203b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3204b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mOMX->getConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
32058338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3206b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3207b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3208b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3209b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3210b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3211b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3212b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3213b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3214b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3215b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3216b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3217b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3218b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3219b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3220b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3221b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3222b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
32238338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3224b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3225b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3226b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3227b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3228b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3229b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3230b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3231b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
32328338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3233b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3234b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3235b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3236b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3237b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3238b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3239b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3240b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3241b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3242b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3243b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3244b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3245b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3246b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3247b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3248b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3249b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3250b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3251b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
32528338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3253b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3254b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3255b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3256b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3257b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3258b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3259b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3260b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3261b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3262b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3263b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3264b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3265b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3266b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3267b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3268b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3269b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3271b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3272b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3273b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3274b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3275b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3276b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3277b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3278b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
32798338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3280b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
32818338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3282b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3283b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3284b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3285b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3286b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
32908338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
32918338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
32938338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
32948338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3297b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3298b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3299b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3300b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3301b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3302b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3303b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3304b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3305b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3306b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3307b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3308b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3309b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3310b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3311b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3312b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3313b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3314b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3315b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3316b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3317b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3318b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3319b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3320b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3321b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3322b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
33238338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33248338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3325b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3326b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3328b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3329b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3330b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3331b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3333b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3334b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3335b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3336b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3337b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3338b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3339b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
33405e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::setHDRStaticInfoForVideoCodec(
33415e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
33425e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
33435e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
33445e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    DescribeHDRStaticInfoParams params;
33455e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    InitOMXParams(&params);
33465e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
33475e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
33485e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    HDRStaticInfo *info = &params.sInfo;
33495e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (getHDRStaticInfoFromFormat(configFormat, info)) {
33505e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
33515e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
33525e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
33535e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    (void)initDescribeHDRStaticInfoIndex();
33545e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
33555e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    // communicate HDR static Info to codec
33565e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    return setHDRStaticInfo(params);
33575e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang}
33585e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
3359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3360b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3361b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
33628338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
33638338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3364b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
33658338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
33668338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3367b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3368b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3369b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
33728338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
33758338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3377b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3378b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3379b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3380b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3381b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3382b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3385b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
33868338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33878338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3388b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3389b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3390b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3391b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3392b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
33948338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3398b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
34038338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3405b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3408b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34115e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
34125e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3413db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    DescribeHDRStaticInfoParams params;
3414db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    InitOMXParams(&params);
34155e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
3416db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3417db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = getHDRStaticInfo(params);
3418db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == OK) {
3419db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        // we only set decodec output HDRStaticInfo if codec supports them
3420db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, format);
3421db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3422db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3423db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3424db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3425db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::initDescribeHDRStaticInfoIndex() {
3426db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = mOMX->getExtensionIndex(
3427db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mNode, "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
3428db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3429db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
3430db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3431db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3432db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3433db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3434db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
3435db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3436db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3437db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        err = mOMX->setConfig(mNode, mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3438db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3439db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3440db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    const HDRStaticInfo *info = &params.sInfo;
3441db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
3442db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
3443db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str(),
3444db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
3445db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
3446db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
3447db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
3448db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3449db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3450db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting HDRStaticInfo failed even though codec advertises support",
3451db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3452db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3453db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3454db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3455db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
3456db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3457db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3458db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        err = mOMX->getConfig(mNode, mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3459db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3460db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3461db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3462db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] getting HDRStaticInfo failed even though codec advertises support",
3463db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3464db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3465db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3466db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
34678338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3468b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3469b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
34705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
34715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
34725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
34735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
34765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
34795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
34805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
34835778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
34845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
34895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
34915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
34925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
34945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
34965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
34985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
34995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
35055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
35065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
35075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
35085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
35095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
35125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
35135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
35155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
35165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
35175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
35225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
35235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
35275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
35295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
35372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
35385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3542a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3543a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3544a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3545a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3546a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
35545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
35595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
35625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
35685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
35695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
35725778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
35735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
35805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
35875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
35885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
35905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
35945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
35985778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
35995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3603870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3604870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3605870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3606870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3607870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3608870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3609870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3610870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3611870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3612870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3613870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3627c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3628c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3629c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3630c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
363189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
363289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
363389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
363489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
363589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
36418338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3643b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
36448338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
36458338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
36468338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
36478338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
36485e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err != OK) {
36495e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        return err;
36505e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
36515e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
36525e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
36535e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
36545e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
36555e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        err = OK;
36565e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
36575e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
3658d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3659d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3660d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
36615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
36635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
36660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
36670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
36680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
36690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
36710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
36730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
36740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
36750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
36760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
36790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
36800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
36820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
36830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
36840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
36850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
36880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
36900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
36910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
36940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
36950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
36970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
36980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
36990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
37000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
37010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
37095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
371296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
371396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
371496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
371596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
371696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
371796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
371896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
371996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
372096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
372896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
372996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
37325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
37335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
37345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
37355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
37375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
37405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
37515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
37535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
37555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
37595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
37655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
37665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
37675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
37685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
37705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
37735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
37775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
37875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
37885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
379396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
37945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
38005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
38075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
380996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
381096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
38115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
38125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
38135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
38145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
38185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
38215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
38225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
38235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
38255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
38265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
38415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
38425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
38435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
38445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
38485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
38505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
38515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
38555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
38635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
38645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
386996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
38765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3878a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3879a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3880a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3881a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3882a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3883a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3884a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3885a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3886a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3887a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3888a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3889a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3890a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3891a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3892a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3893a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3894a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3895a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3896a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3897a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3898a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3899a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3900a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3901a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3902a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3903a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3904a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3905a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3906a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3907a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3908a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3909a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3910a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3911a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3912a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3913a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3914a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3915a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3916a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3917a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3918a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3919a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3920a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3921a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3922a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3923a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3924a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3925a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3926a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3927a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3928a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3929a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
39315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
39325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
39335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
39345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
39355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
393796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
393896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
39415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
39425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
39465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
39490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
39500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
39510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
39520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
39530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
39540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
39550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
39560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
39570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
39580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
39745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
39765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
39775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
39815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
39875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
3988e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else {
3989e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        // Use baseline profile for AVC recording if profile is not specified.
39908eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
39918eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    }
39928eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang
3993e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
3994e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            asString(h264type.eProfile), asString(h264type.eLevel));
3995e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang
39965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
39975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
39985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
39995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
40005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
40015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
40025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
40035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
40045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
40065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
40075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
40085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
40095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
40105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
40115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
40125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
4013e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
4014e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
4015e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nSliceHeaderSpacing = 0;
4016e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
4017e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefFrames = 2;
4018e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nBFrames = 1;
4019e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
4020e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nAllowedPictureTypes =
4021e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
4022e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
4023e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
4024e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
4025e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
4026e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bconstIpred = OMX_TRUE;
4027e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
4028e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
4029e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nCabacInitIdc = 1;
40305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
40335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
40345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
40375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
40385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
40395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
40405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
40415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
40425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
40465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
405196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
40525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4054c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
4055c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
4056c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
4057c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
4058c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
4059c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4060c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4061c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
4062c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4063c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
4064c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
4065c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
4066c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
4067c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4068c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4069c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
4070c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4071c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4072c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4073c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4074c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4075c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4076c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4077c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
4078c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4079c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4080c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4081c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4082c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4083c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4084c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4085c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4086c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4087c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4088c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4089c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4090c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
4091c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4092c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4093c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4094c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4095c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4096c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4097c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
40989aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
40999aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
4100c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4101c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
4102c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4103c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4104c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4105c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4106c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4107c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
4108c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4109c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
411089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
411189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
41124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
41134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
41144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
41154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
41164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
41174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
41184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
41194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
41204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
41214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
41224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
412389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
412489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
412589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
41264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
412789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
412889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
412989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
41304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
41314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
41324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
41334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
41344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
41354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
41374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
41384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
41404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
41414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
41424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
41434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
41444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
41454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
41464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
41474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
41484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
41494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
41504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
41514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
41524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
41544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
41564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
41574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
41584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
41594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
41604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
41614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
41634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
41644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
41654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
41674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
41684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
41694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
41704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
41714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
41724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
41734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
41754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
41764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
41774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
41804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
41814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
41824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
41834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
41844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
41864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
418789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
418889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
418989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
41915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
41925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
41945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
41955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41966e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
41976e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
41995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
42005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
42015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
42025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
42035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
42055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
42065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
42095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
42105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
42125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
42135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42146e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
42156e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
42166e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
42176e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
42186e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
42196e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
42205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42216e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
42225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
422496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
422596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
42265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
42275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
42285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
42295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
42315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
42325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
42335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
42365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
423896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
42395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
42405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
42425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
42435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
42445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
42475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
42485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
42495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
42505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
42525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
42535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
42545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
42575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
42605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
42615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
42625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
42635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
42645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
42665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
42675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
42685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
427278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
427378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4282777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4283777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4284777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4294777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4295777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4296777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4297777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
430578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
430678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
430778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
4318a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4321a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4326d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4327d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4328d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4329d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4330d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4331d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4332d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4333d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4334d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4335d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4336d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4337d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4338d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
43397e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
43407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
43417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
43437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
43447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43457e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
43467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
43477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
43487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
43517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
43527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43537e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
43547e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
43557e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
43567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4358e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
43597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4360c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4361054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4362054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4363c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
43647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
43667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4374609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4403e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4404777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
440531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
440631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4407e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
440831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4409777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4410777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4411777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4412777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
441331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4414777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4415777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4416777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4417777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
441831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
441931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
442031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
442131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
442231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4423e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4424e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4425e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4426e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4427e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4428e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4429e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4430e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4431e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4432e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
44330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
443473dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
44350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
44360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
44370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
44380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
44390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
44400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
44410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
44420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
44431ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                        if (DescribeColorFormat(mOMX, mNode, describeParams)) {
44440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
44450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
44460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
44470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
44480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
44495a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
445073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
445173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
445273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
445373dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
445473dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
445573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
445673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
44570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
445803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
445903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4460b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4461b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4462b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4463b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4464b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4465b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4466b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4467b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4468b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mOMX->getConfig(
4469b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    mNode,
4470b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4471b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4472b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4473b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4474b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4475b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4476b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4477b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4478b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
447991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4480b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4481b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4482b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4483b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4484b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4485b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4486b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4487b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4488b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4489b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
449031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4491b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4492b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4493b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4494b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4495b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4496b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4497b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4498b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4501b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4502b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4503b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4504b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4505b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4506b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4507b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
45085e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
4509b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
45115e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        if (mConfigFormat->contains("hdr-static-info")) {
45125e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                            (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
45135e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        }
4514777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4516e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4517e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
45184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
45194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
45204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
45214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
45224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
45234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
45244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
45254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
45264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
45274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
45284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
45294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
45304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
45314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
45324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
45334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
45344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
45354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
45364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
45374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
45384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
45394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
45404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
45414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
45424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
45434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
45444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
45454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
45464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
45474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
45484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
45494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
45504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
45514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
45524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
45534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
45544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
45554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
45564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
45574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
45584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
45594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
45604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
45614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4562e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4563e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4564777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4565777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4566777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4567777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4568777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4569777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4570777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4571e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4572e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4573e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4574e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4575e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4576e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4577e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4578870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4579870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4580870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4581870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4582870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4583e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
458531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4586e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4587e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
45885a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
45895a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
45905a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
45915a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
459231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
459331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
459431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
459531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
459631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
459731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
459831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
459997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4604e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4606777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4607777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4608777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4609777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4610777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
461114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4612777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4613777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4614777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
46155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4616777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4617777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
46185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
4619777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4620777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
46255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
46265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
46275b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
46285b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
46295b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
46305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
46315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
46325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
46335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
46345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
46355b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
46365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
46375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
46385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
46395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
46405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
4641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
46448b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
46468b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
46479806555d3930be43e11106281dee354820ac1c88Andreas Huber
4648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4652e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4654777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4655777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4656777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4657777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4658777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4670e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
46719806555d3930be43e11106281dee354820ac1c88Andreas Huber
4672777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4673777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4674777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4675777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4676777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
46800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
46830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4693e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4695777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4696777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4697777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4698777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4699777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4707e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4710e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4713777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4714777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4715777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4716777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4717777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4718e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4719e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4720e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4722e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4723e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4727e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4728e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4729e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4730e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4731777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4732777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4733777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4734777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4735777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4736e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4737e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4738e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4739e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4740e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4741e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
474397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
474497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
474597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
474697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4747e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
474897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4749777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4750777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4751777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4752777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4753777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4754777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
475597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
475697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
475797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
475897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
475997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
476097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
47628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
47638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
47648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
47658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
47668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
47678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4768777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4769777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4770777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4771777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4772777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4773777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
47748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
47758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
47768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
47778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
47788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
47798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
47808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
47818c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
47828c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
47838c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
47848c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
47858c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
47868c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4787777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4788777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4789777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4790777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4791777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4792777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
47938c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
47948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
47958c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
47968c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
47978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
47988c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
47998c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
480010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
480110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
480210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
480310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
480410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
480510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4806777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4807777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4808777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4809777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4810777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
481110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
481210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
481310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
481410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
481510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
481610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
481710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
481810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
481910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
482010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
482110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
482210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
482378bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
482410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
482510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
482641d3f579d2c166984958263533284209b90c87d5Marco Nelissen
482741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
482841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
48290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
483041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
483141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
483241d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4833777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4834777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4835777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4836777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4837777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
483841d3f579d2c166984958263533284209b90c87d5Marco Nelissen
483941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
484041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
48410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
484241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
484310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
484410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4846777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4847777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4848777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
485031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
485131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
485231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
485331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4854777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4855777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
485631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
485731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4861b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
4862b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
4863b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
4864b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
4865b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4866b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
4867b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
4868b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
4869b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4870b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
4871b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
4872b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4873b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
4874b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
4875b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4876b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4877b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
4878b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
4879b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
4880b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4881b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
4882b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
4883b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4884b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
4885b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
4886b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4887b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4888b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
4889b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
4890b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
4891b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
4892b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
4893b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
4894b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
4895b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
4896b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
4897b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
4898b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
4899b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
49001734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
4901697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // store new output format, at the same time mark that this is no longer the first frame
4902b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
4903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4904b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
4905777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4906777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
4907777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4908e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
49091734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    if (expectedFormat != NULL) {
49101734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
49111734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
49121734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        if (changes->countEntries() != 0 || to->countEntries() != 0) {
49131734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
49141734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mComponentName.c_str(),
49151734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    changes->debugString(4).c_str(), to->debugString(4).c_str());
49161734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        }
49171734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    }
49181734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar
49195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
49205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
49215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
49225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
49235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
49245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
49255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
49265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
49275b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
49285b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
49295b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
49305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
4931b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
4932b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
4933b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
4934b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
4935b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
4936b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> &notify) {
4937e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4938b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
4939e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4940b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) {
4941b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // notify renderer of the crop change and dataspace change
4942e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4943b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t left, top, right, bottom;
4944b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
4945b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setRect("crop", left, top, right + 1, bottom + 1);
4946b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
4947b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4948b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t dataSpace;
4949b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
4950b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setInt32("dataspace", dataSpace);
4951b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
4952b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
4953b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
4954b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
4955b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
4956b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
4957b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
4958b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
4959b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
4960b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        int32_t channelCount, sampleRate;
496184d7e874983ee0d66db328c454fa603374d4635fMarco Nelissen        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
4962b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
4963b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        if (mSampleRate != 0 && sampleRate != 0) {
4964b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderDelay = mEncoderDelay * sampleRate / mSampleRate;
4965b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderPadding = mEncoderPadding * sampleRate / mSampleRate;
4966b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mSampleRate = sampleRate;
4967b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        }
4968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4969e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4971ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4974b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
4975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4976e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4977b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> notify = mNotify->dup();
4978b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4979b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setMessage("format", mOutputFormat);
498031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
498131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4982b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
4983b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
498431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
498531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
49865778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4987cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4988d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4989251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4990251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4991251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4992251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4993251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4994251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4995251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4996251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4997251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4998251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4999346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5000346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
5001346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
50025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
5003251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
5004cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
5005cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5006cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5009eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
5010eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5011eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5012496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5013496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5014496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5015496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5016496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5017496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5018496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5019496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5020496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5021496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5022496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5023496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
5024496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
5025496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5026496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5027496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5028496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5029496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5030eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
5031a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        IOMX::buffer_id id, const sp<ABuffer> &buffer,
5032a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
5033eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
5034eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
5035a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mHandles.push_back(handle);
503686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    mMemRefs.push_back(memRef);
5037eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5038eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5039eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
5040eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
5041eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5042eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5043eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
5044eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
5045eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5046eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5047eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
5048eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
5049eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5050eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5051a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnarsp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
5052a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    return mHandles.itemAt(index);
5053a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar}
5054a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
505586b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wusp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
505686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    return mMemRefs.itemAt(index);
505786b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu}
505886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu
5059eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
5060eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5061f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5066ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5067ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
508626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
508726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
508826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
508926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5090e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5091e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5092e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5093e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5094e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5095e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
509826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
51021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
51031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
51041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
51051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
51061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
51071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
51081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
51092235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
51101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
51111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
51121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
51131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
51141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
51151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
51161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
51177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
51188f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
51197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
51207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
51227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
51237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
51247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
51257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
51267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5127ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5128ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5130ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
5131ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5132ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5133ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5134ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
513530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
513630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
513730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
513830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
513930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
514030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
514130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
514230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
514330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
514430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
514530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
514630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
514730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
515526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
51565e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
51575e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5158ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
51595e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
51605e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
516126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
51625e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
51635e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
5165609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
5166777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
5167777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
5168777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5169777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
517026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
517126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
517226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
517326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
517426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
517526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
517626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
517726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
517890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
517926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
518026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5181e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5182e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
518390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
518490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
518590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
518690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
518790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
518890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
518990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
519090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
519190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
519290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
519326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
519426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
519526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
519626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
519726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
519826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
519926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52090af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
52100af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
52110af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
52120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
52130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
52140af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
52150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
52160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
52170af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
52180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
52190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
522915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
523015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5231609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
523215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
523415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5240609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
524215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
524915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
525515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
525615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
525990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
526090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
526190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
526290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
526390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
526490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
526590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
526690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
526790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
526890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
526990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5271777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5272777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
527690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
527790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
527890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
527990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
528090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
528190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5284b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
5285b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ColorAspects aspects;
5286b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mRange = (ColorAspects::Range)((data2 >> 24) & 0xFF);
5287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mPrimaries = (ColorAspects::Primaries)((data2 >> 16) & 0xFF);
5288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)((data2 >> 8) & 0xFF);
5289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mTransfer = (ColorAspects::Transfer)(data2 & 0xFF);
5290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5294b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5296ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5302ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5304251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5305251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5306251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5307251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5308251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5309251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
531515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5316ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
53190806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
53200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
53210806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
53220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
53230806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
532415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
532515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
532615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
53270806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
53280806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
533115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
533215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
533315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
533415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
533515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
533615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
533715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
533896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
533996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
534096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
534196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
534296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
534396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5355777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5357777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5358777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
5372d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
5373609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
53762d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
5379609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5390609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
53912d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
53935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5394a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
53955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
53962d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
5397a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
5399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54007fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
54017fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
54027fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
54037fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
54047fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
54057fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
54067fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
54077fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
54083831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
54092d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
54135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
54145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
54155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
54165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
54175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
54190806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
54200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
54210806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
54220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
54230806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
54240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
54250806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
54325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5433dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5434dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5435dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5436dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
54435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5444fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5445fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5446fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5447fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5448fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5449fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                MetadataBufferType metaType = mCodec->mInputMetadataType;
5456d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                int32_t isCSD = 0;
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5458f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    if (mCodec->mIsLegacyVP9Decoder) {
5459f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
5460f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                            mCodec->mComponentName.c_str(), bufferID);
5461f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        postFillThisBuffer(info);
5462f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        break;
5463f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    }
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5465d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    metaType = kMetadataBufferTypeInvalid;
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
54695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
54705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
54715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (buffer != info->mCodecData) {
5473ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5474d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
54765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                         buffer.get(), info->mCodecData.get());
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
5479d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (converter == NULL || isCSD) {
54805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
54815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
54825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
54835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
54845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
54850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
54860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5489078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5490ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5491078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
54925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5493ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
54945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5495078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5497ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5498ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5500ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5501ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5503078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5504349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5512054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5513054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5514054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5515054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5516054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5517054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5518054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5519054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5520054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5521054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5522054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5523054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
552415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5525d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5526d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                status_t err2 = OK;
5527d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                switch (metaType) {
5528d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeInvalid:
5529d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5530d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5531d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeNativeHandleSource:
5532d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
5533d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeHandleMetadata *vnhmd =
5534d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            (VideoNativeHandleMetadata*)info->mCodecData->base();
5535d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        err2 = mCodec->mOMX->updateNativeHandleInMeta(
5536d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                mCodec->mNode, kPortIndexInput,
5537d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                NativeHandle::create(vnhmd->pHandle, false /* ownsHandle */),
5538d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                bufferID);
5539d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5540d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5541d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeANWBuffer:
5542d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
5543d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
5544d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        err2 = mCodec->mOMX->updateGraphicBufferInMeta(
5545d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                mCodec->mNode, kPortIndexInput,
5546d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                new GraphicBuffer(vnmd->pBuffer, false /* keepOwnership */),
5547d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                bufferID);
5548d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5549d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5550d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#endif
5551d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                default:
5552d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
5553d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            asString(metaType), info->mCodecData->size(),
5554d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            sizeof(buffer_handle_t) * 8);
5555d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    err2 = ERROR_UNSUPPORTED;
5556d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5557d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
5558d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5559d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                if (err2 == OK) {
5560d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    err2 = mCodec->mOMX->emptyBuffer(
5561d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        mCodec->mNode,
5562d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        bufferID,
5563d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        0,
5564d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        info->mCodecData->size(),
5565d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        flags,
5566d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        timeUs,
5567d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        info->mFenceFd);
5568d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
556915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
55700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
55710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
55720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
55730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
55775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
55785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
55790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
55800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
55815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
55835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
55845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
55860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
55870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5588dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5589dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
55903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5591dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5592dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5594ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5595349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5596349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
559715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
55980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
55990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
56000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
56010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
56020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
56030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
560415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
560515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
560615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
56080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
56090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
56100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5614dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5618625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5619777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5620777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5621777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5622625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5623777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5624625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
566115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
566215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5663609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
56645778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5665349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
56670806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5668d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5669d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5676d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5677d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5679d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
56860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
56870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
56880806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
56890806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
56900806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
569115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
569215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
569315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
56940806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
56950806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5697054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
570090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
570190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
570290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
570390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
570490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
570590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
570690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
570790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
570890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
570915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
571015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
571115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
571215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
571315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
571415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
571515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5724a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5725a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5726609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
57275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5728349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
572915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
573015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
57310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
57320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
57330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
57340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
57375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
57385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
573931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5740577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
57411d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
5742577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5743b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5744697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                // pretend that output format has changed on the first frame (we used to do this)
5745697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
57461734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
5747697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                }
5748b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
5749b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
5750fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            } else if (rangeLength > 0 && mCodec->mNativeWindow != NULL) {
5751fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                // If potentially rendering onto a surface, always save key format data (crop &
5752fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                // data space) so that we can set it if and once the buffer is rendered.
5753fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
57545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5755b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5756054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
5757054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
57583e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                VideoNativeHandleMetadata &nativeMeta =
57593e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    *(VideoNativeHandleMetadata *)info->mData->data();
57603e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                if (info->mData->size() >= sizeof(nativeMeta)
57613e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeNativeHandleSource) {
57627c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
57633e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    // handle is only valid on 32-bit/mediaserver process
57647c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
57657c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
57663e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    handle = (native_handle_t *)nativeMeta.pHandle;
57677c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5768054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
5769308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
5770308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5771308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
57725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else if (info->mData == info->mCodecData) {
5773308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
57745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
57755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
57765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
57775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
57785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info->mCodecData, info->mData);
57795b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
57805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
57815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
57825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
5783308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
5784496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
578521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
5786496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
5787496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
5788496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
57895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
579021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
5791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
57938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
57948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
57955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5798d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5799609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
58002d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
58015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
5802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5803609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
58085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
58095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
58125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
58135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
5815d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
5816dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
5818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5824777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
58250806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
58260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
58270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
58290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5831777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5832777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5833777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5834777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5842609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
58440806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
58450806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
58460806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
58470806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
58480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
58490806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
58500806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
58510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5853577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
5854fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)
5855fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            && memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
5856fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar        mCodec->mLastNativeWindowCrop = crop;
5857777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5858777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5859577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
5860577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5861b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t dataSpace;
5862fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    if (msg->findInt32("dataspace", &dataSpace)
5863fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            && dataSpace != mCodec->mLastNativeWindowDataSpace) {
5864b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = native_window_set_buffers_data_space(
5865b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
5866fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar        mCodec->mLastNativeWindowDataSpace = dataSpace;
5867b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
5868b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5869b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
58726aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
587379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
58746fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
587790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
587890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
587990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
588090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
588190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
588290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
588390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
588490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5885fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
5886fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
5887c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
5888fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5889c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
5890fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
5891fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
5892fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
5893fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
58945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
5895fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
58960806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5897fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
589815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
58990806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
590015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
590115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
59020806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
5903cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5904cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
5905264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
5906251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5907cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
590815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
590915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
5910cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
59126fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
59136fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
591415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
591515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
59166fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
59176fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
5931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
5940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
5942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5947c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
5948609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
5949c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
595015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
595115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(
595215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                            mCodec->mNode, info->mBufferID, info->mFenceFd);
595315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
59540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
59550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
59560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
59570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5959c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
5960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5964777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
59660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
59670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
59680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5972777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5973777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5974777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5975777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5981f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5985c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
5986c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
5987ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5988ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
598923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mCodec->mNodeBinder->unlinkToDeath(mDeathNotifier);
5990ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5991ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5992ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5993b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
5994ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
5995e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
5996ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
5997ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
5998ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
5999ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6000054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
6001054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
60025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
60035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6004ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
60205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
60215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
60225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
60235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
60245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
60255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6028c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6029c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6030c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
603154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
603254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
6033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6035d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6039c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6045d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6049c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
605230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
605330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
605430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
605530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
605630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
605730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
605830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
60725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
60735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6074c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
60755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
60765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6077ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
60785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
608048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
608148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
608248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
608348a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
6084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6088ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6089b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
60905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
6094d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
60957791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
60965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6097b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6098b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6099b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6100afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
61015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
61025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
61035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
61045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
61055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
61065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
61075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6108b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
61095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
61105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6111b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6112e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
61135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
61141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
61151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6116ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
61171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6118201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
61191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
61201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6121b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6122b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6124da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6125078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6126078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
612723858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node);
6128078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
61311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
61327a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
61337a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
61341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
61351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6136ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
61371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
61381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6139ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
61405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
61419f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
61429f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
61435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
61449f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
61455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6146c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
614752e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6149c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
615123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
615223858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    if (mCodec->mNodeBinder == NULL ||
615323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen            mCodec->mNodeBinder->linkToDeath(mDeathNotifier) != OK) {
615423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // This was a local binder, if it dies so do we, we won't care
615523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // about any notifications in the afterlife.
615623858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mDeathNotifier.clear();
615723858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
615823858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
615926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
616390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6164ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6165ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6167ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
61681713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
61690167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6170ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6171ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6172afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
6173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
61775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6178d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
61795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
61805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
61815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
61865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
61875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6197f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6198f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6199f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6200f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6201f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6202054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6203054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6204a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6205e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6206e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
62074e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
6208054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
621754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6218f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6219f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
62240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
6225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6228c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
622954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
623054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
6231d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
623254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
623354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
623454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6239c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6245c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
62487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
62497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
62507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
62517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
62527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
62537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
62547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
62558f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6256d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
62578f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6258d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6259d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6260d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6261d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
627554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6285d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6286c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
6287c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6290c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6291c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
63005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
63015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
63025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6303ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
63045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
63050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
63065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
63070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
63080806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
63090806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
63100806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
63110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
63125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6313c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6314c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6315c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6316251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6317c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
63185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
63215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6322d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
6323e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
6324e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
63255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
63265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6328c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
63295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
63305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6331d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6332d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
6333a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6334d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
6335a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
6336a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
6337a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
6338a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
6339a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
6340a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
6341a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6342a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6343a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6344a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
6345a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
6346a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
6347d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6348a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6349a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6350a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6351d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
635294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
635394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
635494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
635594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
635694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
635794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
635894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
635994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
636094ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
636172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
636272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
6363d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
63642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
63652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
63662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6367d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
636837b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
636937b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
637037b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
637137b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
637237b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
637337b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
637437b2b389139ed638831e49708c947863eef631efRonghua Wu
637537b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
637637b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
637737b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
637837b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
6379d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
638037b2b389139ed638831e49708c947863eef631efRonghua Wu        }
638137b2b389139ed638831e49708c947863eef631efRonghua Wu    }
638237b2b389139ed638831e49708c947863eef631efRonghua Wu
6383d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
63842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
63852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
63862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
63872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
63882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
63892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
63902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
63912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
63922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
63932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
63942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
63952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
63962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
63972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
63982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
6399d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
64002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
64012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
640272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6403d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
640472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
640572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
640672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
640772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
640872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
640972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
641072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
641172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
641272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
641372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
641494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
641594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
6416d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
641794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
641894ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
641994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6420c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6421c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    if (mCodec->mOMX->getParameter(
6422c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6423c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6424c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6425c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6426c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6427c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
6430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInternalOption(
6431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, IOMX::INTERNAL_OPTION_COLOR_ASPECTS,
6432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                colorAspectsBuffer->base(), colorAspectsBuffer->capacity());
6433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6434b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6435b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6436b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6437b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6439d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6440d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6441d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6442d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6443d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6444d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6445d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6446d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6447d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
6448d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6449b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6450b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6451b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6452b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6453b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
645457fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar
6455d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6456b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
64573e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
6458b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->createInputSurface(
64593e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                mCodec->mNode, kPortIndexInput, dataSpace, &bufferProducer,
64603e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                &mCodec->mInputMetadataType);
64613e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        // framework uses ANW buffers internally instead of gralloc handles
64623e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        if (mCodec->mInputMetadataType == kMetadataBufferTypeGrallocSource) {
64633e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
64643e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        }
6465b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6466d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6467d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6468d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6469d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6470d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
64717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
64727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
64737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
64747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
64757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
64767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
64777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
64787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
64797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
64807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
64817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
64827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
64837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
64847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
64858f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
6486d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
64878f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6488d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6489d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6490d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
6491d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6492d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6493d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6494d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6495d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6496b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6497b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6498b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
6501b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6502b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
65033e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
6504b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInputSurface(
6505b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
6506b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                &mCodec->mInputMetadataType);
65073e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        // framework uses ANW buffers internally instead of gralloc handles
65083e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        if (mCodec->mInputMetadataType == kMetadataBufferTypeGrallocSource) {
65093e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
65103e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        }
6511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6512d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6513d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        surface->getBufferConsumer()->setDefaultBufferDataSpace(dataSpace);
6515d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6516d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6517d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6518d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
6519d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6520d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6521d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
65228f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6523d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
6524d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
6525d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6526d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
6527d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6528d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
65305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
65315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
65320806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
65330806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
65340806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
65350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
65360806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
65370806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6542f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6546f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
65473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6549cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6550cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
655129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6552cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6553cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6554cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6555251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
655691bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6557c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        mCodec->mOMX->sendCommand(
6558c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6559c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6560c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6561c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6562c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6563c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6564c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6565c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
656691bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6567cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6570f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
6578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6580f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
658272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
65906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
65916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
65926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
65936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
65946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
65956463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
65966463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
65976463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
65986463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
65996463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
66016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
66026463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
66036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
66046463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
6605d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
66066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
66076463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
66086463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66096463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6615f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
66200806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
66210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
66220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
66230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
66240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
66250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
66260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
66270806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
66300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
66310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
66320806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
66350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
66360806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
66370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
66380806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6650f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6654f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
66553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6658f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
666072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6667d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6668d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6669d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6670d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6671d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6672d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6673d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6674d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6675d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
6676d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6677d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6678d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
6679d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6680d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6681d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6682d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
66836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
66846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
66856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
66866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
66876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
66886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6694f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
66990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
67000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
67010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
67020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
67030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
67040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
67050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
67060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6721f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6722349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6723349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6726f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6727ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6738054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
67424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
67434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6744054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
67480806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
67530806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
67540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
67550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
67560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
67570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
67580806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
67640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
67650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
67660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
67670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
67680806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67710806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6772349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
677315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
677415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
677515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
67760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
67770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
67780806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
67790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
67830806340688c937e7b78c2d89db3809274130df4eLajos Molnar
67840806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
67850806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
67860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6790c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6791054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6796f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6797349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
67980806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6799349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6800349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6801349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68043cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6805777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6806777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6807777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6808777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
68093cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
68103cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
68113cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
68123cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
68133cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
68143cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6815349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6816349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6819f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
68203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
682290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
6824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6826f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6832c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6833c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6834c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6835c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
683754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6838c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6839c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6840349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6841349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
68420806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
68430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
68440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
68450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
68460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
68480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
68490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
68500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
68510806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
68597a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
6860ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
6861d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
6862d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6863d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
6864d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6865d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
6866d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6867349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6868349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
68690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
68700806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
68710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68720806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
68730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
68740806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
6881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
6883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6888496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
6889496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
6890496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
6891496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
6892496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
6893496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
6894496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6895496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
6896496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
6897496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
6898496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6899a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
6900a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
6901a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
6902a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
6903a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6904a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
6905a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6906a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
6907a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
6908a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
6909a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
6910a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
6911a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6912a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
6913a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
6914a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6915a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
69167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
69177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
69186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
69197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
69207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
69217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
69227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
69234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6924054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
69254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
69264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
69274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
6928054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
69294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
6930054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
69314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
69324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
69334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
69344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
69354dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6944a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
6945a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
6946530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
6947a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6948a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
6949a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
6950a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
6951a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6952a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
6953a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
6954a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
6955a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
6956a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
6957a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6958a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
6959a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
6960a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
6961a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6962a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
6963a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6964a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
6965a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
696672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
696772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
696872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
696972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
697072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
697172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
697272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
697372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
697472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
697572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
697672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
697772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
697872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
697972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
698072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
698172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6982e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
6983e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
6984e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
6985e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
6986b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
6987b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
6988e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
6989e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
6990e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
6991e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
6992b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
6993b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6994b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
6995b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
6996b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
6997b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
6998b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
6999b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7000b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7001b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7002b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7003b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7004b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7005b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7006b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7007b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7008e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7009e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
70108db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
70118db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
70128db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
70138db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
70148db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
70158db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
70168db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
70178db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
70188db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7019870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7020870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7021870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7022870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7023870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7024870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7025870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7026870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7027870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7028870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7029870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
7030a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
7031a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7032a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
70336507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
70346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
7035d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
70366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
70376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
70386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
70396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
70406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
70416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
70426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
70436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
704490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
704590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
704690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
704790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
704890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7049f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7056b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7057b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
705831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7059054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
7061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
7062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7065349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7068b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7069b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7070ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7089f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7094f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7105f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7112349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7113e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7115349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
71163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7117349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7118349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7132f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
71333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
713790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
713890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
713990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
714090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
714190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
714290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7143f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
71490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
71500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
71510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
71520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
71570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
71580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
71590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
71600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
71610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
71620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
71630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
71660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
71670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
71680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
71710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
71720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
71730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
71740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7175cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
71760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7177251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7178d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7179755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7180755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7181755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7182755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7183755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7184755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7185755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7186755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7187cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7191777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7192777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7193777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7194777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7198349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7199349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7200349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7201349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7217f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
72185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
72195778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7222f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
72300806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7250f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
72513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
725231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
72535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7254b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7257f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
72620806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
72630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
72640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
72650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
72660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
72670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
72680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
72690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
72725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7281349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7283349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7284349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
72890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7290f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
72915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
72920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
72930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
72940806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
72950806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
72960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
72970806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
72980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
72990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
73000806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73020167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
73030167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7304bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7305bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7306bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7307bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7308b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7309bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7310bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
73110806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
73120806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73130806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
73140806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
73150806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7320f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7327f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7336f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
73560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7368f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
73693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7372f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
73770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
73780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
73790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
73800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
73810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
73820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
73840806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7386c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7398f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7402f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
74033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7408f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7433f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
7434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7435ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
7436ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
7437d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
74410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
74420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
74430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
74440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
74450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
74460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
7449777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
7450777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
7451777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
7452777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
7453777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
7455e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
74560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
7457e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
7458e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
7459777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
7460777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
7461777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
7462777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
7463777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
7464777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7465777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
7468777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
7469777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
7470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7475349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7476349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
74771d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
7478349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
7479609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
7480349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
7481349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
7482349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
7483349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
74843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
7485349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
7486349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7487349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
7488349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7489349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7490349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7491349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
7497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7499f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
7500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7505f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
7506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7511f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
7512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
7513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
7514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
75157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
75167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
75177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
75187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
751990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
752090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
7522d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
7523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
7524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
7526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
7527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7528dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
7529dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
7530f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
7531f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
7532f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
7533f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
7534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
7535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
75395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
75405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
75415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
75421ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime.c_str());
75435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
75445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
75455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
75465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
75485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = client.connect();
75495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
75505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
75515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
75525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
75545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
75555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    IOMX::node_id node = 0;
75565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
755723858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    err = omx->allocateNode(name.c_str(), observer, NULL, &node);
75585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
75595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
75605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
75615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
75625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75631ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    err = SetComponentRole(omx, node, role);
75645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
75655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        omx->freeNode(node);
75665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
75675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
75685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
75695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
75715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
75725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
75745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
75755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
75765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
75775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75786e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
75796e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
75805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
75815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
75825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
75835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
75845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
75855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
75865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
75876e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
75886e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
75896e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
75906e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
75916e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
75926e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
75935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
75945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
75965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
75975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
75985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
75995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
760036e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
76015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
76026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76036e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
76045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoPortFormat,
76065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
76075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
76121ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim            if (IsFlexibleColorFormat(
76135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    omx, node, portFormat.eColorFormat, false /* usingNativeWindow */,
76145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
76155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
76165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
76175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
76185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
76195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
76205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
76215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
76225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
76235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
76245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
76255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
76265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
76285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
76296e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
76306e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
76316e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
76326e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
76336e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
76346e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
76355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
76375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
76385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
76395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
76405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
76416e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76426e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
76435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
76455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
76465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
76505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
76516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
76526e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
76536e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
76546e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
76556e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
76566e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
76575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
76605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
76615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
76625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
76635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
76675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
76685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->configureVideoTunnelMode(
76695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
76705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
76715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
76725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
76735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        } else if (omx->storeMetaDataInBuffers(
76745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE) == OK ||
76755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            omx->prepareForAdaptivePlayback(
76765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE,
76775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
76785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
76795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
76835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
76845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
76855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
76865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
76875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->getConfig(
76885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
76895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
76905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
76915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
76955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    omx->freeNode(node);
76965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
76975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
76985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
76995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7700a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
7701a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
7702a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
7703a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
7704a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
7705a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
7706a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
7707a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7708a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
7709a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7710a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7711a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7712a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
7713a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7714a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7715a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7716a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7717a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
7718a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7719a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7720a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
7721a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
7722a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7723a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
7724a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7725a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7726a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7727a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
7728a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
7729a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7730a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
7731a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7732a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7733a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7734a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7735a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7736a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7737a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7738a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
7739a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7740a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7741a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7742a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7743a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7744a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7745a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
7746a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7747a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
7748a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7749a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7750a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7751a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7752a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7753a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7754a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
7755a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
7756a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7757a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
7758a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
7759a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
7760a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7761a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
7762a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
7763a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
7765