ACodec.cpp revision 5b4401b28990107bb797dc0d5f3904cf27417e98
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 {
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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 {
270ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    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 {
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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 {
306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    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 {
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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 {
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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 {
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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 {
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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 {
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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 {
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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 {
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    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()
497afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
498609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
500e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
5018db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
503346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5049806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
50554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
5069806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5079806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
508e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5099806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
510054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
511054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
512054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mInputMetadataType(kMetadataBufferTypeInvalid),
513054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mOutputMetadataType(kMetadataBufferTypeInvalid),
514011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
515054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
51794ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
51937b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
5202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
521609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
522ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
5238338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
5248338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0) {
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
539dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
547f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5531d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
559a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
560a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
561a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
562a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5635778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5695778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
5801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
5811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
5831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
5841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
5861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
5871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
5891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
5907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5928f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
593d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
5948f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
595d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
596d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
597d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
598d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6035778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6087a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
612f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
62030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
62130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
62330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
626496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
628496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
629496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6304dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
635054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
637054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
638054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
652e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
671e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
672e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);
6731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
677f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
678e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
679e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
680e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
681e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
682e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
683e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
6841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
6921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
6931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
6991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
713dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
714dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
715dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
721054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
722011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
739054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
74115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
74515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
74615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
759484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
760484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
761484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
762484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
763484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
765e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
777054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()) {
778054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
791054219874873b41f1c815552987c10465c34ba2bLajos Molnar            MetadataBufferType type =
792054219874873b41f1c815552987c10465c34ba2bLajos Molnar                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
7935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
794054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (type == kMetadataBufferTypeGrallocSource) {
795054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoGrallocMetadata);
796054219874873b41f1c815552987c10465c34ba2bLajos Molnar            } else if (type == kMetadataBufferTypeANWBuffer) {
797054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
798054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
799054219874873b41f1c815552987c10465c34ba2bLajos Molnar
800054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // If using gralloc or native source input metadata buffers, allocate largest
801054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // metadata size as we prefer to generate native source metadata, but component
8025fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // may require gralloc source. For camera source, allocate at least enough
8035fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // size for native metadata buffers.
8045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t allottedSize = bufSize;
8055fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) {
806054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
8075fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
8085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                bufSize = max(bufSize, sizeof(VideoNativeMetadata));
8095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
8105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
821054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
822054219874873b41f1c815552987c10465c34ba2bLajos Molnar
82328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
82428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            ALOGV("[%s] Allocating %u buffers of size %zu/%zu (from %u using %s) on %s port",
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
827054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
8285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
8315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
83228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
83328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
83428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
83528edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
83628edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
83728edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
8385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
8395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
84034e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
84134e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
84234e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
84328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
847054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
848054219874873b41f1c815552987c10465c34ba2bLajos Molnar                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
8495581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
850777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
851777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
854ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
85515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
85690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
857a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                info.mNativeHandle = NULL;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
860afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
861b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        ? kRequiresAllocateBufferOnInputPorts
862b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        : kRequiresAllocateBufferOnOutputPorts;
8631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
864e33d922fd86699c664a15f09e6d8b2e422736a40Lajos Molnar                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
865ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
866ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
867a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
868a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    native_handle_t *native_handle = NULL;
869a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    err = mOMX->allocateSecureBuffer(
870054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, bufSize, &info.mBufferID,
871a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
872a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
873a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY: this representation is unorthodox, but ACodec requires
874a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // an ABuffer with a proper size to validate range offsets and lengths.
875a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // Since mData is never referenced for secure input, it is used to store
876a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // either the pointer to the secure buffer, or the opaque handle as on
877a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // some devices ptr is actually an opaque handle, not a pointer.
878a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
879a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY2: use native handle as the base of the ABuffer if received one,
880a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // because Widevine source only receives these base addresses.
881a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    info.mData = new ABuffer(ptr != NULL ? ptr : (void *)native_handle, bufSize);
882a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    info.mNativeHandle = NativeHandle::create(native_handle, true /* ownsHandle */);
8835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = info.mData;
884ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
886054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
888054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
889ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
890ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
891ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
8925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = new ABuffer(mem->pointer(), bufSize);
8935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecRef = mem;
8945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
895054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (type == kMetadataBufferTypeANWBuffer) {
896054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
897054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
8985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // if we require conversion, allocate conversion buffer for client use;
9005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // otherwise, reuse codec buffer
9015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (mConverter[portIndex] != NULL) {
9025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        CHECK_GT(conversionBufferSize, (size_t)0);
9035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mem = mDealer[portIndex]->allocate(conversionBufferSize);
9045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        if (mem == NULL|| mem->pointer() == NULL) {
9055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            return NO_MEMORY;
9065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        }
9075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = new ABuffer(mem->pointer(), conversionBufferSize);
9085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = mem;
9095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else {
9105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = info.mCodecData;
9115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = info.mCodecRef;
9125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
9161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
9171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
925d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
928eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
929eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
930eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
932eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
933a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        desc->addBuffer(info.mBufferID, info.mData, info.mNativeHandle, info.mMemRef);
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
936eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
942e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
943e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {
9441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
9491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
9521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
9561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
9571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
9581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
9591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
9601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
9611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
9631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
9651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
9661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
968f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
969e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
970b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
9711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
9721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
9731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
9741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
9751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
9761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
9771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
9781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
9791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
9801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
9821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
9831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
9841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
9891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
992e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);
9931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
995e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
9961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
999ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
1000ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
1001ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
1002ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1003ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1004ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
1005ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
1006ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1007ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1008ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
1009ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
1010ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
1011ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
1012ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1013ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1014054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
1015258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
1016258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1017054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
1018258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1019258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
102029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1021258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
1022258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
1023258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1024258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1025e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
1026e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
10271faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
10281faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1029e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1030e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
1031e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
1032e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1033e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
1034e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
1035e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
10361faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
10371faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1038e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
1039e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1040258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1041258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
1042258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1043258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1044e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1045e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1046e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1047e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1048e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1049609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1050e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1051e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1052e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1053258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1054258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1055258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1056258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
106129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1066054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1067054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1076054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1077e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1079054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
10803298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
10813298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
10823298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10833298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1084609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
10908ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
109115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
109215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
109429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
109974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
110074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
110115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
110215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
110390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
11055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
110674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
110774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
110874006804065941841883c4b46ee785070164023fJamie Gennis
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1113609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
111474006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
111874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
111974006804065941841883c4b46ee785070164023fJamie Gennis
1120609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
113274006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1134054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1135054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1136054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
11413175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
11423175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
11433175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
11443175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
11453175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
11463fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1149054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
11503298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
11513298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
11523298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
11533298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1157054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1159054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1163e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1165e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1166e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1167e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1168054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1169054219874873b41f1c815552987c10465c34ba2bLajos Molnar            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
117028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar    size_t totalSize = bufferCount * align(bufSize, MemoryDealer::getAllocationAlignment());
1171e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1172e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1173e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
1174e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1175e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1176e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
117715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
117890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1179e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1180e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1181e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1182054219874873b41f1c815552987c10465c34ba2bLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
11835581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
1184777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
1185777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1186054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1187054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1188054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1189e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
11905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mMemRef = mem;
11915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
11925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecRef = mem;
1193e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1194e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
1195e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        err = mOMX->useBuffer(
1196cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1197e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1198e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1199e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1200e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1201e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1202e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1203011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1204e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1205011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1206011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1207011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1208011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1209011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1210011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1211011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1212011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1213011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1214e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1215e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1216011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
121715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd;
121815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1219011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1220011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1221011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1222011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1223011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1224011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1225e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            mOMX->updateGraphicBufferInMeta(
1226e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1227e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
122815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1229e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1230011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1231011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1232011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1233011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
12343175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (info->mStatus == BufferInfo::OWNED_BY_US) {
12353175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                status_t error = cancelBufferToNativeWindow(info);
12363175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                if (err == OK) {
12373175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                    err = error;
12383175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                }
1239011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1240011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1241011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1242011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1243011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1244011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1245011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1246054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1247054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1248054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1249054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1250054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1251054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1252054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1253054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1254054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1255054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
12560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1257054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
12580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1260609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1263054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
126415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
126515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
126615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1267777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1268777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1269777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1270054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1271777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1272054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1273054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
127415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
127515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
127615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
127715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
127815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
127915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
128015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
128115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
128215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
128315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
12840806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
12850806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
12860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
12870806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
12880806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
12890806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
12900806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
12910806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
12920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
12930806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
12940806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
12950806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
12960806340688c937e7b78c2d89db3809274130df4eLajos Molnar
12970806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
12980806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
12990806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
13000806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
13010806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
13020806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
13030806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
13040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
13050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
13060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
13070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13080806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13090806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1313609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
131815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
131915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13213fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
13223fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
13230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13263fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
133090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
133190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
133290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
133390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
133490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
133590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
133690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
133790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
133890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
133990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
134090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
134190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
134290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
134390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
134490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
134590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
134690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
134790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = mNotify->dup();
134890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
134990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
135090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
135190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
135290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
135390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
135490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1355604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1356604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1357604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1358604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1359604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1360604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
136190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
136290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
136390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
136490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
136590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->post();
136690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
136790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
136890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1369f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
13708ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1372ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1373ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1374ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1375ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1376ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1377ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1378ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1379346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1380346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1381346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1382346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1383346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
138415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1385dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
138615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
138715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
138815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1389dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1390dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1392dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1393b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1394b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1395dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1396dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1397dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
139890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1399dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1400dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1401dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1402dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1403dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1404dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1405dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1406dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1407dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1408dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1409dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1410dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
141190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1412dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1413dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
141415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
141590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1416dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1417dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1418dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1420dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1421dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1422dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1423dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1424dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1425054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1426dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1427dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1428dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1429dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1430dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1431dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1433dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1434054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1435dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1436dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1437b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1438b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1439dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1440dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1441054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1442054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1443054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1444054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1445054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1446054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1447054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1448054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1449054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14500806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
14510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
14520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
14530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1454054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1455054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
14570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
14580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
145915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
146090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
146190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1462d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
14630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    mOMX->updateGraphicBufferInMeta(
14640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
14650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mBufferID);
1466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1467054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1468054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata *grallocMeta =
1469054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1470054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1471054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1472054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14737c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)grallocMeta->pHandle,
1474054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1475054219874873b41f1c815552987c10465c34ba2bLajos Molnar    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1476054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata *nativeMeta =
1477054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1478054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1479054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1480054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14817c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)nativeMeta->pBuffer,
1482054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1483054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
14860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1490777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1491938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1492938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1493777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1494777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1495777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1496777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14990806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1501777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1504349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1505777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1506938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1507938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15112ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
15122ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
15132ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
15142ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1515777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1516777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1517777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1518777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1522777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
15270806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
153015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    MetadataBufferType type =
153115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
153215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
153315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
153415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
153515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
153615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
153715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
153815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
153915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
154015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
15410806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
15420806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
15430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
15440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
15450806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
15460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
15490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
15500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
15510806340688c937e7b78c2d89db3809274130df4eLajos Molnar
15520806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
15530806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
15540806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
15550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
155815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
155915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
156015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
156115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1562604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1563604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1564604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1565604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
156690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1567777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1569777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1572f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
15730806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1585777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
15915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    const char *role = getComponentRole(isEncoder, mime);
15925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
15935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
15945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
15955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = setComponentRole(mOMX, mNode, role);
15965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
15975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
15985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
15995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
16005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
16015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
16025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
16035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
16045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarconst char *ACodec::getComponentRole(
16055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        bool isEncoder, const char *mime) {
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
16152944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
16162944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
16172944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
16182944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1625729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1626729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1627bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1628bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1629c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1630c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1631c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1632c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
16352472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
16362472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
164194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
164294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
164394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
164494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1645ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1646ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
1647a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu        { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
1648a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu            "video_decoder.dolby-vision", "video_encoder.dolby-vision" },
16492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
16502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1651ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1652ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1653774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1654774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
165597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
165697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
16578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
16588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
16725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NULL;
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return isEncoder ? kMimeToRole[i].encoderRole
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
16775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
16805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::setComponentRole(
16815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node, const char *role) {
16825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMX_PARAM_COMPONENTROLETYPE roleParams;
16835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    InitOMXParams(&roleParams);
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    strncpy((char *)roleParams.cRole,
16865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            role, OMX_MAX_STRINGNAME_SIZE - 1);
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return omx->setParameter(
16915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            node, OMX_IndexParamStandardComponentRole,
16925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            &roleParams, sizeof(roleParams));
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1702b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1703b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1704b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1705e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1708054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mInputMetadataType = kMetadataBufferTypeInvalid;
1709054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mOutputMetadataType = kMetadataBufferTypeInvalid;
17108db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
17182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
17192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
17202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1725d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1727d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1728054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1729d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1730054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1731308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1732d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1733054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
1734054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1735054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // For this specific case we could be using camera source even if storeMetaDataInBuffers
1736054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
1737054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
1738054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mInputMetadataType = kMetadataBufferTypeCameraSource;
1739054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1740c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1741c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1742c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mOMX->getParameter(
1743c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1744c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1745c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1746c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1747c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1748054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1750308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
17513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
17523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
17533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
17543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
17553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
17563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
17573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
17583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
17593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
17613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
17623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
17633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
17643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
17663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
17673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
17703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
17713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
17723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
17743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
17763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1777308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1778308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1779308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1780308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
17818db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1782308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1783308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1784308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1785308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1786308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1787054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1788308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1789308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1790308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1791308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1792a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1793a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1794a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1795a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1796a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1797a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
179894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
179994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
18002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
18012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
18022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
180337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
180437b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
180537b2b389139ed638831e49708c947863eef631efRonghua Wu        }
180637b2b389139ed638831e49708c947863eef631efRonghua Wu
18072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
18082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
180994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
181072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
181172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
181272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
181372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
181472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
181572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1816308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1817308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
18183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
18200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
18213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1822b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1823011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1824e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1825e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
18261713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
18271713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
18281713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
18291713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
18301713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
18311713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
18321713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
18331713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
18341713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
18351713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1836a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1837a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        if (mFlags & kFlagIsSecure) {
1838a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            // use native_handles for secure input buffers
1839a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = mOMX->enableNativeBuffers(
1840a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    mNode, kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
1841a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            ALOGI_IF(err != OK, "falling back to non-native_handles");
1842a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = OK; // ignore error for now
1843a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
18453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
18461de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
18471de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
18485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18496597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
18506597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
18516597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
18526597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
18536597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
18546597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
18556597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
18566597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
18576597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
18586597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
18596597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
18606597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
18616597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
18626597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
18636597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
18646597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
18656597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
18666597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
18675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
18685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
18695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
18705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1871ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
18725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
187397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
187497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
18755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
18765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
18785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
187997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
18805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
18815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1882fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1883fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1884d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1885d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1886d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1887d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1888d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1889d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1890d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1891d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1892d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
18933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
18943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1895d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1896d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1897d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1898d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1899d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1900d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
19015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1902ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1903ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1904ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
19053fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
19063fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
19073fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
19083fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
19093fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
19103fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
19113fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
19123fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
19133fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
19145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
19155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
1916054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
19175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
19185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1919fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1920e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
19215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
19225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
19235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
19245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
19265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
19275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
19285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
19295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
19305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
19325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
19335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
19345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
19355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
19365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
19375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
19385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
19395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
19405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
19415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
19425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
19445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
19455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
19465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
19475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
19485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
19495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
19515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
19525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
19535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
19545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
19555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
19565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
19585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
19595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
19605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
19615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1962e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
19635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
19645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
19655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
19665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
19675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
1968054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
1969011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1970011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1971011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
19725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1973fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
19740167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
19755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
19765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
19775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
19785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
19795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
19800167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1981e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1982e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1983e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1984e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1985e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1986e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1987e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1989054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
19905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
19915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
19925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
19935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
1994308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
19953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
19963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
19973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
19983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
19993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
20003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
2003b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2005b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
20093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
20103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
20131de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
20143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
20173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
2018777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
2019777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
2020777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
2021777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
20223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
20243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
20253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
20263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
20273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
2028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
2029777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
2030777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
2031777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
20323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
20333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
2034777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
2035777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
2036777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
2037777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
20383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
20393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
20403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
20413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
20423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
20433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
20443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
20453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
20463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
2047e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
20483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
20493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
2050054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (storingMetadataInDecodedBuffers()) {
2051054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        err = mOMX->storeMetaDataInBuffers(
2052054219874873b41f1c815552987c10465c34ba2bLajos Molnar                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
2053054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
20543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
20553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
20563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
20573a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
2059a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                        err = mOMX->enableNativeBuffers(
2060a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                                mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
20613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
20633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
20643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
20653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
2066b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
2067b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
20703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
20713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
20743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
20753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
207642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
207742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
207842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
207942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
208042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
208142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
208242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
208342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
208442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
208542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
208642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
208742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
208842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
2089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2095aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
2096b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
20978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
20982965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
20998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
2100ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
2101ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
2102ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
2103aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
2104aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
2105aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
2106b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2107b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
2108b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
2109ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
21108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
21118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
21128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21132965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
21142965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
21152965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
21162965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
21178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
21188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
21208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21218045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
21228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
21248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
21268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
21288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21298045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
21308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
21328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
21348045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
21368045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2138ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
21394471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
21402965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
21412965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2143729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2145729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2147729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2148729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2149729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2150729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2151729de186450f78c099637e1fce743fe531862c52Andreas Huber
2152729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
215617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
215717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
215817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
215917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
216017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2163ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
21642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
21652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
21662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
21672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
21682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
21692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
21702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2171516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2172cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2173cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2174516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2175cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
21762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2177516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2178516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2179516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
21812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2182516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2183516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2184516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
21862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
21872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2188516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2189516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
21902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2191ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2192ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2193ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2194ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2195ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2196ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2197ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
21985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2199ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
220097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
220197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
220297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
220397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
220497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
220597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
220697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
220797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
220897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
22098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
22108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
22118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
22128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
22138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
22148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
22158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
22168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
22178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2219729de186450f78c099637e1fce743fe531862c52Andreas Huber
22204471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
22214471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
22224471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
22234471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
22248b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
22258b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
22268b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
22279806555d3930be43e11106281dee354820ac1c88Andreas Huber
22288b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
22298b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
22308b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
22318b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
22329806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
22339806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
22349806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
22359806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
22369806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
22379806555d3930be43e11106281dee354820ac1c88Andreas Huber
2238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22458b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
22468b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
22478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
22488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2250ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2251ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2252ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2253ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2254ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2255ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2256ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2257ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2258ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2259ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
22604e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2261b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // trigger a kWhatOutputFormatChanged msg on first buffer
2262b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
22634e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2264777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2265777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2266777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2267777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2268777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2269777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2270777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2271777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
22725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // create data converters if needed
22745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!video && err == OK) {
22755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
22765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (encoder) {
22775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
22795b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexInput] != NULL) {
22805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
22815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        } else {
22835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
22855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexOutput] != NULL) {
22865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
22875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
22895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
22905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22948b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
22958b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
22968b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
22978b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22988b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
22998b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
23008b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
23018b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
23028b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
23038b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
23048b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
23058b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
23068b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
23078b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
23088b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
23098b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2310ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2311ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2312ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2313ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2314ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2315ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2316ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2317ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2318ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2319ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2320ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2321ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2322ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2323ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2324ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2325ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2326ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2327ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2328ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2329ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
2330ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2331ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2332ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2333ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2334ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2335ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2336ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2337ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2338870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2339870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2340870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2341870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2342870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    status_t err = mOMX->getConfig(
2343870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2344870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2345870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2346870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2347870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2348870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2349870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2350870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2351870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2352870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2353870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2354870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->getParameter(
2355870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2356870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2357870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2358870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2359870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2360870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2361870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2362870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2363870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2364870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2365870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2366870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2367870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->getParameter(
2368870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2369870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2370870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2371870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2372870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2373870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2374870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2375870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2376870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2377870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2378870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2379870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2380870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2381870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2382870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2383870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2384870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2385870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2386870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    status_t err = mOMX->setConfig(
2387870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2388870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2389870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2390870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2391870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2392870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2393870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2394870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2395870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2396870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2397870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2398870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2399870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2400870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2401870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2402870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2403870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2404870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2405870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2406870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2407870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2408870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2409870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2410870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2411870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2412870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2413870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2414870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = mOMX->getParameter(
2415870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2416870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2417870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2418870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2419870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2420870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2421870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2422870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2423870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2424870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2425870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->setParameter(mNode, OMX_IndexParamVideoIntraRefresh,
2426870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                             &refreshParams, sizeof(refreshParams));
2427870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2428870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2429870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2430870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2431870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2432870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2433870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2466777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2467777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2468777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2469777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
24806e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24936e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
24946e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
24956e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
24966e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
24976e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
24986e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
24996e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2507aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
25088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
25092965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
25102965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2511ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2575aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2577b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2578b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2579b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2580b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2581b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2582b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2583b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2584b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2585b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2586b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2587b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2588b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2589b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2590b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2591b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2592b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2593b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2594b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2595b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2596b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2597b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2598b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2599b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2600b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2601b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2602b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2627ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2628ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2629ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2630ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2631ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2634dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
26358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
26368045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
26378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
26388045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
26398045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
26408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
26412965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
26428045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
26438045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
26448045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
26458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
26468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
26478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
26488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
26498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
26508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
26518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
265497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
265597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
265697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
265797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
265897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
265997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
266097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
266197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
266297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
266397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
266497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
266597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
266697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
266797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
266897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
266997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
267097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
267197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
267297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
267397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
267497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
267597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
267697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
267797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
267897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
267997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
268097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
268197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
268297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
268397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
268497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
268597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
268697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
268797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
268897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
268997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
269097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
269197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
26928a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
26938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
26948a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
26958a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
26968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
26988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
26998a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27008a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27018a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
27028a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
27038a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
27048a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27068a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
27078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
27088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
27098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
27118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
27128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
27138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
27148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
27158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
27178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
27188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27198a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27208a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
27218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
27228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
27248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
27258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
27268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
27278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
27288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
27298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2776729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2777729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2779729de186450f78c099637e1fce743fe531862c52Andreas Huber
2780729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2781729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2782729de186450f78c099637e1fce743fe531862c52Andreas Huber
2783729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2784729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2785729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2786729de186450f78c099637e1fce743fe531862c52Andreas Huber
2787729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2792729de186450f78c099637e1fce743fe531862c52Andreas Huber
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2796729de186450f78c099637e1fce743fe531862c52Andreas Huber
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2801729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2802729de186450f78c099637e1fce743fe531862c52Andreas Huber
280317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2804777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2805777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2806777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2808729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
280917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2810729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2811729de186450f78c099637e1fce743fe531862c52Andreas Huber
28122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
28132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
28142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
28162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
28172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
28182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
28192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
28212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
28222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
28232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
28242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
28252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
28262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
28272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
28282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
28292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
28302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
28312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
28322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
28332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
28352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
28362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
28372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
28382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
28392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2840729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
28415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
2842729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2843729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2844729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2845729de186450f78c099637e1fce743fe531862c52Andreas Huber
2846729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2847729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2848729de186450f78c099637e1fce743fe531862c52Andreas Huber
2849729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2850729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2851729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2852729de186450f78c099637e1fce743fe531862c52Andreas Huber
2853729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2854729de186450f78c099637e1fce743fe531862c52Andreas Huber
2855729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2856729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2857729de186450f78c099637e1fce743fe531862c52Andreas Huber
2858729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2859729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2860729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2861729de186450f78c099637e1fce743fe531862c52Andreas Huber
2862729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2863729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2864729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2865729de186450f78c099637e1fce743fe531862c52Andreas Huber
2866729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2867729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2868729de186450f78c099637e1fce743fe531862c52Andreas Huber
2869729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2870729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2871729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2872729de186450f78c099637e1fce743fe531862c52Andreas Huber
2873729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
28745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    switch (encoding) {
28755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm8bit:
28765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataUnsigned;
28775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 8;
28785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28795b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcmFloat:
28805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataFloat;
28815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 32;
28825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm16bit:
28845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataSigned;
28855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 16;
28865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        default:
28885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            return BAD_VALUE;
28895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
2890729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2891729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2892729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2893729de186450f78c099637e1fce743fe531862c52Andreas Huber
2894c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2895c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2896729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2897729de186450f78c099637e1fce743fe531862c52Andreas Huber
28985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    err = mOMX->setParameter(
2899729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
29005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // if we could not set up raw format to non-16-bit, try with 16-bit
29015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // NOTE: we will also verify this via readback, in case codec ignores these fields
29025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (err != OK && encoding != kAudioEncodingPcm16bit) {
29035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.eNumData = OMX_NumericalDataSigned;
29045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.nBitPerSample = 16;
29055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        err = mOMX->setParameter(
29065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
29075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
29085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return err;
2909729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2910729de186450f78c099637e1fce743fe531862c52Andreas Huber
29115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
291297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
29135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
29145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
29165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
29175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
29185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
29195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
29205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
29215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
29235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
29245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
29255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
29265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
29275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
29285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
29305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
29315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
29350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
29360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29436e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2953229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2954229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
29550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
29560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
29570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
29580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2959229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2960229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2961229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2962229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2963229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29886e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
29896e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
29906e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
29916e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
29926e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
29936e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
30080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
30090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
30100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
30110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
30120d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
30130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
30140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
30150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
30160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
30170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
30180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
30190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
30200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
30210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
30220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
30270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
30280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
30310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
30320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
30330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
30340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
30350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
30360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
30370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
30380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
30390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
30400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
30410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
30420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
30440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
30450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
30470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
30500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
30510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
30520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
30530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
30540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
30550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
30580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
30590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
30600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
30610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
30620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
30630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
30640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
30650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3072e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
3073e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
3074e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3075e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
3076e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
30772472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3078e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
308194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
308294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3083a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3084e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
3085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3088e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3089e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3090e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3091e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3092e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3093e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3094e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3100e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3102e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3103e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3106e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3115e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
31198338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3120b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
312189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
312289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
312389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
312489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
312589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
312689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
314189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
314289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
314389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
314489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
314589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
31460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
314789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
314889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
314989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
31500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
315189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
315289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
31530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
315489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
316078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
316178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
316278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
316378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
316478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
316578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
316678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
316778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
316878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
317078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3183b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3184b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3185b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
31868338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
31878338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3188b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3189b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3190b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3191b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3192b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = mOMX->getExtensionIndex(
3193b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mNode, "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3194b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3195b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3196b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3197b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3198b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
31998338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3200b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3201b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3202b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3203b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mOMX->setConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
3204b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3205b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3206b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3207b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3208b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3209b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3210b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3211b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3212b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3213b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3214b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3215b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3216b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3217b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3218b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "[%s] getting color aspects failed even though codec advertises support",
3219b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
32208338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
32218338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
32228338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3223b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3224b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3225b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
32268338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
32278338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3228b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
32298338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3230b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3231b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3232b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3233b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3234b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3235b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3236b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
32378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
32388338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3239b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
32408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3241b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3242b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3243b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3244b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3245b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3246b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3247b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3248b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mOMX->getConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
32498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3250b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3251b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3252b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3253b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3254b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3255b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3256b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3257b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3258b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3259b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3260b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3261b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3262b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3263b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3264b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3265b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3266b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
32678338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3268b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3269b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3271b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3272b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3273b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3274b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3275b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
32768338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3277b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3278b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3279b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3280b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3281b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3282b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3283b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3284b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3285b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3286b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3294b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
32968338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3297b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3298b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3299b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3300b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3301b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3302b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3303b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3304b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3305b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3306b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3307b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3308b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3309b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3310b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3311b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3312b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3313b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3314b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3315b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3316b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3317b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3318b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3319b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3320b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3321b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3322b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
33238338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3324b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
33258338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3326b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3328b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3329b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3330b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3331b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3333b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
33348338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33358338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3336b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
33378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
33388338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3339b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3340b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3341b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3342b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3343b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3345b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3346b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3347b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3348b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3349b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3350b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3351b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3352b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3353b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3354b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3355b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3356b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3357b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3358b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3360b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3361b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3362b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3363b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3364b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3365b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
33678338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33688338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3369b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3377b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3378b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3379b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3380b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3381b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3382b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3385b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3386b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
33878338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
33888338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3389b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
33908338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
33918338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3392b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3394b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
33978338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3398b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
34008338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3405b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3408b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
34118338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34128338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3414b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3415b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3416b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3417b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3418b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
34198338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3420b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3424b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3425b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3427b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
34288338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34368338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3437b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
34395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
34405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
34455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
34465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
34485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
34495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
34525778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
34535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
34585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
34605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
34615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
34635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
34655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
34675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
34685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
34745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
34755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
34765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
34785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
34815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
34825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
34845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
34855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
34865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
34895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
34915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
34925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
34935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
34965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
34985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
35005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
35015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
35025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
35035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
35062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
35075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
35105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3511a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3512a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3513a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3514a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3515a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
35165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
35225778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
35235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
35375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
35385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
35425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
35565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
35575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
35585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
35595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
35605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
35635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
35675778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
35685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3572870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3573870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3574870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3575870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3576870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3577870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3578870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3579870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3580870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3581870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3582870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
35855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
35905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
35945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3596c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3597c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3598c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3599c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
360089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
360189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
360289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
360389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
360489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
36055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
36065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36098338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
36108338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
36138338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
36148338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
36158338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
36168338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3617d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3618d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3619d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
36250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
36260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
36270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
36280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
36300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
36320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
36330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
36340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
36350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
36380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
36390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
36410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
36420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
36430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
36440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
36470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
36490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
36500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
36530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
36540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
36560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
36570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
36580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
36590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
36600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
36635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
36655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
36665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
36685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
367196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
367296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
367396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
367496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
367596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
367696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
367796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
367896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
367996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
36805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
368796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
368896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
37295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
37325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
37335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
37365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
37385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
37395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
37435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
375296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
37535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
37595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
37655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
37665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
376896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
376996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
37705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
37735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
37775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
37915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
37925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
37945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
37955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
37965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
37985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
38005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
38075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
38105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
38135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
38145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
38175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
38185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
38195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
38205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
38225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
38235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
382896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
38295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3837a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3838a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3839a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3840a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3841a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3842a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3843a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3844a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3845a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3846a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3847a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3848a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3849a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3850a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3851a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3852a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3853a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3854a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3855a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3856a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3857a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3858a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3859a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3860a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3861a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3862a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3863a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3864a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3865a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3866a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3867a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3868a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3869a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3870a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3871a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3872a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3873a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3874a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3875a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3876a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3877a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3878a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3879a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3880a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3881a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3882a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3883a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3884a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3885a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3886a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3887a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3888a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
38895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
38905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
38915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
38925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
389696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
389796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
38985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
38995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
39015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
39025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
39080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
39090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
39100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
39110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
39120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
39130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
39140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
39150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
39160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
39170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
39195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
39235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
39315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
39335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
39345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
39355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
39365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
39425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
39465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
39475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
39505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
39515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
39525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
39535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
39545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
39555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
39565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
39575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
39635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
39665207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
39675207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
39685207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nSliceHeaderSpacing = 0;
39695207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
39705207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nRefFrames = 2;
39715207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nBFrames = 1;
39725207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
39735207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nAllowedPictureTypes =
39745207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
39755207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
39765207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
39775207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
39785207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
39795207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bconstIpred = OMX_TRUE;
39805207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
39815207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
39825207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nCabacInitIdc = 1;
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
39865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
39875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
39915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
39925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
39935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
39945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
39955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
39965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
39985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
39995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
400496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
40055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4007c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
4008c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
4009c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
4010c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
4011c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
4012c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4013c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4014c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
4015c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4016c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
4017c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
4018c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
4019c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
4020c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4021c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4022c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
4023c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4024c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4025c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4026c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4027c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4028c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4029c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4030c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
4031c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4032c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4033c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4034c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4035c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4036c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4037c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4038c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4039c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4040c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4041c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4042c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4043c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
4044c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4045c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4046c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4047c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4048c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4049c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4050c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
40519aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
40529aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
4053c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4054c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
4055c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4056c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4057c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4058c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4059c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4060c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
4061c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4062c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
406389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
406489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
40654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
40664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
40674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
40684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
40694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
40704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
40714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
40724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
40734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
40744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
40754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
407689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
407789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
407889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
40794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
408089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
408189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
408289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
40834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
40844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
40854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
40864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
40874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
40884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
40904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
40914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
40924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
40934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
40944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
40954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
40964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
40974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
40984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
40994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
41004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
41014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
41024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
41034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
41044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
41054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
41074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
41094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
41104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
41114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
41124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
41134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
41144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
41164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
41174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
41184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
41204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
41214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
41224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
41234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
41244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
41254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
41264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
41284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
41294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
41304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
41334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
41344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
41354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
41364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
41374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
41394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
414089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
414189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
414289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
41506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
41555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
41565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
41625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
41635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
41655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
41665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
41686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
41696e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
41706e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
41716e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
41726e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
41735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41746e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
41755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
417796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
417896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
41795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
41815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
41825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
41845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
41855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
41865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
419196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
41925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
41955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
41965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
42005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
42015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
42025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
42035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
42055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
42065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
42105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
42135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
42145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
42155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
42165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
42175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
42195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
42205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
42215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
422578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
422678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4235777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4236777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4237777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4247777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4248777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4249777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4250777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
425878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
425978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
426078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
4271a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4274a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4278d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4279d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4280d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4281d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4282d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4283d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4284d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4285d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4286d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4287d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4288d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4289d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4290d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4291d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
42927e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
42937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
42947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
42967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
42977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
42997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
43007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
43017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
43047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
43057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43067e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
43077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
43087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
43097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4311e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
43127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4313c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4314054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4315054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4316c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
43177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
43197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4327609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
435773dd808754c641fe798273d356ee38368715fa7bLajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormat2Params &params) {
435873dd808754c641fe798273d356ee38368715fa7bLajos Molnar    MediaImage2 &image = params.sMediaImage;
435903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
436003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
436173dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
436203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
436303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
436403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
436503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
436603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
436703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
436803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
436903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
437003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
437103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
43725a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
43732ad160ba086f0504cf56dcc24619a0cee2546a23Dan Stoza        fmt != (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YV12) {
437403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
4375229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
437603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
437703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4378b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
4379b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
4380b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
4381b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
4382b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
4383b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
4384b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
438534e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // we need stride and slice-height to be non-zero and sensible. These values were chosen to
438634e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // prevent integer overflows further down the line, and do not indicate support for
438734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // 32kx32k video.
438834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    if (params.nStride == 0 || params.nSliceHeight == 0
438934e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            || params.nStride > 32768 || params.nSliceHeight > 32768) {
4390b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
4391b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
4392b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
4393b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
4394b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
439503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
439673dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV;
439703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
439803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
439973dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mBitDepthAllocated = 8;
440003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
440103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
440203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
440303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
440403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
440503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
44065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
44075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
44085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
44095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
44105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
44115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
44125a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
44145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
44155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
44165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
44175a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
44185a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
44205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
44215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
44225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
44235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
44245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
44255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
44265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
44275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
44285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
44295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
443103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
443203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
443303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
443403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
443503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
443603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
443703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
443803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
443903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
444003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
444103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
444203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
444303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
444403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
444503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
444603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
444703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
444803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
444903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
445003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
445103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
445203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
445303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
445403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
445503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
445603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
445703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
445803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
445903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
446003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
446103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
446203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
446303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
446403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
446503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
4466229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
4467229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
4468229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4469229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
4470229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
4471229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
447273dd808754c641fe798273d356ee38368715fa7bLajos Molnar        DescribeColorFormat2Params &describeParams)
4473229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
4474229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
4475229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
4476229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
447773dd808754c641fe798273d356ee38368715fa7bLajos Molnar            &describeColorFormatIndex) == OK) {
447873dd808754c641fe798273d356ee38368715fa7bLajos Molnar        DescribeColorFormatParams describeParamsV1(describeParams);
447973dd808754c641fe798273d356ee38368715fa7bLajos Molnar        if (omx->getParameter(
448073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                node, describeColorFormatIndex,
448173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                &describeParamsV1, sizeof(describeParamsV1)) == OK) {
448273dd808754c641fe798273d356ee38368715fa7bLajos Molnar            describeParams.initFromV1(describeParamsV1);
448373dd808754c641fe798273d356ee38368715fa7bLajos Molnar            return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
448473dd808754c641fe798273d356ee38368715fa7bLajos Molnar        }
448573dd808754c641fe798273d356ee38368715fa7bLajos Molnar    } else if (omx->getExtensionIndex(
448673dd808754c641fe798273d356ee38368715fa7bLajos Molnar            node, "OMX.google.android.index.describeColorFormat2", &describeColorFormatIndex) == OK
448773dd808754c641fe798273d356ee38368715fa7bLajos Molnar               && omx->getParameter(
448873dd808754c641fe798273d356ee38368715fa7bLajos Molnar            node, describeColorFormatIndex, &describeParams, sizeof(describeParams)) == OK) {
448973dd808754c641fe798273d356ee38368715fa7bLajos Molnar        return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
449073dd808754c641fe798273d356ee38368715fa7bLajos Molnar    }
449173dd808754c641fe798273d356ee38368715fa7bLajos Molnar
449273dd808754c641fe798273d356ee38368715fa7bLajos Molnar    return describeDefaultColorFormat(describeParams);
4493229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
4494229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4495229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
4496229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
4497229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
44980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
449973dd808754c641fe798273d356ee38368715fa7bLajos Molnar    DescribeColorFormat2Params describeParams;
4500229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
4501229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
4502229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
4503229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
4504229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
4505229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
4506229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
45070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
4508229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4509229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
4510229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4511229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
4512229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
4513229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
4514229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
451573dd808754c641fe798273d356ee38368715fa7bLajos Molnar    const MediaImage2 &img = describeParams.sMediaImage;
451673dd808754c641fe798273d356ee38368715fa7bLajos Molnar    if (img.mType == MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
451773dd808754c641fe798273d356ee38368715fa7bLajos Molnar        if (img.mNumPlanes != 3
451873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                || img.mPlane[img.Y].mHorizSubsampling != 1
451973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                || img.mPlane[img.Y].mVertSubsampling != 1) {
4520229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
4521229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
4522229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4523229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
4524229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
4525229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
4526229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
4527229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
4528229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
4529229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
4530229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
4531229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
4532229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
4533229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
4534229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
4535229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
453603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
453703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4538e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4539777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
454031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
454131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4542e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
454331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4544777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4545777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4546777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4547777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
454831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4549777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4550777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4551777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4552777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
455331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
455431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
455531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
455631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
455731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4558e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4559e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4560e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4561e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4562e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4563e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4564e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4565e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4566e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4567e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
45680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
456973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
45700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
45710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
45720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
45730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
45740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
45750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
45760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
45770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
45780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
45790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
45800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
45810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
45820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
45830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
45845a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
458573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
458673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
458773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
458873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
458973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
459073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
459173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
45920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
459303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
459403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4595b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4596b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4597b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4598b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4599b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4600b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4601b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4602b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4603b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mOMX->getConfig(
4604b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    mNode,
4605b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4606b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4607b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4608b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4609b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4610b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4613b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
461491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4615b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4616b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4617b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4618b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4619b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4621b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4622b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4623b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4624b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
462531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4626b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4627b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4628b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4629b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4630b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4631b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4632b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4633b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4634b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4635b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4636b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4637b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4638b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4639b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4640b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4641b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
4643b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4644b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
4645777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4647e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4648e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
46494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
46504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
46514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
46524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
46534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
46544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
46554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
46564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
46574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
46584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
46594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
46604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
46614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
46624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
46634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
46644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
46654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
46664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
46674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
46684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
46704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
46734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
46754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
46784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
46804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
46834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
46874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
46884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
46894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
46904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
46914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
46924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4693e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4694e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4695777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4696777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4697777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4698777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4699777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4700777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4701777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4702e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4703e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4704e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4705e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4706e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4707e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4709870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4710870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4711870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4712870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4713870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4714e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
471631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4717e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4718e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
47195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
47205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
47215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
47225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
472331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
472431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
472531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
472631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
472731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
472831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
472931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
473097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4735e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4737777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4738777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4739777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4740777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4741777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
474214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4743777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4744777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4745777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
47465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4747777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4748777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
47495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
4750777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4751777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
47565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
47575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
47585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
47595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
47605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
47615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
47625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
47635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
47645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
47655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
47665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
47675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
47685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
47695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
47705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
47715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
4772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
47758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
47778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
47789806555d3930be43e11106281dee354820ac1c88Andreas Huber
4779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4782e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4783e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4785777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4786777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4787777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4788777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4789777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4796e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4801e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
48029806555d3930be43e11106281dee354820ac1c88Andreas Huber
4803777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4804777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4805777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4806777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4807777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
48110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
48140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4821e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4824e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4826777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4827777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4828777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4829777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4830777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4838e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4844777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4845777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4846777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4847777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4848777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4851e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4852e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4853e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4854e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4855e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4856e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4862777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4863777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4864777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4865777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4866777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4870e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4871e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4872e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4873e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
487497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
487597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
487697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
487797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4878e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
487997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4880777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4881777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4882777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4883777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4884777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4885777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
488697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
488797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
488897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
488997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
489097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
489197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4892e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
48938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
48948a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
48958a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
48968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
48978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
48988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4899777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4900777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4901777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4903777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4904777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
49058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49068a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
49078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
49088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
49098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
49108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
49118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49128c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
49138c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
49148c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
49158c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
49168c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
49178c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4918777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4919777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4920777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4921777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4922777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4923777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
49248c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
49258c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
49268c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
49278c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
49288c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
49298c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
49308c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
493110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
493210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
493310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
493410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
493510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
493610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4937777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4938777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4939777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4940777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4941777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
494210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
494310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
494410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
494510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
494610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
494710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
494810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
494910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
495010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
495110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
495210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
495310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
495478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
495510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
495610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
495741d3f579d2c166984958263533284209b90c87d5Marco Nelissen
495841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
495941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
49600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
496141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
496241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
496341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4964777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4965777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4966777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4967777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4968777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
496941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
497041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
497141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
49720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
497341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
497410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
497510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4977777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4978777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4979777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4980e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
498131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
498231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
498331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
498431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4986777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
498731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
498831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4989e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4990e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4991e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4992b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
4993b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
4994b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
4995b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
4996b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4997b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
4998b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
4999b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
5000b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5001b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5002b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
5003b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5004b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5005b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
5006b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5007b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5008b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5009b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5010b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
5011b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5012b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5013b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
5014b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5015b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5016b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
5017b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5018b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5019b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5020b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5021b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
5022b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
5023b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
5024b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5025b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
5026b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
5027b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
5028b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
5029b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
5030b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5031b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::onOutputFormatChanged() {
5032b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // store new output format
5033b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
5034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5035b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5036777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5037777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
5038777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
50405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
50415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
50425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
50435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
50445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
50455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
50465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
50475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
50485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
50495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
50505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
50515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
5052b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
5053b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
5054b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5055b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5056b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5057b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> &notify) {
5058e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
5059b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5060e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5061b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) {
5062b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // notify renderer of the crop change and dataspace change
5063e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
5064b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t left, top, right, bottom;
5065b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
5066b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setRect("crop", left, top, right + 1, bottom + 1);
5067b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5068b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5069b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t dataSpace;
5070b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
5071b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setInt32("dataspace", dataSpace);
5072b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5073b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5074b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5075b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5076b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
5077b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
5078b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5079b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5080b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5081e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
5082b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5083e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
5084e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
5085e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
5086ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5087e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
5088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
5089b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5090e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
5091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5092b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> notify = mNotify->dup();
5093b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
5094b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setMessage("format", mOutputFormat);
509531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
509631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5097b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5098b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
509931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
510031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51015778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5102cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
5103d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
5104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5105251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
5106251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
5107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
5108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
5109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
5110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
5111251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5114346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5115346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
5116346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
51175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
5118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
5119cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
5120cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5121cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5124eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
5125eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5126eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5127496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5128496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5129496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5130496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5131496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5132496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5133496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5134496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5135496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5136496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5137496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5138496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
5139496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
5140496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5141496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5142496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5143496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5144496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5145eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
5146a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        IOMX::buffer_id id, const sp<ABuffer> &buffer,
5147a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
5148eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
5149eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
5150a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mHandles.push_back(handle);
515186b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    mMemRefs.push_back(memRef);
5152eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5153eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5154eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
5155eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
5156eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5157eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5158eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
5159eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
5160eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5161eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5162eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
5163eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
5164eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5165eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5166a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnarsp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
5167a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    return mHandles.itemAt(index);
5168a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar}
5169a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
517086b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wusp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
517186b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    return mMemRefs.itemAt(index);
517286b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu}
517386b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu
5174eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
5175eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5176f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5181ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5182ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
520126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
520226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
520326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
520426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5205e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5206e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5207e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5208e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5209e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5210e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
521326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
52171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
52181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
52191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
52201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
52221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
52231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52242235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
52251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
52271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
52281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
52291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
52301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
52311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
52338f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
52347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
52357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5236251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
52377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
52387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
52397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
52407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5242ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5244251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5245ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
5246ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5247ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5248ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5249ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
525030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
525130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
525230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
525330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
525430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
525530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
525630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
525730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
525830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
525930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
526030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
526130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
526230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
527026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
52715e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
52725e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5273ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
52745e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
52755e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
527626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
52775e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
52785e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
5280609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
5281777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
5282777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
5283777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5284777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
528526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
528626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
528726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
528826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
528926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
529026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
529126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
529226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
529390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
529426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
529526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5296e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5297e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
529890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
529990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
530090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
530190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
530290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
530390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
530490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
530590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
530690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
530790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
530826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
530926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
531026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
531126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
531226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
531326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
531426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53240af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
53250af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
53260af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
53270af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
53280af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
53290af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
53300af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
53310af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
53320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
53330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
53340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
534415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
534515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5346609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
534715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
534915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5355609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
535715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
536415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
537015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
537115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
537490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
537590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
537690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
537790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
537890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
537990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
538090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
538190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
538290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
538390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
538490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5386777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5387777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
539290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
539390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
539490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
539590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
539690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
5400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ColorAspects aspects;
5401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mRange = (ColorAspects::Range)((data2 >> 24) & 0xFF);
5402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mPrimaries = (ColorAspects::Primaries)((data2 >> 16) & 0xFF);
5403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)((data2 >> 8) & 0xFF);
5404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mTransfer = (ColorAspects::Transfer)(data2 & 0xFF);
5405b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5408b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5411ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5417ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5419251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5420251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5421251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5422251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5423251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5424251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5425251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5431ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5432349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5433349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
54340806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
54350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
54360806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
54370806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
54380806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
543915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
544015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
544115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
54420806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
54430806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
544715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
544815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
544915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
545015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
545115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
545215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
545396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
545496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
545596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
545696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
545796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
545896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5459d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5470777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5472777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5473777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
5487d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
5488609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
54912d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
5494609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5505609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
55062d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
55085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5509a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
55105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55112d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
5512a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55157fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
55167fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
55177fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
55187fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
55197fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
55207fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
55217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
55227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
55233831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
55242d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
55285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
55295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
55305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
55315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
55325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
55340806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
55350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
55360806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
55370806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
55380806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
55390806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
55400806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5548dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5549dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5550dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5551dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5559fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5560fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5561fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5562fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5563fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5564fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
55765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
55775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
55785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55795b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (buffer != info->mCodecData) {
5580ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
55835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                         buffer.get(), info->mCodecData.get());
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
55865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (converter == NULL) {
55875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
55885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
55895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
55905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
55915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
55920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
55930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5596078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5597ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5598078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
55995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5600ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
56015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5602078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5604ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5605ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5607ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5608ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5610078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5611349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5619054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5620054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5621054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5622054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5623054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5624054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5625054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5626054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5627054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5628054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
563115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
56320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
56330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode,
56340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    bufferID,
56350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    0,
56365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info->mCodecData->size(),
56370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    flags,
563815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
563915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd);
564015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
56420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
56430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
56440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
56485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
56495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
56500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
56510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
56525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
56535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
56545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
56555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
56570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
56580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5659dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5660dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
56613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5662dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5663dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5665ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5666349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5667349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
566815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
56690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
56700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
56710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
56720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
56730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
56740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
567515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
567615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
567715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
56790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
56800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
56810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5685dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5689625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5690777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5691777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5692777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5693625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5694777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5695625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
573215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
573315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5734609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
57355778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5736349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
57380806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5739d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
57570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
57580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
57590806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
57600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
57610806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
576215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
576315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
576415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
57650806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
57660806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
577290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
577390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
577490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
577590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
577690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
577790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
577890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
577990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
578015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
578115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
578215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
578315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
578415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
578515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
578615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5795a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5796a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5797609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
57985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5799349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
580015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
580115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
58020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
58030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
58050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
58085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
58095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
581031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5811577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
58121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
5813577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5814b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5815b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
5816b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
58175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5818b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5819054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
5820054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
5821054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
5822054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
5823054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (info->mData->size() >= sizeof(grallocMeta)
5824054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
58257c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
5826054219874873b41f1c815552987c10465c34ba2bLajos Molnar                } else if (info->mData->size() >= sizeof(nativeMeta)
5827054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
58287c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
58297c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
58307c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
58317c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
5832054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
58337c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5834054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
5835308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
5836308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5837308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
58385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else if (info->mData == info->mCodecData) {
5839308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
58405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
58415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
58425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
58435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
58445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info->mCodecData, info->mData);
58455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
58465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
58485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
5849308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
5850496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
585121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
5852496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
5853496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
5854496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
58555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
585621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
58598b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
58608b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
58615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5864d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5865609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
58662d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
58675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5869609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
58745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
58755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
58785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
58795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
5881d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
5882dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5890777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
58910806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
58920806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
58930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
58950806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5897777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5898777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5899777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5900777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5908609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
59100806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
59110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
59120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
59130806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
59140806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
59150806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
59160806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
59170806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5919577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
5920777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5921777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5922777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5923577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
5924577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5925b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t dataSpace;
5926b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (msg->findInt32("dataspace", &dataSpace)) {
5927b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = native_window_set_buffers_data_space(
5928b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
5929b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
5930b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5931b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
59346aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
593579ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
59366fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
5937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
593990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
594090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
594190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
594290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
594390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
594490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
594590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
594690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5947fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
5948fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
5949c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
5950fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5951c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
5952fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
5953fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
5954fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
5955fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
59565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
5957fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
59580806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5959fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
596015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
59610806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
596215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
596315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
59640806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
5965cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5966cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
5967264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
5968251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5969cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
597015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
597115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
5972cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
59746fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
59756fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
597615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
597715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
59786fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
59796fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
5993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6009c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
6010609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
6011c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
601215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
601315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(
601415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                            mCodec->mNode, info->mBufferID, info->mFenceFd);
601515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
60160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
60170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
60180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
60190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
6021c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6026777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
60280806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
60290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
60300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6034777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6035777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6036777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6037777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6043f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6047c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
6048c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
6049ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6050ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
605123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mCodec->mNodeBinder->unlinkToDeath(mDeathNotifier);
6052ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
6053ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
6054ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6055b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
6056ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
6057e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
6058ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
6059ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
6060ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
6061ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6062054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
6063054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
60645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
60655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6066ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6069f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
60825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
60835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
60845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
60855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
60865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
60875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6091c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6092c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
609354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
609454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
6095c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6097d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
6098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6101c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6107d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6111c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
611530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
611630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
611730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
611830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
611930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
612030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6132c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
61345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
61355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6136c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
61375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
61385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6139ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
61405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
614248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
614348a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
614448a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
614548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6150ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6151b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
61525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
6156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
61577791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
61585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6159b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6160b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6161b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6162afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
61635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
61645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
61655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
61665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
61675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
61685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
61695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6170b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
61715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
61725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6173b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6174e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
61755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
61761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
61771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6178ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
61791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6180201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
61811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
61821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6183b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6184b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6186da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6187078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6188078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
618923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node);
6190078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
61931065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
61947a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
61957a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
61961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
61971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6198ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
61991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
62001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6201ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
62025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
62039f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
62049f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
62055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
62069f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
62075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6208c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
620952e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6211c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
621323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
621423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    if (mCodec->mNodeBinder == NULL ||
621523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen            mCodec->mNodeBinder->linkToDeath(mDeathNotifier) != OK) {
621623858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // This was a local binder, if it dies so do we, we won't care
621723858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // about any notifications in the afterlife.
621823858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mDeathNotifier.clear();
621923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
622023858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
622126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
622590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6226ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6227ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6228ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6229ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
62301713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
62310167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6232ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6233ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6234afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
6235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
6237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
62395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6240d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
62415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
62425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
62435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6245c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
62485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
62495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6259f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6260f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6261f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6262f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6263f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6264054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6265054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6266a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6267e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6268e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
62694e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
6270054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
627954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6280f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6281f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6285c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
62860806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
6287c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6290c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
629154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
629254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
6293d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
629454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
629554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
629654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6300c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6301c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
63107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
63117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
63127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
63137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
63147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
63157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
63167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
63178f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6318d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
63198f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6320d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6321d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6322d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6323d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6328c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6331c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6332c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6336c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
633754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6340c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6343c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6345c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6347d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
6349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6350c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6355c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6356c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6358c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6359c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6360c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
63625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
63635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
63645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6365ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
63665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
63670806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
63685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
63690806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
63700806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
63710806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
63720806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
63730806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
63745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6375c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6376c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6377c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6378251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6379c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
63805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
63835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6384d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
6385e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
6386e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
63875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
63885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
63915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
63925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6393d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6394d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
6395a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6396d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
6397a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
6398a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
6399a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
6400a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
6401a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
6402a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
6403a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6404a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6405a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6406a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
6407a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
6408a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
6409d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6410a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6411a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6412a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6413d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
641494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
641594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
641694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
641794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
641894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
641994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
642094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
642194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
642294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
642372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
642472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
6425d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
64262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
64272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
64282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6429d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
643037b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
643137b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
643237b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
643337b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
643437b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
643537b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
643637b2b389139ed638831e49708c947863eef631efRonghua Wu
643737b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
643837b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
643937b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
644037b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
6441d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
644237b2b389139ed638831e49708c947863eef631efRonghua Wu        }
644337b2b389139ed638831e49708c947863eef631efRonghua Wu    }
644437b2b389139ed638831e49708c947863eef631efRonghua Wu
6445d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
64462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
64472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
64482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
64492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
64502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
64512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
64522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
64532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
64542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
64552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
64562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
64572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
64582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
64592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
64602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
6461d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
64622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
64632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
646472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6465d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
646672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
646772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
646872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
646972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
647072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
647172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
647272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
647372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
647472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
647572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
647694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
647794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
6478d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
647994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
648094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
648194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6482c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6483c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    if (mCodec->mOMX->getParameter(
6484c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6485c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6486c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6487c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6488c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6489c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6490b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6491b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
6492b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInternalOption(
6493b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, IOMX::INTERNAL_OPTION_COLOR_ASPECTS,
6494b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                colorAspectsBuffer->base(), colorAspectsBuffer->capacity());
6495b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6496b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6497b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6498b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6501d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6502d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6503d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6504d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6505d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6506d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6507d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6508d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6509d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
6510d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
651657fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar
6517d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->createInputSurface(
6520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, dataSpace, &bufferProducer, &mCodec->mInputMetadataType);
6521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6522d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6523d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6524d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6525d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6526d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
65277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
65287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
65297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
65307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
65317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
65327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
65337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
65347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
65357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
65367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
65377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
65387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
65397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
65407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
65418f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
6542d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
65438f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6544d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6545d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6546d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
6547d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6548d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6549d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6550d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6551d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6552b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6553b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6554b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6555b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6556b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
6557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInputSurface(
6560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
6561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                &mCodec->mInputMetadataType);
6562b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6563d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6564d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6565b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        surface->getBufferConsumer()->setDefaultBufferDataSpace(dataSpace);
6566d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6567d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6568d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6569d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
6570d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6571d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6572d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
65738f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6574d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
6575d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
6576d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6577d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
6578d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6579d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
65815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
65825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
65830806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
65840806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
65850806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
65860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
65870806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
65880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6593f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6597f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
65983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6600cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6601cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
660229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6603cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6604cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6605cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6606251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
660791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6608c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        mCodec->mOMX->sendCommand(
6609c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6610c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6611c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6612c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6613c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6614c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6615c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6616c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
661791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6618cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6621f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
6629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6631f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
663372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
66416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
66426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
66436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
66446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
66456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
66466463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
66476463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
66486463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
66496463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
66506463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
66526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
66536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
66546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
66556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
6656d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
66576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
66586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
66596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6666f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
66710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
66720806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
66730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
66740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
66750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
66760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
66770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
66780806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
66810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
66820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
66830806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66850806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
66860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
66870806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
66880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
66890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6701f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6705f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
67063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6709f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
671172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6718d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6719d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6720d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6721d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6722d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6723d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6724d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6725d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6726d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
6727d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6728d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6729d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
6730d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6731d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6732d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6733d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
67346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
67356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
67366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
67376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
67386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
67396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6745f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
67500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
67510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
67520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
67530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
67540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
67550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
67560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
67570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6772f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6773349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6774349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6777f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6778ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6789054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
67934dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
67944dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6795054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
67990806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
68040806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
68050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
68060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
68070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
68080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
68090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
68150806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
68160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
68170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
68180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
68190806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6823349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
682415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
682515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
682615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
68270806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
68280806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
68290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
68300806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
68340806340688c937e7b78c2d89db3809274130df4eLajos Molnar
68350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
68360806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68370806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6841c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6842054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6847f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6848349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
68490806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6850349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6851349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6852349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68553cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6856777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6857777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6858777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6859777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
68603cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
68613cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
68623cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
68633cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
68643cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
68653cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6866349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6867349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6870f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
68713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
687390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
6875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6877f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6883c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6884c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6885c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6886c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6887c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
688854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6889c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6890c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6891349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6892349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
68930806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
68940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
68950806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
68960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
68970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
68990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
69000806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
69020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
69107a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
6911ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
6912d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
6913d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6914d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
6915d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6916d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
6917d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6918349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6919349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
69200806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
69210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
69220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69230806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
69250806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
6932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
6934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6939496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
6940496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
6941496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
6942496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
6943496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
6944496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
6945496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6946496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
6947496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
6948496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
6949496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6950a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
6951a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
6952a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
6953a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
6954a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6955a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
6956a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6957a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
6958a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
6959a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
6960a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
6961a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
6962a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6963a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
6964a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
6965a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6966a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
69677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
69687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
69696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
69707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
69717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
69727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
69737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
69744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6975054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
69764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
69774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
69784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
6979054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
69804dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
6981054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
69824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
69834dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
69844dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
69854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
69864dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6995a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
6996a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
6997530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
6998a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6999a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
7000a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
7001a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
7002a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7003a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
7004a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
7005a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
7006a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
7007a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
7008a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7009a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
7010a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7011a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
7012a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7013a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
7014a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7015a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
7016a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
701772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
701872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
701972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
702072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
702172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
702272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
702372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
702472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
702572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
702672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
702772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
702872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
702972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
703072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
703172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
703272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7033e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
7034e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
7035e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
7036e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
7037b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
7038b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
7039e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
7040e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
7041e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
7042e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
7043b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
7044b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7045b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7046b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7047b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7048b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7049b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
7050b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7051b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7052b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7053b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7054b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7055b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7056b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7057b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7058b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7059e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7060e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
70618db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
70628db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
70638db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
70648db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
70658db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
70668db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
70678db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
70688db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
70698db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7070870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7071870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7072870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7073870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7074870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7075870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7076870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7077870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7078870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7079870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7080870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
7081a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
7082a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7083a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
70846507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
70856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
7086d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
70876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
70886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
70896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
70906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
70916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
70926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
70936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
70946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
709590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
709690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
709790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
709890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
709990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7100f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7107b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7108b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
710931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7110054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
7112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
7113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7116349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7119b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7120b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7121ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7140f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7145f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7156f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7164e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7166349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
71673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7168349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7169349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7183f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
71843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
718890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
718990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
719090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
719190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
719290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
719390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
72000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
72010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
72020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
72030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
72080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
72090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
72100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
72110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
72120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
72130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
72140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
72170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
72180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
72190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
72220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
72230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
72240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
72250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7226cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
72270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7228251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7229d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7230755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7231755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7232755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7233755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7234755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7235755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7236755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7237755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7238cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7242777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7243777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7244777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7245777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7249349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7250349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7251349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7252349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7268f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
72695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
72705778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
72810806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7301f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
73023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
730331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
73045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7305b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7308f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
73130806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
73140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
73150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
73160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
73170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
73180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
73200806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
73235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7329349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7330349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7331349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7334349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7335349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
73400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7341f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
73425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
73430806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
73440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
73450806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
73460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
73470806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
73480806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
73490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
73500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
73510806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73530167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
73540167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7355bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7356bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7357bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7358bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7359b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7360bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7361bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
73620806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
73630806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
73650806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
73660806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7371f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7378f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7387f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7391f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
74070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7419f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
74203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7423f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
74280806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
74290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
74300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
74310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
74320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
74330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
74340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
74350806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7437c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7449f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7453f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
74543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7459f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7484f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
7485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7486ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
7487ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
7488d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
74920806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
74930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
74940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
74950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
74960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
74970806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
7500777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
7501777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
7502777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
7503777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
7504777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
7506e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
75070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
7508e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
7509e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
7510777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
7511777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
7512777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
7513777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
7514777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
7515777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7516777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
7519777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
7520777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
7521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7526349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
75281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
7529349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
7530609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
7531349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
7532349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
7533349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
7534349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
75353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
7536349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
7537349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7538349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
7539349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7540349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7541349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7542349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
7548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7550f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
7551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7556f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
7557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7562f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
7563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
7564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
7565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
75667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
75677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
75687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
75697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
757090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
757190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
7573d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
7574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
7575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
7577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
7578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7579dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
7580dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
7581f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
7582f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
7583f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
7584f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
7585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
7586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
75905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
75915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
75925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
75935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    const char *role = getComponentRole(isEncoder, mime.c_str());
75945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
75955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
75965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
75975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
75995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = client.connect();
76005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
76055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
76065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    IOMX::node_id node = 0;
76075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
760823858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    err = omx->allocateNode(name.c_str(), observer, NULL, &node);
76095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
76115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    err = setComponentRole(omx, node, role);
76155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        omx->freeNode(node);
76175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
76185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
76225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
76235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
76255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
76265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
76275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
76285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76296e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76306e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
76315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
76335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
76345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
76386e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
76396e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
76406e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
76416e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
76426e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
76436e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
76445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
76475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
76485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
76495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
76505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
765136e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
76525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
76536e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76546e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
76555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoPortFormat,
76575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
76585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
76635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (isFlexibleColorFormat(
76645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    omx, node, portFormat.eColorFormat, false /* usingNativeWindow */,
76655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
76665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
76675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
76685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
76695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
76705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
76715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
76725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
76735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
76745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
76755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
76765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
76775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
76795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
76806e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
76816e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
76826e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
76836e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
76846e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
76856e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
76865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
76885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
76895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
76905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
76915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
76926e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76936e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
76945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
76965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
76975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
77005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
77015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
77026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
77036e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
77046e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
77056e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
77066e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
77076e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
77085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
77115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
77125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
77135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
77145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
77185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
77195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->configureVideoTunnelMode(
77205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
77215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
77225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
77235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
77245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        } else if (omx->storeMetaDataInBuffers(
77255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE) == OK ||
77265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            omx->prepareForAdaptivePlayback(
77275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE,
77285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
77295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
77305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
77345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
77355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
77365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
77375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
77385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->getConfig(
77395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
77405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
77415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
77425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
77465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    omx->freeNode(node);
77475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
77485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
77495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
77505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7751a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
7752a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
7753a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
7754a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
7755a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
7756a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
7757a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
7758a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7759a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
7760a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7761a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7762a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7763a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
7764a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7765a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7766a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7767a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7768a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
7769a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7770a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7771a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
7772a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
7773a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7774a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
7775a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7776a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7777a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7778a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
7779a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
7780a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7781a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
7782a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7783a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7784a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7785a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7786a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7787a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7788a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7789a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
7790a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7791a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7792a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7793a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7794a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7795a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7796a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
7797a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7798a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
7799a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7800a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7801a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7802a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7803a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7804a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7805a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
7806a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
7807a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7808a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
7809a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
7810a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
7811a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7812a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
7813a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
7814a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
7816