ACodec.cpp revision 598c14420eefb2df4b50d9dd55bbf99bbc35e95e
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) {
724598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa            ALOGV("skipping buffer");
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
2260697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
22614e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2262b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // trigger a kWhatOutputFormatChanged msg on first buffer
2263b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
22644e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2265777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2266777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2267777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2268777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2269777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2270777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2271777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2272777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
22735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // create data converters if needed
22755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!video && err == OK) {
22765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
22775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (encoder) {
22785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22795b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
22805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexInput] != NULL) {
22815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
22825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        } else {
22845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
22865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexOutput] != NULL) {
22875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
22885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
22905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
22915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22958b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
22968b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
22978b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
22988b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22998b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
23008b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
23018b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
23028b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
23038b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
23048b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
23058b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
23068b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
23078b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
23088b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
23098b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
23108b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2311ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2312ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2313ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2314ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2315ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2316ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2317ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2318ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2319ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2320ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2321ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2322ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2323ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2324ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2325ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2326ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2327ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2328ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2329ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2330ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
2331ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2332ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2333ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2334ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2335ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2336ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2337ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2338ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2339870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2340870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2341870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2342870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2343870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    status_t err = mOMX->getConfig(
2344870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2345870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2346870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2347870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2348870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2349870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2350870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2351870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2352870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2353870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2354870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2355870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->getParameter(
2356870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2357870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2358870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2359870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2360870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2361870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2362870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2363870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2364870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2365870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2366870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2367870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2368870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->getParameter(
2369870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2370870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2371870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2372870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2373870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2374870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2375870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2376870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2377870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2378870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2379870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2380870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2381870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2382870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2383870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2384870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2385870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2386870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2387870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    status_t err = mOMX->setConfig(
2388870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2389870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2390870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2391870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2392870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2393870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2394870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2395870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2396870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2397870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2398870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2399870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2400870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2401870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2402870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2403870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2404870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2405870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2406870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2407870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2408870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2409870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2410870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2411870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2412870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2413870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2414870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2415870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = mOMX->getParameter(
2416870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2417870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2418870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2419870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2420870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2421870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2422870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2423870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2424870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2425870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2426870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->setParameter(mNode, OMX_IndexParamVideoIntraRefresh,
2427870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                             &refreshParams, sizeof(refreshParams));
2428870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2429870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2430870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2431870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2432870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2433870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2434870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2467777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2468777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2469777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2470777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
24816e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24946e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
24956e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
24966e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
24976e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
24986e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
24996e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
25006e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2508aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
25098045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
25102965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
25112965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2576aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2578b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2579b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2580b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2581b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2582b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2583b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2584b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2585b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2586b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2587b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2588b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2589b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2590b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2591b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2592b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2593b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2594b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2595b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2596b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2597b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2598b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2599b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2600b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2601b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2602b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2603b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2628ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2629ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2630ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2631ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2632ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26348045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2635dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
26368045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
26378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
26388045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
26398045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
26408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
26418045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
26422965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
26438045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
26448045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
26458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
26468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
26478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
26488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
26498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
26508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
26518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
26528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
265597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
265697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
265797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
265897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
265997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
266097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
266197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
266297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
266397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
266497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
266597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
266697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
266797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
266897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
266997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
267097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
267197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
267297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
267397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
267497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
267597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
267697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
267797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
267897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
267997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
268097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
268197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
268297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
268397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
268497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
268597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
268697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
268797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
268897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
268997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
269097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
269197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
269297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
26938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
26948a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
26958a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
26968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
26978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
26998a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
27008a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27018a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27028a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
27038a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
27048a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
27058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27068a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
27088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
27098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
27108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
27128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
27138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
27148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
27158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
27168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
27188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
27198a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27208a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
27228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
27238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
27258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
27268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
27278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
27288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
27298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
27308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2777729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2778729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2780729de186450f78c099637e1fce743fe531862c52Andreas Huber
2781729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2782729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2783729de186450f78c099637e1fce743fe531862c52Andreas Huber
2784729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2785729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2786729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2787729de186450f78c099637e1fce743fe531862c52Andreas Huber
2788729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2793729de186450f78c099637e1fce743fe531862c52Andreas Huber
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2797729de186450f78c099637e1fce743fe531862c52Andreas Huber
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2802729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2803729de186450f78c099637e1fce743fe531862c52Andreas Huber
280417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2805777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2806777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2807777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2809729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
281017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2811729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2812729de186450f78c099637e1fce743fe531862c52Andreas Huber
28132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
28142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
28152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
28172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
28182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
28192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
28202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
28222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
28232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
28242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
28252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
28262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
28272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
28282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
28292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
28302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
28312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
28322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
28332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
28342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
28362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
28372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
28382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
28392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
28402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2841729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
28425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
2843729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2844729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2845729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2846729de186450f78c099637e1fce743fe531862c52Andreas Huber
2847729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2848729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2849729de186450f78c099637e1fce743fe531862c52Andreas Huber
2850729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2851729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2852729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2853729de186450f78c099637e1fce743fe531862c52Andreas Huber
2854729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2855729de186450f78c099637e1fce743fe531862c52Andreas Huber
2856729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2857729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2858729de186450f78c099637e1fce743fe531862c52Andreas Huber
2859729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2860729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2861729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2862729de186450f78c099637e1fce743fe531862c52Andreas Huber
2863729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2864729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2865729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2866729de186450f78c099637e1fce743fe531862c52Andreas Huber
2867729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2868729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2869729de186450f78c099637e1fce743fe531862c52Andreas Huber
2870729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2871729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2872729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2873729de186450f78c099637e1fce743fe531862c52Andreas Huber
2874729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
28755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    switch (encoding) {
28765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm8bit:
28775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataUnsigned;
28785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 8;
28795b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcmFloat:
28815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataFloat;
28825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 32;
28835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm16bit:
28855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataSigned;
28865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 16;
28875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        default:
28895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            return BAD_VALUE;
28905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
2891729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2892729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2893729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2894729de186450f78c099637e1fce743fe531862c52Andreas Huber
2895c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2896c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2897729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2898729de186450f78c099637e1fce743fe531862c52Andreas Huber
28995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    err = mOMX->setParameter(
2900729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
29015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // if we could not set up raw format to non-16-bit, try with 16-bit
29025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // NOTE: we will also verify this via readback, in case codec ignores these fields
29035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (err != OK && encoding != kAudioEncodingPcm16bit) {
29045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.eNumData = OMX_NumericalDataSigned;
29055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.nBitPerSample = 16;
29065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        err = mOMX->setParameter(
29075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
29085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
29095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return err;
2910729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2911729de186450f78c099637e1fce743fe531862c52Andreas Huber
29125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
291397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
29145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
29155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
29175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
29185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
29195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
29205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
29215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
29225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
29245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
29255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
29265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
29275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
29285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
29295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
29315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
29325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
29360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
29370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29446e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2954229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2955229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
29560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
29570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
29580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
29590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2960229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2961229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2962229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2963229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2964229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29896e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
29906e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
29916e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
29926e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
29936e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
29946e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
30090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
30100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
30110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
30120d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
30130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
30140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
30150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
30160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
30170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
30180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
30190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
30200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
30210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
30220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
30230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
30280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
30290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
30320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
30330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
30340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
30350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
30360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
30370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
30380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
30390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
30400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
30410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
30420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
30430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
30450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
30460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
30480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
30510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
30520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
30530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
30540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
30550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
30560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
30590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
30600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
30610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
30620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
30630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
30640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
30650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
30660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3073e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
3074e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
3075e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3076e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
3077e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
30782472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3081e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
308294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
308394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3084a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
3086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3089e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3090e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3091e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3092e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3093e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3094e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3095e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3100e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3102e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3103e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3106e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3115e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3116e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
31208338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3121b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
312289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
312389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
312489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
312589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
312689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
312789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
314289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
314389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
314489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
314589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
314689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
31470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
314889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
314989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
315089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
31510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
315289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
315389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
31540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
315589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
316178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
316278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
316378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
316478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
316578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
316678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
316778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
316878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
316978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
317178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3184b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3185b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3186b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
31878338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
31888338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3189b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3190b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3191b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3192b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3193b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = mOMX->getExtensionIndex(
3194b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mNode, "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3195b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3196b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3197b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3198b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3199b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
32008338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3201b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3202b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3203b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3204b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mOMX->setConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
3205b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3206b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3207b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3208b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3209b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3210b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3211b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3212b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3213b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3214b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3215b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3216b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3217b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3218b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3219b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "[%s] getting color aspects failed even though codec advertises support",
3220b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
32218338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
32228338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
32238338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3224b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3225b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3226b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
32278338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
32288338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3229b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
32308338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3231b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3232b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3233b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3234b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3235b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3236b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3237b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
32388338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
32398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3240b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
32418338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3242b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3243b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3244b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3245b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3246b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3247b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3248b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3249b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mOMX->getConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
32508338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3251b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3252b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3253b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3254b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3255b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3256b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3257b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3258b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3259b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3260b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3261b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3262b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3263b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3264b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3265b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3266b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3267b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
32688338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3269b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3271b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3272b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3273b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3274b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3275b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3276b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
32778338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3278b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3279b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3280b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3281b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3282b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3283b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3284b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3285b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3286b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3294b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
32978338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3298b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3299b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3300b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3301b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3302b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3303b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3304b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3305b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3306b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3307b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3308b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3309b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3310b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3311b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3312b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3313b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3314b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3315b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3316b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3317b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3318b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3319b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3320b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3321b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3322b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3323b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
33248338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3325b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
33268338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3328b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3329b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3330b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3331b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3333b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3334b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
33358338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33368338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3337b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
33388338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
33398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3340b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3341b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3342b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3343b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3345b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3346b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3347b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3348b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3349b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3350b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3351b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3352b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3353b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3354b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3355b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3356b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3357b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3358b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3360b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3361b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3362b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3363b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3364b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3365b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3367b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
33688338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33698338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3377b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3378b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3379b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3380b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3381b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3382b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3385b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3386b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
33888338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
33898338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3390b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
33918338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
33928338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3394b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
33988338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
34018338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3405b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3408b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3411b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
34128338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34138338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3414b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3415b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3416b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3417b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3418b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3419b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
34208338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3424b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3425b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3427b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
34298338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3434b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3439b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
34405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
34465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
34475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
34495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
34505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
34535778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
34545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
34595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
34615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
34625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
34645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
34665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
34685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
34695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
34755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
34765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
34785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
34795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
34825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
34835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
34855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
34865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
34875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
34905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
34925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
34935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
34945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
34975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
34995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
35015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
35025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
35035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
35055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
35072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
35085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
35115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3512a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3513a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3514a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3515a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3516a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
35175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
35235778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
35295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
35385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
35425778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
35435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
35575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
35585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
35595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
35605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
35625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
35685778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
35695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3573870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3574870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3575870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3576870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3577870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3578870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3579870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3580870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3581870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3582870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3583870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
35855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
35875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
35905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
35945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3597c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3598c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3599c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3600c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
360189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
360289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
360389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
360489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
360589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
36065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36108338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
36118338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3613b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
36148338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
36158338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
36168338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
36178338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3618d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3619d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3620d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
36260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
36270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
36280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
36290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
36310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
36330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
36340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
36350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
36360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
36390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
36400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
36420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
36430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
36440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
36450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
36480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
36500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
36510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
36520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
36530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
36540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
36550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
36570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
36580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
36590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
36600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
36610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
36635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
36655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
36665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
36705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
367296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
367396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
367496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
367596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
367696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
367796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
367896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
367996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
368096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
368896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
368996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
37325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
37335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
37345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
37375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
37395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
37405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
37435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
37485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
375396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
37545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
37655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
37665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
37675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
376996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
377096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
37735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
37765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
37865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
37925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
37935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
37955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
37965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
37975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
37995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
38105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
38115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
38145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
38185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
38195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
38205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
38215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
38235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
38245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
382996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
38305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3838a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3839a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3840a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3841a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3842a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3843a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3844a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3845a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3846a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3847a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3848a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3849a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3850a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3851a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3852a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3853a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3854a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3855a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3856a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3857a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3858a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3859a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3860a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3861a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3862a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3863a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3864a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3865a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3866a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3867a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3868a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3869a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3870a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3871a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3872a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3873a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3874a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3875a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3876a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3877a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3878a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3879a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3880a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3881a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3882a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3883a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3884a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3885a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3886a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3887a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3888a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3889a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
38905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
38915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
38925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
389796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
389896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
38995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
39015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
39025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
39035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
39090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
39100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
39110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
39120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
39130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
39140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
39150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
39160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
39170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
39180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
39225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
39315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
39325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
39345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
39355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
39365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
39375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
39415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
39445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
39475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
3948e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else {
3949e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        // Use baseline profile for AVC recording if profile is not specified.
39508eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
39518eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    }
39528eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang
3953e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
3954e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            asString(h264type.eProfile), asString(h264type.eLevel));
3955e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang
39565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
39575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
39585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
39635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
39705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
3973e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
3974e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
3975e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nSliceHeaderSpacing = 0;
3976e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
3977e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefFrames = 2;
3978e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nBFrames = 1;
3979e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3980e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nAllowedPictureTypes =
3981e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
3982e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
3983e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
3984e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
3985e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
3986e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bconstIpred = OMX_TRUE;
3987e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
3988e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
3989e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nCabacInitIdc = 1;
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
39935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
39945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
39975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
39985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
39995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
40005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
40015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
40025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
40035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
40055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
40065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
401196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
40125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4014c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
4015c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
4016c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
4017c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
4018c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
4019c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4020c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4021c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
4022c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4023c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
4024c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
4025c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
4026c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
4027c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4028c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4029c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
4030c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4031c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4032c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4033c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4034c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4035c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4036c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4037c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
4038c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4039c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4040c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4041c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4042c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4043c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4044c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4045c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4046c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4047c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4048c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4049c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4050c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
4051c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4052c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4053c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4054c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4055c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4056c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4057c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
40589aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
40599aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
4060c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4061c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
4062c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4063c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4064c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4065c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4066c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4067c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
4068c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4069c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
407089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
407189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
40724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
40734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
40744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
40754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
40764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
40774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
40784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
40794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
40804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
40814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
40824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
408389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
408489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
408589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
40864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
408789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
408889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
408989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
40904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
40914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
40924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
40934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
40944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
40954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
40974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
40984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
40994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
41004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
41014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
41024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
41034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
41044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
41054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
41064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
41074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
41084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
41094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
41104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
41114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
41124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
41144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
41164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
41174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
41184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
41194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
41204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
41214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
41234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
41244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
41254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
41274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
41284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
41294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
41304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
41314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
41324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
41334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
41354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
41364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
41374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
41404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
41414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
41424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
41434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
41444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
41464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
414789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
414889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
414989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
41505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
41555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41566e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
41576e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
41605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
41615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
41625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
41635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
41655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
41665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
41695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
41705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
41725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
41735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41746e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
41756e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
41766e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
41776e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
41786e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
41796e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41816e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
41825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
418496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
418596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
41865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
41875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
41885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
41895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
41915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
41925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
419896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
41995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
42005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
42025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
42035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
42095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
42105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
42125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
42135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
42145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
42175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
42205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
42215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
42225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
42235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
42245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
42265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
42275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
42285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
423278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
423378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4242777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4243777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4244777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4254777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4255777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4256777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4257777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
426578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
426678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
426778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
4278a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4281a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4285d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4286d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4287d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4288d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4289d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4290d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4291d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4292d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4293d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4294d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4295d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4296d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4297d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4298d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
42997e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
43007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
43017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
43037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
43047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
43067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
43077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
43087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
43117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
43127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
43137e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
43147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
43157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
43167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4318e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
43197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4320c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4321054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4322054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4323c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
43247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
43267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4334609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
436303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
436473dd808754c641fe798273d356ee38368715fa7bLajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormat2Params &params) {
436573dd808754c641fe798273d356ee38368715fa7bLajos Molnar    MediaImage2 &image = params.sMediaImage;
436603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
436703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
436873dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
436903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
437003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
437103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
437203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
437303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
437403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
437503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
437603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
437703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
437803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
43795a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
43802ad160ba086f0504cf56dcc24619a0cee2546a23Dan Stoza        fmt != (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YV12) {
438103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
4382229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
438303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
438403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4385b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
4386b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
4387b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
4388b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
4389b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
4390b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
4391b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
439234e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // we need stride and slice-height to be non-zero and sensible. These values were chosen to
439334e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // prevent integer overflows further down the line, and do not indicate support for
439434e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // 32kx32k video.
439534e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    if (params.nStride == 0 || params.nSliceHeight == 0
439634e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            || params.nStride > 32768 || params.nSliceHeight > 32768) {
4397b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
4398b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
4399b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
4400b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
4401b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
440203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
440373dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV;
440403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
440503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
440673dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mBitDepthAllocated = 8;
440703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
440803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
440903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
441003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
441103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
441203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
44135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
44145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
44155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
44165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
44175a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
44185a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
44195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
44215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
44225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
44235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
44245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
44255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
44275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
44285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
44295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
44305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
44315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
44325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
44335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
44345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
44355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
44365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
443803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
443903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
444003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
444103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
444203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
444303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
444403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
444503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
444603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
444703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
444803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
444903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
445003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
445103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
445203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
445303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
445403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
445503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
445603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
445703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
445803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
445903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
446003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
446103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
446203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
446303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
446403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
446503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
446603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
446703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
446803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
446903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
447003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
447103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
447203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
4473229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
4474229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
4475229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4476229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
4477229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
4478229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
447973dd808754c641fe798273d356ee38368715fa7bLajos Molnar        DescribeColorFormat2Params &describeParams)
4480229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
4481229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
4482229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
4483229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
448473dd808754c641fe798273d356ee38368715fa7bLajos Molnar            &describeColorFormatIndex) == OK) {
448573dd808754c641fe798273d356ee38368715fa7bLajos Molnar        DescribeColorFormatParams describeParamsV1(describeParams);
448673dd808754c641fe798273d356ee38368715fa7bLajos Molnar        if (omx->getParameter(
448773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                node, describeColorFormatIndex,
448873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                &describeParamsV1, sizeof(describeParamsV1)) == OK) {
448973dd808754c641fe798273d356ee38368715fa7bLajos Molnar            describeParams.initFromV1(describeParamsV1);
449073dd808754c641fe798273d356ee38368715fa7bLajos Molnar            return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
449173dd808754c641fe798273d356ee38368715fa7bLajos Molnar        }
449273dd808754c641fe798273d356ee38368715fa7bLajos Molnar    } else if (omx->getExtensionIndex(
449373dd808754c641fe798273d356ee38368715fa7bLajos Molnar            node, "OMX.google.android.index.describeColorFormat2", &describeColorFormatIndex) == OK
449473dd808754c641fe798273d356ee38368715fa7bLajos Molnar               && omx->getParameter(
449573dd808754c641fe798273d356ee38368715fa7bLajos Molnar            node, describeColorFormatIndex, &describeParams, sizeof(describeParams)) == OK) {
449673dd808754c641fe798273d356ee38368715fa7bLajos Molnar        return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
449773dd808754c641fe798273d356ee38368715fa7bLajos Molnar    }
449873dd808754c641fe798273d356ee38368715fa7bLajos Molnar
449973dd808754c641fe798273d356ee38368715fa7bLajos Molnar    return describeDefaultColorFormat(describeParams);
4500229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
4501229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4502229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
4503229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
4504229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
45050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
450673dd808754c641fe798273d356ee38368715fa7bLajos Molnar    DescribeColorFormat2Params describeParams;
4507229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
4508229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
4509229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
4510229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
4511229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
4512229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
4513229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
45140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
4515229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4516229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
4517229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4518229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
4519229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
4520229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
4521229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
452273dd808754c641fe798273d356ee38368715fa7bLajos Molnar    const MediaImage2 &img = describeParams.sMediaImage;
452373dd808754c641fe798273d356ee38368715fa7bLajos Molnar    if (img.mType == MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
452473dd808754c641fe798273d356ee38368715fa7bLajos Molnar        if (img.mNumPlanes != 3
452573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                || img.mPlane[img.Y].mHorizSubsampling != 1
452673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                || img.mPlane[img.Y].mVertSubsampling != 1) {
4527229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
4528229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
4529229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4530229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
4531229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
4532229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
4533229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
4534229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
4535229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
4536229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
4537229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
4538229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
4539229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
4540229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
4541229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
4542229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
454303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
454403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4545e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4546777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
454731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
454831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
455031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4551777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4552777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4553777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4554777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
455531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4556777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4557777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4558777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4559777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
456031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
456131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
456231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
456331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
456431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4565e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4566e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4567e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4568e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4569e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4570e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4571e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4572e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4573e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4574e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
45750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
457673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
45770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
45780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
45790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
45800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
45810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
45820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
45830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
45840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
45850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
45860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
45870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
45880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
45890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
45900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
45915a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
459273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
459373dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
459473dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
459573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
459673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
459773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
459873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
45990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
460003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
460103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4602b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4603b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4604b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4605b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4606b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4607b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4608b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4609b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4610b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mOMX->getConfig(
4611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    mNode,
4612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4613b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4614b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4615b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4616b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4617b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4618b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4619b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
462191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4622b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4623b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4624b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4625b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4626b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4627b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4628b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4629b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4630b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4631b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
463231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4633b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4634b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4635b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4636b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4637b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4638b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4639b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4640b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4641b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4643b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4644b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4645b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4646b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4647b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4648b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4649b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
4650b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4651b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
4652777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4654e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4655e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
46564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
46574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
46584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
46594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
46604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
46614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
46624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
46634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
46644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
46654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
46664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
46674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
46684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
46694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
46704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
46714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
46724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
46734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
46744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
46754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
46774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
46804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
46824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
46854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
46874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
46904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
46944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
46954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
46964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
46974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
46984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
46994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4700e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4702777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4703777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4704777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4705777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4706777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4708777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4710e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4714e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4715e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4716870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4717870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4718870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4719870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4720870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
472331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
47265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
47275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
47285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
47295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
473031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
473131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
473231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
473331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
473431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
473531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
473631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
473797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4744777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4745777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4746777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4747777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4748777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
474914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4750777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4751777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4752777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
47535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4754777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4755777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
47565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
4757777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4758777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
47635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
47645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
47655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
47665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
47675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
47685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
47695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
47705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
47715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
47725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
47735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
47745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
47755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
47765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
47775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
47785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
4779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
47828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
47848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
47859806555d3930be43e11106281dee354820ac1c88Andreas Huber
4786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4790e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4792777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4793777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4794777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4795777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4796777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
48099806555d3930be43e11106281dee354820ac1c88Andreas Huber
4810777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4811777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4812777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4813777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4814777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
48180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
48210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4831e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4833777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4834777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4835777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4836777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4837777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4851777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4852777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4853777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4854777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4855777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4856e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4865e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4869777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4870777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4871777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4872777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4873777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4874e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4875e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4876e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4878e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4879e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4880e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
488197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
488297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
488397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
488497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
488697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4887777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4888777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4889777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4890777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4891777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4892777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
489397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
489497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
489597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
489697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
489797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
489897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4899e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
49008a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
49018a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
49028a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
49038a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
49048a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
49058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4906777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4907777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4908777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4911777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
49128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
49148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
49158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
49168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
49178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
49188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49198c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
49208c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
49218c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
49228c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
49238c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
49248c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4925777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4926777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4927777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4928777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4929777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
49318c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
49328c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
49338c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
49348c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
49358c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
49368c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
49378c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
493810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
493910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
494010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
494110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
494210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
494310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4944777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4945777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4948777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
494910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
495010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
495110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
495210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
495310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
495410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
495510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
495610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
495710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
495810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
495910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
496010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
496178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
496210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
496310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
496441d3f579d2c166984958263533284209b90c87d5Marco Nelissen
496541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
496641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
49670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
496841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
496941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
497041d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4971777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4972777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4973777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4974777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4975777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
497641d3f579d2c166984958263533284209b90c87d5Marco Nelissen
497741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
497841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
49790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
498041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
498110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
498210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4986777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4987e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
498831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
498931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
499031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
499131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4992777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4993777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
499431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
499531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4996e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4997e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4998e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4999b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
5000b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
5001b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
5002b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
5003b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5004b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
5005b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5006b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
5007b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5008b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5009b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
5010b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5011b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5012b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
5013b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5014b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5015b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5016b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5017b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
5018b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5019b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5020b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
5021b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5022b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5023b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
5024b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5025b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5026b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5027b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5028b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
5029b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
5030b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
5031b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5032b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
5033b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
5034b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
5035b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
5036b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
5037b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
50381734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5039697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // store new output format, at the same time mark that this is no longer the first frame
5040b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
5041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5042b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5043777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5044777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
5045777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5046e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
50471734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    if (expectedFormat != NULL) {
50481734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
50491734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
50501734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        if (changes->countEntries() != 0 || to->countEntries() != 0) {
50511734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
50521734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mComponentName.c_str(),
50531734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    changes->debugString(4).c_str(), to->debugString(4).c_str());
50541734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        }
50551734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    }
50561734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar
50575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
50585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
50595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
50605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
50615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
50625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
50635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
50645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
50655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
50665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
50675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
50685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
5069b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
5070b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
5071b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5072b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5073b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5074b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> &notify) {
5075e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
5076b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5077e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5078b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) {
5079b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // notify renderer of the crop change and dataspace change
5080e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
5081b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t left, top, right, bottom;
5082b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
5083b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setRect("crop", left, top, right + 1, bottom + 1);
5084b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5085b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5086b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t dataSpace;
5087b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
5088b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setInt32("dataspace", dataSpace);
5089b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5090b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5091b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5092b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5093b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
5094b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
5095b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5096b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5097b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5098e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
5099b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5100e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
5101e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
5102e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
5103ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5104e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
5105e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
5106b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5107e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
5108e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5109b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> notify = mNotify->dup();
5110b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
5111b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setMessage("format", mOutputFormat);
511231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
511331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5114b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5115b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
511631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
511731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51185778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5119cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
5120d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
5121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
5123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
5124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
5125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
5126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
5127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
5128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5131346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5132346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
5133346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
51345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
5135251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
5136cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
5137cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5138cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5141eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
5142eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5143eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5144496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5145496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5146496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5147496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5148496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5149496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5150496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5151496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5152496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5153496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5154496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5155496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
5156496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
5157496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5158496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5159496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5161496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5162eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
5163a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        IOMX::buffer_id id, const sp<ABuffer> &buffer,
5164a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
5165eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
5166eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
5167a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mHandles.push_back(handle);
516886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    mMemRefs.push_back(memRef);
5169eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5170eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5171eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
5172eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
5173eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5174eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5175eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
5176eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
5177eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5178eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5179eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
5180eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
5181eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5182eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5183a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnarsp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
5184a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    return mHandles.itemAt(index);
5185a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar}
5186a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
518786b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wusp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
518886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    return mMemRefs.itemAt(index);
518986b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu}
519086b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu
5191eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
5192eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5193f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5198ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5199ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
521726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
521826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
521926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
522026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
522126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5222e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5223e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5224e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5225e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5226e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5227e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
523026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
52341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
52351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
52361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
52371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
52391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
52401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52412235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
52421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
52441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
52451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
52461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
52471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
52481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
52508f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
52517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
52527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5253251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
52547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
52557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
52567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
52577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5259ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5260ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5261251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5262ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
5263ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5264ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5265ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5266ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
526730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
526830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
526930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
527030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
527130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
527230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
527330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
527430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
527530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
527630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
527730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
527830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
527930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
528726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
52885e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
52895e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5290ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
52915e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
52925e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
529326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
52945e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
52955e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
5297609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
5298777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
5299777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
5300777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5301777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
530226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
530326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
530426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
530526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
530626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
530726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
530826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
530926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
531090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
531126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
531226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5313e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5314e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
531590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
531690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
531790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
531890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
531990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
532090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
532190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
532290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
532390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
532490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
532526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
532626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
532726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
532826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
532926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
533026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
533126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
53420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
53430af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
53440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
53450af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
53460af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
53470af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
53480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
53490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
53500af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
53510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
536115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
536215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5363609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
536415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
536615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5372609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
537415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
538115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
538715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
538815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
539290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
539390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
539490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
539590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
539690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
539790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
539890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
539990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
540090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
540190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5403777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5404777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
540890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
540990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
541090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
541190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
541290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
541390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5416b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
5417b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ColorAspects aspects;
5418b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mRange = (ColorAspects::Range)((data2 >> 24) & 0xFF);
5419b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mPrimaries = (ColorAspects::Primaries)((data2 >> 16) & 0xFF);
5420b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)((data2 >> 8) & 0xFF);
5421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mTransfer = (ColorAspects::Transfer)(data2 & 0xFF);
5422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5424b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5425b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5428ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5434ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5436251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5437251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5438251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5439251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5440251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5441251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5442251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5448ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5449349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5450349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
54510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
54520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
54530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
54540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
54550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
545615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
545715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
545815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
54590806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
54600806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
546315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
546415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
546515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
546615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
546715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
546815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
546915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
547096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
547196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
547296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
547396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
547496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
547596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5487777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5489777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5490777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
5504d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
5505609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
55082d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
5511609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5522609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
55232d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
55255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5526a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
55275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
5529a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55327fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
55337fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
55347fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
55357fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
55367fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
55377fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
55387fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
55397fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
55403831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
55412d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
55455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
55465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
55475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
55485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
55495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
55510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
55520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
55530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
55540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
55550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
55560806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
55570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5565dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5566dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5567dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5568dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5576fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5577fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5578fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5579fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5580fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5581fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
55935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
55945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
55955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55965b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (buffer != info->mCodecData) {
5597ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
56005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                         buffer.get(), info->mCodecData.get());
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
56035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (converter == NULL) {
56045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
56055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
56065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
56075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
56085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
56090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
56100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5613078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5614ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5615078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
56165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5617ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
56185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5619078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5621ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5622ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5624ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5625ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5627078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5628349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5636054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5639054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5640054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5641054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5642054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5643054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5644054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5645054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5646054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5647054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
564815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
56490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
56500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode,
56510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    bufferID,
56520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    0,
56535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info->mCodecData->size(),
56540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    flags,
565515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
565615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd);
565715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
56590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
56600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
56610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
56655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
56665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
56670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
56680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
56695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
56705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
56715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
56725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
56740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
56750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5676dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5677dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
56783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5679dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5680dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5682ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5683349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5684349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
568515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
56860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
56870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
56880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
56890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
56900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
56910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
569215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
569315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
569415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
56960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
56970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
56980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5702dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5706625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5708777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5709777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5710625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5711777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5712625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
574915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
575015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5751609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
57525778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5753349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
57550806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5757d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5758d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5759d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5760d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5762d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5763d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5765d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5766d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5767d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5768d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5769d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5770d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5771d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
57740806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
57750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
57760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
57770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
57780806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
577915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
578015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
578115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
57820806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
57830806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
578890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
578990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
579090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
579190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
579290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
579390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
579490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
579590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
579690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
579715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
579815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
579915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
580015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
580115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
580215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
580315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5812a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5813a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5814609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
58155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5816349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
581715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
581815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
58190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
58200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
58220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
58255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
58265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
582731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5828577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
58291d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
5830577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5831b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5832697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                // pretend that output format has changed on the first frame (we used to do this)
5833697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
58341734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
5835697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                }
5836b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
5837b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
58385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5839b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5840054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
5841054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
5842054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
5843054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
5844054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (info->mData->size() >= sizeof(grallocMeta)
5845054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
58467c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
5847054219874873b41f1c815552987c10465c34ba2bLajos Molnar                } else if (info->mData->size() >= sizeof(nativeMeta)
5848054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
58497c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
58507c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
58517c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
58527c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
5853054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
58547c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5855054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
5856308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
5857308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5858308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
58595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else if (info->mData == info->mCodecData) {
5860308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
58615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
58625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
58635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
58645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
58655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info->mCodecData, info->mData);
58665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
58675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
58695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
5870308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
5871496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
587221ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
5873496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
5874496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
5875496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
58765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
587721ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
58808b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
58818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
58825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5885d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5886609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
58872d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
58885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5890609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
5893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
58955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
58965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
58995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
59005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
5902d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
5903dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5911777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
59120806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
59130806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
59140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
59160806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5918777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5919777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5920777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5921777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5929609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
59310806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
59320806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
59330806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
59340806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
59350806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
59360806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
59370806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
59380806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5940577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
5941777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5942777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5943777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5944577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
5945577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5946b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t dataSpace;
5947b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (msg->findInt32("dataspace", &dataSpace)) {
5948b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = native_window_set_buffers_data_space(
5949b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
5950b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
5951b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5952b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
59556aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
595679ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
59576fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
5958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
5959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
596090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
596190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
596290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
596390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
596490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
596590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
596690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
596790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5968fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
5969fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
5970c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
5971fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5972c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
5973fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
5974fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
5975fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
5976fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
59775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
5978fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
59790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5980fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
598115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
59820806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
598315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
598415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
59850806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
5986cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5987cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
5988264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
5989251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5990cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
599115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
599215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
5993cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
59956fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
59966fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
599715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
599815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
59996fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
60006fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6030c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
6031609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
6032c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
603315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
603415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(
603515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                            mCodec->mNode, info->mBufferID, info->mFenceFd);
603615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
60370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
60380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
60390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
60400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
6042c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6047777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
60490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
60500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
60510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60520806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6055777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6056777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6057777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6058777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6064f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
6069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
6070ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6071ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
607223858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mCodec->mNodeBinder->unlinkToDeath(mDeathNotifier);
6073ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
6074ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
6075ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6076b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
6077ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
6078e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
6079ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
6080ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
6081ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
6082ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6083054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
6084054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
60855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
60865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6087ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6088c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6090f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
61035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
61045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
61055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
61065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
61075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
61085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6113c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
611454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
611554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
6116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6118d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
6119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6122c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6128d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6132c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
613530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
613630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
613730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
613830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
613930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
614030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
614130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6149f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6152c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6153c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6154c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
61555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
61565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6157c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
61585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
61595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6160ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
61615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
616348a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
616448a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
616548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
616648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61701d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6172b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
61735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
6177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
61787791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
61795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6180b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6181b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6182b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6183afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
61845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
61855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
61865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
61875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
61885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
61895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
61905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6191b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
61925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
61935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6194b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6195e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
61965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
61971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
61981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6199ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
62001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6201201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
62021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
62031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6204b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6205b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6207da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6208078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6209078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
621023858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node);
6211078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
62141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
62157a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
62167a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
62171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
62181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6219ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
62201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
62211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6222ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
62235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
62249f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
62259f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
62265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
62279f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
62285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6229c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
623052e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6231c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6232c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
623423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
623523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    if (mCodec->mNodeBinder == NULL ||
623623858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen            mCodec->mNodeBinder->linkToDeath(mDeathNotifier) != OK) {
623723858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // This was a local binder, if it dies so do we, we won't care
623823858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // about any notifications in the afterlife.
623923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mDeathNotifier.clear();
624023858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
624123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
624226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
624690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6247ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6248ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6249ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6250ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
62511713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
62520167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6253ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6254ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6255afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
6256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
6258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
62605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6261d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
62625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
62635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
62645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
62695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
62705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6280f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6281f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6282f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6283f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6284f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6285054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6286054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6287a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6288e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6289e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
62904e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
6291054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
630054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6301f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6302f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
63070806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
6308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
631254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
631354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
6314d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
631554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
631654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
631754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6318c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6321c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6322c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6328c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
63317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
63327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
63337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
63347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
63357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
63367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
63377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
63388f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6339d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
63408f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6341d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6342d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6343d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6344d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6345c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6347c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6350c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6355c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6356c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
635854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6359c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6360c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6366c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6367c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6368d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
6370c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6371c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6372c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6373c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6376c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6377c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6378c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6379c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6380c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6381c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6382c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
63835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
63845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
63855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6386ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
63875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
63880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
63895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
63900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
63910806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
63920806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
63930806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
63940806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
63955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6396c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6397c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6398c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6399251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
64015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
64045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6405d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
6406e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
6407e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
64085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
64095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6411c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
64125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
64135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6414d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6415d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
6416a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6417d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
6418a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
6419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
6420a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
6421a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
6422a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
6423a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
6424a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6425a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6426a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6427a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
6428a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
6429a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
6430d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6431a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6432a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6433a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6434d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
643594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
643694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
643794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
643894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
643994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
644094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
644194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
644294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
644394ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
644472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
644572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
6446d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
64472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
64482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
64492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6450d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
645137b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
645237b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
645337b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
645437b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
645537b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
645637b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
645737b2b389139ed638831e49708c947863eef631efRonghua Wu
645837b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
645937b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
646037b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
646137b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
6462d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
646337b2b389139ed638831e49708c947863eef631efRonghua Wu        }
646437b2b389139ed638831e49708c947863eef631efRonghua Wu    }
646537b2b389139ed638831e49708c947863eef631efRonghua Wu
6466d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
64672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
64682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
64692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
64702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
64712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
64722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
64732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
64742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
64752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
64762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
64772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
64782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
64792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
64802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
64812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
6482d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
64832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
64842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
648572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6486d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
648772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
648872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
648972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
649072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
649172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
649272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
649372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
649472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
649572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
649672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
649794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
649894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
6499d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
650094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
650194ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
650294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6503c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6504c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    if (mCodec->mOMX->getParameter(
6505c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6506c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6507c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6508c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6509c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6510c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
6513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInternalOption(
6514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, IOMX::INTERNAL_OPTION_COLOR_ASPECTS,
6515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                colorAspectsBuffer->base(), colorAspectsBuffer->capacity());
6516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6522d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6523d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6524d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6525d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6526d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6527d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6528d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6529d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6530d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
6531d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6535b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6536b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
653757fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar
6538d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->createInputSurface(
6541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, dataSpace, &bufferProducer, &mCodec->mInputMetadataType);
6542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6543d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6544d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6545d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6546d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6547d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
65487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
65497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
65507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
65517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
65527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
65537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
65547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
65557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
65567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
65577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
65587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
65597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
65607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
65617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
65628f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
6563d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
65648f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6565d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6566d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6567d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
6568d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6569d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6570d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6571d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6572d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6573b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6574b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6576b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6577b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
6578b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6579b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6580b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInputSurface(
6581b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
6582b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                &mCodec->mInputMetadataType);
6583b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6584d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6585d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6586b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        surface->getBufferConsumer()->setDefaultBufferDataSpace(dataSpace);
6587d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6588d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6589d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6590d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
6591d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6592d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6593d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
65948f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6595d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
6596d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
6597d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6598d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
6599d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6600d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6601c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
66025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
66035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
66040806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
66050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
66060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
66070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
66080806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
66090806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6614f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6618f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
66193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6621cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6622cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
662329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6624cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6625cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6626cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6627251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
662891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6629c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        mCodec->mOMX->sendCommand(
6630c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6631c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6632c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6633c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6634c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6635c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6636c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6637c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
663891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6639cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6642f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
6650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6652f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
665472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
66626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
66636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
66646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
66656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
66666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
66676463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
66686463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
66696463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
66706463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
66716463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66726463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
66736463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
66746463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
66756463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
66766463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
6677d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
66786463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
66796463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
66806463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66816463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6687f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
66920806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
66930806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
66940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
66950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
66960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
66970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
66980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
66990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
67020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
67030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
67040806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
67070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
67080806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
67090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
67100806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6722f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6726f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
67273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6730f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
673272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6739d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6740d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6741d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6742d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6743d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6744d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6745d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6746d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6747d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
6748d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6749d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6750d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
6751d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6752d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6753d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6754d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
67556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
67566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
67576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
67586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
67596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
67606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6766f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
67710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
67720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
67730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
67740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
67750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
67760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
67770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
67780806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6793f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6794349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6795349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6798f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6799ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6810054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
68144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
68154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6816054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6818054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
68200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
68250806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
68260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
68270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
68280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
68290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
68300806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
68360806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
68370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
68380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
68390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
68400806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68430806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6844349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
684515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
684615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
684715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
68480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
68490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
68500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
68510806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
68550806340688c937e7b78c2d89db3809274130df4eLajos Molnar
68560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
68570806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6862c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6863054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6868f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6869349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
68700806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6871349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6872349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6873349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68763cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6877777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6878777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6879777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6880777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
68813cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
68823cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
68833cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
68843cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
68853cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
68863cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6887349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6888349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6891f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
68923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
689490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
6896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6898f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6904c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6905c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6906c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6907c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6908c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
690954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6910c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6911c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6912349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6913349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
69140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
69150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
69160806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
69170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
69180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
69200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
69210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
69230806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
69317a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
6932ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
6933d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
6934d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6935d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
6936d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6937d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
6938d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6939349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6940349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
69410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
69420806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
69430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
69460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
6953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
6955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6960496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
6961496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
6962496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
6963496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
6964496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
6965496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
6966496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6967496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
6968496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
6969496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
6970496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6971a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
6972a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
6973a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
6974a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
6975a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6976a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
6977a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6978a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
6979a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
6980a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
6981a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
6982a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
6983a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6984a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
6985a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
6986a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6987a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
69887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
69897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
69906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
69917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
69927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
69937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
69947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
69954dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6996054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
69974dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
69984dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
69994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
7000054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
70014dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
7002054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
70034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
70044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
70054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
70064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
70074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
7008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7016a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
7017a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
7018530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
7019a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7020a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
7021a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
7022a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
7023a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7024a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
7025a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
7026a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
7027a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
7028a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
7029a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7030a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
7031a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7032a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
7033a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7034a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
7035a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7036a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
7037a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
703872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
703972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
704072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
704172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
704272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
704372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
704472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
704572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
704672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
704772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
704872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
704972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
705072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
705172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
705272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
705372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7054e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
7055e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
7056e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
7057e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
7058b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
7059b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
7060e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
7061e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
7062e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
7063e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
7064b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
7065b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7066b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7067b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7068b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7069b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7070b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
7071b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7072b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7073b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7074b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7075b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7076b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7077b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7078b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7079b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7080e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7081e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
70828db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
70838db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
70848db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
70858db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
70868db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
70878db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
70888db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
70898db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
70908db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7091870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7092870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7093870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7094870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7095870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7096870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7097870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7098870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7099870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7100870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7101870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
7102a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
7103a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7104a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
71056507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
71066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
7107d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
71086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
71096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
71106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
71116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
71126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
71136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
71146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
71156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
711690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
711790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
711890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
711990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
712090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7121f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7128b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7129b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
713031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7131054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
7133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
7134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7137349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7140b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7141b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7142ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7161f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7166f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7177f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7184349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7185e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7187349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
71883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7189349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7190349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7204f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
72053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
720990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
721090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
721190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
721290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
721390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
721490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7215f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
72210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
72220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
72230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
72240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
72290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
72300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
72310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
72320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
72330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
72340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
72350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
72380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
72390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
72400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
72430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
72440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
72450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
72460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7247cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
72480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7249251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7250d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7251755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7252755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7253755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7254755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7255755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7256755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7257755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7258755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7259cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7263777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7264777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7265777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7266777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7271349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7272349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7273349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7289f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
72905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
72915778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
73020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7322f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
73233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
732431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
73255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7326b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
73340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
73350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
73360806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
73370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
73380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
73390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
73410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
73445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7350349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7351349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7352349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7353349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7354349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7355349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7356349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
73610af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7362f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
73635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
73640806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
73650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
73660806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
73670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
73680806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
73690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
73700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
73710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
73720806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73740167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
73750167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7376bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7377bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7378bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7379bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7380b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7381bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7382bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
73830806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
73840806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73850806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
73860806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
73870806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7392f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7399f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7408f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7412f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
74280806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7440f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
74413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7444f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
74490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
74500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
74510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
74520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
74530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
74540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
74550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
74560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7458c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7470f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7474f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
74753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7480f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7505f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
7506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7507ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
7508ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
7509d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
75130806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
75140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
75150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
75160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
75170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
75180806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
7521777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
7522777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
7523777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
7524777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
7525777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
7527e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
75280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
7529e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
7530e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
7531777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
7532777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
7533777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
7534777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
7535777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
7536777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7537777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
7540777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
7541777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
7542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7547349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7548349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
75491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
7550349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
7551609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
7552349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
7553349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
7554349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
7555349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
75563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
7557349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
7558349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7559349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
7560349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7561349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7562349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7563349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
7569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7571f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
7572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7577f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
7578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7583f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
7584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
7585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
7586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
75877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
75887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
75897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
75907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
759190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
759290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
7594d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
7595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
7596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
7598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
7599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7600dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
7601dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
7602f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
7603f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
7604f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
7605f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
7606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
7607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
76115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
76125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
76135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
76145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    const char *role = getComponentRole(isEncoder, mime.c_str());
76155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
76165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
76175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
76205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = client.connect();
76215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
76265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
76275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    IOMX::node_id node = 0;
76285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
762923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    err = omx->allocateNode(name.c_str(), observer, NULL, &node);
76305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
76325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    err = setComponentRole(omx, node, role);
76365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        omx->freeNode(node);
76385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
76395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
76435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
76445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
76465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
76475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
76485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
76495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
76525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
76545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
76555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
76596e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
76606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
76616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
76626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
76636e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
76646e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
76655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
76685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
76695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
76705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
76715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
767236e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
76735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
76746e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76756e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
76765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoPortFormat,
76785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
76795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
76845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (isFlexibleColorFormat(
76855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    omx, node, portFormat.eColorFormat, false /* usingNativeWindow */,
76865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
76875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
76885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
76895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
76905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
76915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
76925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
76935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
76945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
76955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
76965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
76975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
76985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
77005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
77016e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
77026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
77036e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
77046e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
77056e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
77066e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
77075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
77095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
77105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
77115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
77125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
77136e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
77146e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
77155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
77165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
77175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
77185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
77195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
77205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
77215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
77225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
77236e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
77246e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
77256e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
77266e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
77276e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
77286e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
77295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
77325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
77335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
77345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
77355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
77395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
77405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->configureVideoTunnelMode(
77415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
77425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
77435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
77445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
77455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        } else if (omx->storeMetaDataInBuffers(
77465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE) == OK ||
77475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            omx->prepareForAdaptivePlayback(
77485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE,
77495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
77505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
77515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
77555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
77565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
77575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
77585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
77595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->getConfig(
77605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
77615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
77625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
77635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
77675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    omx->freeNode(node);
77685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
77695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
77705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
77715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7772a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
7773a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
7774a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
7775a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
7776a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
7777a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
7778a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
7779a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7780a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
7781a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7782a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7783a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7784a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
7785a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7786a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7787a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7788a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7789a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
7790a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7791a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7792a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
7793a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
7794a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7795a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
7796a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7797a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7798a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7799a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
7800a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
7801a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7802a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
7803a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7804a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7805a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7806a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7807a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7808a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7809a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7810a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
7811a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7812a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7813a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7814a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7815a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7816a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7817a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
7818a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7819a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
7820a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7821a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7822a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7823a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7824a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7825a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7826a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
7827a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
7828a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7829a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
7830a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
7831a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
7832a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7833a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
7834a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
7835a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
7837