ACodec.cpp revision 1734c7d01c1567568ced29398b23abd601fd44cb
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
4090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar#include <media/stagefright/MediaCodec.h>
41afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
45b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
52777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar#include "include/DataConverter.h"
5673dd808754c641fe798273d356ee38368715fa7bLajos Molnar#include "omx/OMXUtils.h"
57496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
58f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnarenum {
616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar};
636e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
99251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
100251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
101251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
102251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
103251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
105251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
10626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
10726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
10826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
109984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    virtual ~MessageList() {
110984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    }
11126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
11226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
11326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
11426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
11526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
11626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
11726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
1185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnarstatic sp<DataConverter> getCopyConverter() {
1195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
1205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static sp<DataConverter> sCopyConverter;        // zero-inited
1215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
1225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return sCopyConverter;
1235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar}
1245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
13326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
134984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        if (messages.empty()) {
135984a54322f7c70bc75e862d91bdd975814872affLajos Molnar            return;
136984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        }
137984a54322f7c70bc75e862d91bdd975814872affLajos Molnar
138984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        sp<AMessage> notify = mNotify->dup();
13926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        bool first = true;
14026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
14126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
14226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
14326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
14426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            if (first) {
14526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                notify->setInt32("node", omx_msg.node);
146984a54322f7c70bc75e862d91bdd975814872affLajos Molnar                first = false;
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
15026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
15126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
15226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
15326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
15426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
15526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
15626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
15726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
15826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
16126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
16326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
16426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
16526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
16826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
17126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
17326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
17426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
17626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
17726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
17926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
18026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
18126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
18226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
18326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
18526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
18626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
18990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
19090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
19190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
19290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
19390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
19490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
19590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
19690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
19726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
19826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
19926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
20026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
20126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
20226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
20326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
20426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
24226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
24626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
24726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
24826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
24926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
25026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
25115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
25715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
25815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
26190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
269ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
270ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
271ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
272ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
273ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
274ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
275ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
276ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
277ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
278ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
279ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
280ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
281ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
282ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
283ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
284ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
285ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
286ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
299ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3178f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
318c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
321d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
322d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
362054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
370349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
371349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
37890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
381349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
382349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
39790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
46515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
46615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
46715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
46815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
46915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
47015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
47115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
47215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
47315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
47415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
47515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
47615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
47715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
47815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
47915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
48015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
48315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
48415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
48515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
48615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
48915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
49015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
49115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
49215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
49315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
49415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
49515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
496f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
497afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
498609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
500e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
5018db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
503346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5049806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
50554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
5069806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5079806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
508e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5099806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
510054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
511054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
512054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mInputMetadataType(kMetadataBufferTypeInvalid),
513054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mOutputMetadataType(kMetadataBufferTypeInvalid),
514011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
515054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
51794ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
51937b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
5202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
521609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
522ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
5238338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
5248338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0) {
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
539dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
547f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5531d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
559a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
560a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
561a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
562a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5635778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5695778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
5801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
5811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
5831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
5841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
5861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
5871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
5891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
5907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5928f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
593d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
5948f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
595d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
596d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
597d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
598d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6035778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6087a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
612f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
62030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
62130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
62330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
626496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
628496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
629496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6304dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
635054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
637054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
638054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
652e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
671e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
672e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);
6731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
677f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
678e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
679e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
680e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
681e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
682e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
683e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
6841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
6921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
6931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
6991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
713dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
714dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
715dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
721054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
722011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
739054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
74115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
74515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
74615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
759484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
760484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
761484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
762484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
763484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
765e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
777054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()) {
778054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
791054219874873b41f1c815552987c10465c34ba2bLajos Molnar            MetadataBufferType type =
792054219874873b41f1c815552987c10465c34ba2bLajos Molnar                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
7935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
794054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (type == kMetadataBufferTypeGrallocSource) {
795054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoGrallocMetadata);
796054219874873b41f1c815552987c10465c34ba2bLajos Molnar            } else if (type == kMetadataBufferTypeANWBuffer) {
797054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
798054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
799054219874873b41f1c815552987c10465c34ba2bLajos Molnar
800054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // If using gralloc or native source input metadata buffers, allocate largest
801054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // metadata size as we prefer to generate native source metadata, but component
8025fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // may require gralloc source. For camera source, allocate at least enough
8035fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // size for native metadata buffers.
8045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t allottedSize = bufSize;
8055fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) {
806054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
8075fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
8085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                bufSize = max(bufSize, sizeof(VideoNativeMetadata));
8095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
8105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
821054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
822054219874873b41f1c815552987c10465c34ba2bLajos Molnar
82328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
82428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            ALOGV("[%s] Allocating %u buffers of size %zu/%zu (from %u using %s) on %s port",
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
827054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
8285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
8315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
83228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
83328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
83428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
83528edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
83628edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
83728edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
8385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
8395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
84034e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
84134e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
84234e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
84328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
847054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
848054219874873b41f1c815552987c10465c34ba2bLajos Molnar                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
8495581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
850777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
851777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
854ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
85515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
85690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
857a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                info.mNativeHandle = NULL;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
860afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
861b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        ? kRequiresAllocateBufferOnInputPorts
862b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        : kRequiresAllocateBufferOnOutputPorts;
8631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
864e33d922fd86699c664a15f09e6d8b2e422736a40Lajos Molnar                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
865ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
866ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
867a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
868a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    native_handle_t *native_handle = NULL;
869a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    err = mOMX->allocateSecureBuffer(
870054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, bufSize, &info.mBufferID,
871a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
872a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
873a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY: this representation is unorthodox, but ACodec requires
874a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // an ABuffer with a proper size to validate range offsets and lengths.
875a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // Since mData is never referenced for secure input, it is used to store
876a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // either the pointer to the secure buffer, or the opaque handle as on
877a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // some devices ptr is actually an opaque handle, not a pointer.
878a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
879a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY2: use native handle as the base of the ABuffer if received one,
880a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // because Widevine source only receives these base addresses.
881a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    info.mData = new ABuffer(ptr != NULL ? ptr : (void *)native_handle, bufSize);
882a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    info.mNativeHandle = NativeHandle::create(native_handle, true /* ownsHandle */);
8835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = info.mData;
884ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
886054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
888054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
889ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
890ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
891ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
8925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = new ABuffer(mem->pointer(), bufSize);
8935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecRef = mem;
8945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
895054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (type == kMetadataBufferTypeANWBuffer) {
896054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
897054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
8985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // if we require conversion, allocate conversion buffer for client use;
9005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // otherwise, reuse codec buffer
9015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (mConverter[portIndex] != NULL) {
9025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        CHECK_GT(conversionBufferSize, (size_t)0);
9035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mem = mDealer[portIndex]->allocate(conversionBufferSize);
9045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        if (mem == NULL|| mem->pointer() == NULL) {
9055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            return NO_MEMORY;
9065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        }
9075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = new ABuffer(mem->pointer(), conversionBufferSize);
9085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = mem;
9095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else {
9105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = info.mCodecData;
9115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = info.mCodecRef;
9125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
9161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
9171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
925d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
928eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
929eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
930eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
932eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
933a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        desc->addBuffer(info.mBufferID, info.mData, info.mNativeHandle, info.mMemRef);
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
936eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
942e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
943e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {
9441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
9491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
9521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
9561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
9571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
9581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
9591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
9601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
9611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
9631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
9651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
9661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
968f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
969e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
970b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
9711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
9721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
9731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
9741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
9751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
9761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
9771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
9781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
9791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
9801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
9821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
9831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
9841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
9891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
992e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);
9931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
995e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
9961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
999ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
1000ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
1001ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
1002ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1003ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1004ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
1005ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
1006ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1007ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1008ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
1009ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
1010ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
1011ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
1012ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1013ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1014054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
1015258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
1016258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1017054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
1018258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1019258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
102029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1021258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
1022258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
1023258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1024258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1025e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
1026e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
10271faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
10281faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1029e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1030e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
1031e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
1032e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1033e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
1034e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
1035e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
10361faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
10371faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1038e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
1039e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1040258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1041258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
1042258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1043258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1044e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1045e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1046e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1047e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1048e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1049609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1050e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1051e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1052e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1053258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1054258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1055258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1056258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
106129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1066054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1067054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1076054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1077e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1079054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
10803298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
10813298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
10823298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10833298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1084609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
10908ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
109115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
109215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
109429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
109974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
110074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
110115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
110215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
110390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
11055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
110674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
110774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
110874006804065941841883c4b46ee785070164023fJamie Gennis
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1113609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
111474006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
111874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
111974006804065941841883c4b46ee785070164023fJamie Gennis
1120609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
113274006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1134054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1135054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1136054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
11413175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
11423175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
11433175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
11443175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
11453175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
11463fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1149054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
11503298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
11513298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
11523298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
11533298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1157054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1159054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1163e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1165e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1166e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1167e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1168054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1169054219874873b41f1c815552987c10465c34ba2bLajos Molnar            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
117028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar    size_t totalSize = bufferCount * align(bufSize, MemoryDealer::getAllocationAlignment());
1171e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1172e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1173e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
1174e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1175e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1176e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
117715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
117890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1179e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1180e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1181e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1182054219874873b41f1c815552987c10465c34ba2bLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
11835581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
1184777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
1185777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1186054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1187054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1188054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1189e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
11905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mMemRef = mem;
11915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
11925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecRef = mem;
1193e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1194e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
1195e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        err = mOMX->useBuffer(
1196cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1197e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1198e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1199e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1200e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1201e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1202e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1203011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1204e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1205011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1206011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1207011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1208011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1209011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1210011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1211011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1212011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1213011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1214e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1215e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1216011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
121715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd;
121815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1219011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1220011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1221011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1222011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1223011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1224011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1225e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            mOMX->updateGraphicBufferInMeta(
1226e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1227e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
122815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1229e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1230011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1231011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1232011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1233011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
12343175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (info->mStatus == BufferInfo::OWNED_BY_US) {
12353175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                status_t error = cancelBufferToNativeWindow(info);
12363175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                if (err == OK) {
12373175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                    err = error;
12383175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                }
1239011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1240011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1241011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1242011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1243011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1244011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1245011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1246054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1247054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1248054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1249054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1250054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1251054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1252054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1253054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1254054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1255054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
12560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1257054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
12580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1260609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1263054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
126415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
126515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
126615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1267777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1268777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1269777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1270054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1271777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1272054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1273054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
127415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
127515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
127615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
127715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
127815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
127915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
128015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
128115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
128215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
128315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
12840806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
12850806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
12860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
12870806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
12880806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
12890806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
12900806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
12910806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
12920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
12930806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
12940806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
12950806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
12960806340688c937e7b78c2d89db3809274130df4eLajos Molnar
12970806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
12980806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
12990806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
13000806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
13010806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
13020806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
13030806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
13040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
13050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
13060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
13070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13080806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13090806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1313609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
131815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
131915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13213fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
13223fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
13230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13263fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
133090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
133190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
133290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
133390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
133490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
133590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
133690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
133790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
133890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
133990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
134090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
134190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
134290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
134390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
134490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
134590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
134690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
134790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = mNotify->dup();
134890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
134990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
135090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
135190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
135290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
135390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
135490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1355604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1356604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1357604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1358604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1359604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1360604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
136190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
136290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
136390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
136490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
136590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->post();
136690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
136790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
136890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1369f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
13708ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1372ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1373ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1374ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1375ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1376ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1377ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1378ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1379346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1380346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1381346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1382346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1383346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
138415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1385dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
138615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
138715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
138815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1389dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1390dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1392dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1393b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1394b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1395dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1396dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1397dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
139890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1399dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1400dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1401dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1402dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1403dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1404dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1405dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1406dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1407dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1408dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1409dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1410dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
141190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1412dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1413dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
141415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
141590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1416dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1417dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1418dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1420dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1421dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1422dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1423dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1424dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1425054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1426dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1427dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1428dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1429dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1430dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1431dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1433dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1434054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1435dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1436dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1437b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1438b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1439dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1440dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1441054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1442054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1443054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1444054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1445054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1446054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1447054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1448054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1449054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14500806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
14510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
14520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
14530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1454054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1455054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
14570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
14580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
145915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
146090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
146190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1462d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
14630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    mOMX->updateGraphicBufferInMeta(
14640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
14650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mBufferID);
1466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1467054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1468054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata *grallocMeta =
1469054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1470054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1471054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1472054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14737c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)grallocMeta->pHandle,
1474054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1475054219874873b41f1c815552987c10465c34ba2bLajos Molnar    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1476054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata *nativeMeta =
1477054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1478054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1479054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1480054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14817c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)nativeMeta->pBuffer,
1482054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1483054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
14860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1490777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1491938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1492938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1493777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1494777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1495777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1496777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14990806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1501777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1504349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1505777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1506938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1507938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15112ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
15122ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
15132ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
15142ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1515777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1516777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1517777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1518777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1522777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
15270806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
153015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    MetadataBufferType type =
153115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
153215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
153315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
153415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
153515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
153615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
153715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
153815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
153915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
154015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
15410806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
15420806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
15430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
15440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
15450806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
15460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
15490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
15500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
15510806340688c937e7b78c2d89db3809274130df4eLajos Molnar
15520806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
15530806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
15540806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
15550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
155815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
155915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
156015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
156115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1562604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1563604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1564604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1565604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
156690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1567777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1569777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1572f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
15730806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1585777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
15915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    const char *role = getComponentRole(isEncoder, mime);
15925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
15935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
15945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
15955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = setComponentRole(mOMX, mNode, role);
15965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
15975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
15985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
15995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
16005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
16015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
16025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
16035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
16045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarconst char *ACodec::getComponentRole(
16055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        bool isEncoder, const char *mime) {
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
16152944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
16162944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
16172944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
16182944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1625729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1626729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1627bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1628bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1629c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1630c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1631c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1632c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
16352472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
16362472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
164194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
164294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
164394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
164494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1645ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1646ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
1647a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu        { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
1648a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu            "video_decoder.dolby-vision", "video_encoder.dolby-vision" },
16492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
16502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1651ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1652ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1653774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1654774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
165597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
165697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
16578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
16588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
16725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NULL;
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return isEncoder ? kMimeToRole[i].encoderRole
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
16775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
16805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::setComponentRole(
16815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node, const char *role) {
16825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMX_PARAM_COMPONENTROLETYPE roleParams;
16835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    InitOMXParams(&roleParams);
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    strncpy((char *)roleParams.cRole,
16865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            role, OMX_MAX_STRINGNAME_SIZE - 1);
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return omx->setParameter(
16915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            node, OMX_IndexParamStandardComponentRole,
16925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            &roleParams, sizeof(roleParams));
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1702b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1703b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1704b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1705e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1708054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mInputMetadataType = kMetadataBufferTypeInvalid;
1709054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mOutputMetadataType = kMetadataBufferTypeInvalid;
17108db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
17182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
17192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
17202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1725d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1727d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1728054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1729d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1730054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1731308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1732d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1733054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
1734054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1735054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // For this specific case we could be using camera source even if storeMetaDataInBuffers
1736054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
1737054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
1738054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mInputMetadataType = kMetadataBufferTypeCameraSource;
1739054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1740c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1741c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1742c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mOMX->getParameter(
1743c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1744c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1745c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1746c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1747c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1748054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1750308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
17513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
17523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
17533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
17543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
17553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
17563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
17573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
17583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
17593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
17613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
17623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
17633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
17643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
17663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
17673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
17703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
17713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
17723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
17743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
17763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1777308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1778308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1779308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1780308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
17818db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1782308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1783308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1784308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1785308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1786308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1787054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1788308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1789308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1790308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1791308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1792a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1793a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1794a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1795a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1796a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1797a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
179894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
179994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
18002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
18012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
18022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
180337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
180437b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
180537b2b389139ed638831e49708c947863eef631efRonghua Wu        }
180637b2b389139ed638831e49708c947863eef631efRonghua Wu
18072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
18082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
180994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
181072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
181172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
181272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
181372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
181472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
181572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1816308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1817308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
18183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
18200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
18213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1822b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1823011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1824e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1825e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
18261713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
18271713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
18281713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
18291713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
18301713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
18311713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
18321713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
18331713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
18341713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
18351713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1836a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1837a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        if (mFlags & kFlagIsSecure) {
1838a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            // use native_handles for secure input buffers
1839a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = mOMX->enableNativeBuffers(
1840a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    mNode, kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
1841a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            ALOGI_IF(err != OK, "falling back to non-native_handles");
1842a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = OK; // ignore error for now
1843a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
18453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
18461de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
18471de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
18485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18496597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
18506597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
18516597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
18526597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
18536597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
18546597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
18556597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
18566597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
18576597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
18586597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
18596597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
18606597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
18616597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
18626597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
18636597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
18646597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
18656597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
18666597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
18675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
18685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
18695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
18705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1871ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
18725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
187397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
187497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
18755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
18765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
18785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
187997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
18805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
18815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1882fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1883fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1884d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1885d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1886d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1887d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1888d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1889d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1890d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1891d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1892d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
18933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
18943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1895d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1896d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1897d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1898d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1899d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1900d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
19015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1902ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1903ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1904ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
19053fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
19063fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
19073fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
19083fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
19093fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
19103fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
19113fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
19123fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
19133fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
19145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
19155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
1916054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
19175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
19185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1919fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1920e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
19215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
19225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
19235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
19245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
19265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
19275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
19285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
19295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
19305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
19325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
19335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
19345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
19355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
19365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
19375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
19385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
19395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
19405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
19415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
19425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
19445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
19455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
19465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
19475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
19485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
19495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
19515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
19525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
19535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
19545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
19555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
19565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
19585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
19595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
19605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
19615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1962e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
19635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
19645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
19655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
19665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
19675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
1968054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
1969011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1970011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1971011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
19725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1973fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
19740167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
19755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
19765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
19775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
19785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
19795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
19800167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1981e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1982e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1983e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1984e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1985e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1986e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1987e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1989054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
19905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
19915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
19925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
19935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
1994308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
19953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
19963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
19973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
19983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
19993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
20003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
2003b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2005b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
20093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
20103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
20131de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
20143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
20173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
2018777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
2019777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
2020777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
2021777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
20223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
20243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
20253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
20263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
20273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
2028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
2029777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
2030777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
2031777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
20323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
20333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
2034777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
2035777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
2036777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
2037777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
20383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
20393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
20403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
20413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
20423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
20433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
20443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
20453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
20463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
2047e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
20483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
20493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
2050054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (storingMetadataInDecodedBuffers()) {
2051054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        err = mOMX->storeMetaDataInBuffers(
2052054219874873b41f1c815552987c10465c34ba2bLajos Molnar                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
2053054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
20543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
20553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
20563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
20573a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
2059a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                        err = mOMX->enableNativeBuffers(
2060a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                                mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
20613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
20633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
20643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
20653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
2066b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
2067b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
20703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
20713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
20743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
20753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
207642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
207742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
207842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
207942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
208042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
208142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
208242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
208342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
208442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
208542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
208642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
208742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
208842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
2089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2095aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
2096b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
20978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
20982965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
20998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
2100ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
2101ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
2102ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
2103aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
2104aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
2105aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
2106b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2107b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
2108b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
2109ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
21108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
21118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
21128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21132965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
21142965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
21152965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
21162965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
21178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
21188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
21208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21218045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
21228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
21248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
21268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
21288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21298045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
21308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
21328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
21348045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
21368045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2138ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
21394471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
21402965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
21412965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2143729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2145729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2147729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2148729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2149729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2150729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2151729de186450f78c099637e1fce743fe531862c52Andreas Huber
2152729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
215617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
215717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
215817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
215917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
216017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2163ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
21642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
21652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
21662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
21672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
21682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
21692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
21702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2171516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2172cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2173cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2174516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2175cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
21762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2177516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2178516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2179516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
21812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2182516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2183516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2184516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
21862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
21872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2188516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2189516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
21902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2191ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2192ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2193ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2194ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2195ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2196ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2197ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
21985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2199ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
220097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
220197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
220297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
220397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
220497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
220597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
220697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
220797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
220897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
22098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
22108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
22118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
22128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
22138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
22148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
22158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
22168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
22178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2219729de186450f78c099637e1fce743fe531862c52Andreas Huber
22204471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
22214471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
22224471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
22234471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
22248b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
22258b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
22268b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
22279806555d3930be43e11106281dee354820ac1c88Andreas Huber
22288b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
22298b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
22308b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
22318b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
22329806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
22339806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
22349806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
22359806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
22369806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
22379806555d3930be43e11106281dee354820ac1c88Andreas Huber
2238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22458b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
22468b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
22478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
22488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2250ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2251ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2252ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2253ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2254ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2255ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2256ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2257ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2258ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2259ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
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);
39485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39508eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    // XXX
39518eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
39528eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        ALOGW("Use baseline profile instead of %d for AVC recording",
39538eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang            h264type.eProfile);
39548eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
39558eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    }
39568eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang
39575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
39585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
39635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
39705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
39745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
39775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
39785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
39815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
39855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
39865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
39875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
39895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
399596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
39965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3998c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3999c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
4000c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
4001c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
4002c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
4003c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4004c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4005c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
4006c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4007c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
4008c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
4009c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
4010c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
4011c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4012c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4013c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
4014c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4015c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4016c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4017c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4018c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4019c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4020c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4021c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
4022c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4023c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4024c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4025c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4026c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4027c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4028c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4029c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4030c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4031c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4032c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4033c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4034c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
4035c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4036c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4037c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4038c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4039c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4040c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4041c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
40429aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
40439aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
4044c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4045c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
4046c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4047c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4048c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4049c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4050c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4051c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
4052c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4053c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
405489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
405589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
40564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
40574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
40584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
40594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
40604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
40614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
40624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
40634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
40644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
40654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
40664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
406789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
406889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
406989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
40704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
407189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
407289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
407389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
40744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
40754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
40764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
40774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
40784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
40794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
40814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
40824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
40834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
40844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
40854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
40864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
40874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
40884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
40894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
40904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
40914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
40924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
40934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
40944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
40954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
40964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
40984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
40994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
41004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
41014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
41024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
41034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
41044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
41054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
41074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
41084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
41094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
41114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
41124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
41134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
41144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
41154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
41164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
41174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
41194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
41204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
41214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
41234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
41244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
41254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
41264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
41274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
41284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
41294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
41304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
413189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
413289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
413389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
41345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
41355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
41365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
41375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
41385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
41395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41406e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
41416e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
41505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
41565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
41575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41586e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
41596e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
41606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
41616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
41626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
41636e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41656e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
41665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
416896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
416996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
41705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
41715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
41725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
41735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
41755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
41765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
41775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
418296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
41835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
41845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
41865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
41875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
41885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
41915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
41925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
41945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
41965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
42015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
42055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
42065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
42105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
42115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
42125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
421678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
421778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4226777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4227777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4228777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4238777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4239777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4240777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4241777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
424978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
425078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
425178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
4262a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4265a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4269d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4270d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4271d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4272d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4273d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4274d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4275d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4276d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4277d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4278d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4279d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4280d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4281d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4282d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
42837e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
42847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
42857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
42877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
42887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
42907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
42917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
42927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
42937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
42957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
42967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42977e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
42987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
42997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
43007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4302e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
43037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4304c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4305054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4306054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4307c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
43087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
43097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
43107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4318609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
434873dd808754c641fe798273d356ee38368715fa7bLajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormat2Params &params) {
434973dd808754c641fe798273d356ee38368715fa7bLajos Molnar    MediaImage2 &image = params.sMediaImage;
435003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
435103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
435273dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
435303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
435403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
435503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
435603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
435703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
435803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
435903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
436003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
436103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
436203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
43635a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
43642ad160ba086f0504cf56dcc24619a0cee2546a23Dan Stoza        fmt != (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YV12) {
436503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
4366229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
436703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
436803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4369b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
4370b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
4371b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
4372b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
4373b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
4374b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
4375b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
437634e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // we need stride and slice-height to be non-zero and sensible. These values were chosen to
437734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // prevent integer overflows further down the line, and do not indicate support for
437834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // 32kx32k video.
437934e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    if (params.nStride == 0 || params.nSliceHeight == 0
438034e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            || params.nStride > 32768 || params.nSliceHeight > 32768) {
4381b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
4382b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
4383b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
4384b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
4385b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
438603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
438773dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV;
438803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
438903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
439073dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mBitDepthAllocated = 8;
439103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
439203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
439303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
439403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
439503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
439603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
43975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
43985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
43995a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
44005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
44015a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
44025a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
44035a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44045a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
44055a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
44065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
44075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
44085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
44095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
44115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
44125a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
44135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
44145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
44155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
44165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
44175a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
44185a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
44195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
44205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
44215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
442203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
442303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
442403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
442503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
442603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
442703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
442803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
442903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
443003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
443103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
443203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
443303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
443403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
443503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
443603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
443703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
443803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
443903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
444003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
444103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
444203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
444303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
444403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
444503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
444603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
444703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
444803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
444903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
445003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
445103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
445203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
445303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
445403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
445503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
445603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
4457229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
4458229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
4459229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4460229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
4461229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
4462229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
446373dd808754c641fe798273d356ee38368715fa7bLajos Molnar        DescribeColorFormat2Params &describeParams)
4464229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
4465229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
4466229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
4467229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
446873dd808754c641fe798273d356ee38368715fa7bLajos Molnar            &describeColorFormatIndex) == OK) {
446973dd808754c641fe798273d356ee38368715fa7bLajos Molnar        DescribeColorFormatParams describeParamsV1(describeParams);
447073dd808754c641fe798273d356ee38368715fa7bLajos Molnar        if (omx->getParameter(
447173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                node, describeColorFormatIndex,
447273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                &describeParamsV1, sizeof(describeParamsV1)) == OK) {
447373dd808754c641fe798273d356ee38368715fa7bLajos Molnar            describeParams.initFromV1(describeParamsV1);
447473dd808754c641fe798273d356ee38368715fa7bLajos Molnar            return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
447573dd808754c641fe798273d356ee38368715fa7bLajos Molnar        }
447673dd808754c641fe798273d356ee38368715fa7bLajos Molnar    } else if (omx->getExtensionIndex(
447773dd808754c641fe798273d356ee38368715fa7bLajos Molnar            node, "OMX.google.android.index.describeColorFormat2", &describeColorFormatIndex) == OK
447873dd808754c641fe798273d356ee38368715fa7bLajos Molnar               && omx->getParameter(
447973dd808754c641fe798273d356ee38368715fa7bLajos Molnar            node, describeColorFormatIndex, &describeParams, sizeof(describeParams)) == OK) {
448073dd808754c641fe798273d356ee38368715fa7bLajos Molnar        return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
448173dd808754c641fe798273d356ee38368715fa7bLajos Molnar    }
448273dd808754c641fe798273d356ee38368715fa7bLajos Molnar
448373dd808754c641fe798273d356ee38368715fa7bLajos Molnar    return describeDefaultColorFormat(describeParams);
4484229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
4485229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4486229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
4487229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
4488229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
44890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
449073dd808754c641fe798273d356ee38368715fa7bLajos Molnar    DescribeColorFormat2Params describeParams;
4491229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
4492229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
4493229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
4494229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
4495229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
4496229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
4497229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
44980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
4499229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4500229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
4501229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4502229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
4503229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
4504229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
4505229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
450673dd808754c641fe798273d356ee38368715fa7bLajos Molnar    const MediaImage2 &img = describeParams.sMediaImage;
450773dd808754c641fe798273d356ee38368715fa7bLajos Molnar    if (img.mType == MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
450873dd808754c641fe798273d356ee38368715fa7bLajos Molnar        if (img.mNumPlanes != 3
450973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                || img.mPlane[img.Y].mHorizSubsampling != 1
451073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                || img.mPlane[img.Y].mVertSubsampling != 1) {
4511229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
4512229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
4513229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4514229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
4515229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
4516229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
4517229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
4518229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
4519229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
4520229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
4521229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
4522229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
4523229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
4524229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
4525229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
4526229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
452703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
452803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4529e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4530777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
453131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
453231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4533e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
453431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4535777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4536777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4537777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4538777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
453931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4540777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4541777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4542777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4543777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
454431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
454531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
454631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
454731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
454831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4550e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4551e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4552e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4553e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4554e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4555e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4556e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4557e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4558e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
45590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
456073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
45610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
45620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
45630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
45640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
45650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
45660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
45670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
45680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
45690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
45700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
45710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
45720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
45730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
45740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
45755a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
457673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
457773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
457873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
457973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
458073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
458173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
458273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
45830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
458403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
458503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4586b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4587b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4588b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4589b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4590b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4591b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4592b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4593b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4594b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mOMX->getConfig(
4595b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    mNode,
4596b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4597b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4598b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4599b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4600b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4601b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4602b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4603b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4604b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
460591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4606b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4607b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4608b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4609b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4610b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4613b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4614b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4615b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
461631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4617b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4618b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4619b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4621b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4622b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4623b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4624b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4625b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4626b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4627b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4628b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4629b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4630b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4631b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4632b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4633b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
4634b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4635b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
4636777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4638e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4639e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
46404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
46414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
46424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
46434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
46444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
46454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
46464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
46474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
46484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
46494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
46504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
46514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
46524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
46534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
46544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
46554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
46564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
46574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
46584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
46594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
46614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
46644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
46664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
46694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
46714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
46744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
46754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
46764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
46774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
46784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
46794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
46804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
46814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
46824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
46834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4684e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4685e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4686777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4687777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4688777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4689777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4690777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4691777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4692777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4693e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4694e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4695e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4696e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4697e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4698e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4699e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4700870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4701870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4702870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4703870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4704870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4705e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
470731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
47105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
47115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
47125a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
47135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
471431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
471531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
471631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
471731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
471831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
471931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
472031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
472197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4728777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4729777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4730777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4731777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4732777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
473314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4734777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4735777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4736777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
47375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4738777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4739777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
47405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
4741777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4742777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4745e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
47475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
47485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
47495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
47505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
47515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
47525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
47535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
47545b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
47555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
47565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
47575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
47585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
47595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
47605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
47615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
47625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
4763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4764e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4765e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
47668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
47688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
47699806555d3930be43e11106281dee354820ac1c88Andreas Huber
4770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4776777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4777777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4778777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4779777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4780777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4782e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4792e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
47939806555d3930be43e11106281dee354820ac1c88Andreas Huber
4794777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4795777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4796777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4797777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4798777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
48020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
48050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4817777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4818777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4819777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4820777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4821777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4829e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4830e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4831e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4832e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4833e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4834e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4835777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4836777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4837777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4838777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4839777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4851e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4852e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4853777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4854777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4855777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4856777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4857777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
486597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
486697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
486797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
486897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
487097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4871777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4872777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4873777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4874777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4875777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4876777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
487797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
487897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
487997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
488097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
488197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
488297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4883e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
48848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
48858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
48868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
48878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
48888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
48898a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4890777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4891777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4892777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4893777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4894777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4895777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
48968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
48978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
48988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
48998a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
49008a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
49018a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
49028a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
49048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
49058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
49068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
49078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
49088c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4911777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4912777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4913777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4914777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
49158c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
49168c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
49178c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
49188c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
49198c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
49208c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
49218c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
492210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
492310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
492410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
492510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
492610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
492710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4928777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4929777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4931777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4932777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
493310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
493410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
493510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
493610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
493710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
493810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
493910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
494010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
494110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
494210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
494310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
494410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
494578bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
494610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
494710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
494841d3f579d2c166984958263533284209b90c87d5Marco Nelissen
494941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
495041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
49510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
495241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
495341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
495441d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4955777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4956777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4957777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4958777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4959777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
496041d3f579d2c166984958263533284209b90c87d5Marco Nelissen
496141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
496241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
49630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
496441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
496510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
496610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4967e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4968777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4969777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4970777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4971e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
497231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
497331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
497431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
497531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4976777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4977777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
497831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
497931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4980e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4981e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4982e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4983b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
4984b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
4985b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
4986b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
4987b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4988b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
4989b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
4990b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
4991b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4992b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
4993b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
4994b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4995b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
4996b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
4997b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4998b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4999b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5000b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5001b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
5002b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5003b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5004b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
5005b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5006b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5007b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
5008b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5009b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5010b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5011b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5012b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
5013b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
5014b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
5015b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5016b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
5017b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
5018b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
5019b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
5020b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
5021b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
50221734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5023697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // store new output format, at the same time mark that this is no longer the first frame
5024b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
5025e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5026b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5027777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
5029777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5030e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
50311734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    if (expectedFormat != NULL) {
50321734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
50331734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
50341734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        if (changes->countEntries() != 0 || to->countEntries() != 0) {
50351734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
50361734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mComponentName.c_str(),
50371734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    changes->debugString(4).c_str(), to->debugString(4).c_str());
50381734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        }
50391734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    }
50401734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar
50415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
50425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
50435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
50445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
50455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
50465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
50475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
50485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
50495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
50505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
50515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
50525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
5053b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
5054b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
5055b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5056b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5057b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5058b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> &notify) {
5059e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
5060b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5061e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5062b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) {
5063b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // notify renderer of the crop change and dataspace change
5064e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
5065b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t left, top, right, bottom;
5066b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
5067b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setRect("crop", left, top, right + 1, bottom + 1);
5068b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5069b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5070b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t dataSpace;
5071b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
5072b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setInt32("dataspace", dataSpace);
5073b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5074b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5075b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5076b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5077b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
5078b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
5079b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5080b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5081b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5082e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
5083b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5084e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
5085e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
5086e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
5087ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
5089e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
5090b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
5092e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5093b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> notify = mNotify->dup();
5094b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
5095b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setMessage("format", mOutputFormat);
509631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
509731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5098b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5099b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
510031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
510131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51025778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5103cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
5104d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
5105251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5106251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
5107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
5108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
5109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
5110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
5111251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
5112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5114251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5115346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5116346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
5117346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
51185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
5119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
5120cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
5121cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5122cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5125eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
5126eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5127eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5128496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5129496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5130496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5131496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5132496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5133496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5134496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5135496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5136496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5137496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5138496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5139496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
5140496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
5141496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5142496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5143496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5144496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5145496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5146eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
5147a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        IOMX::buffer_id id, const sp<ABuffer> &buffer,
5148a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
5149eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
5150eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
5151a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mHandles.push_back(handle);
515286b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    mMemRefs.push_back(memRef);
5153eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5154eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5155eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
5156eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
5157eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5158eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5159eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
5160eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
5161eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5162eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5163eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
5164eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
5165eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5166eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5167a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnarsp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
5168a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    return mHandles.itemAt(index);
5169a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar}
5170a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
517186b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wusp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
517286b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    return mMemRefs.itemAt(index);
517386b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu}
517486b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu
5175eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
5176eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5177f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5182ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5183ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
520226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
520326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
520426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
520526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5206e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5207e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5208e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5209e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5210e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5211e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
521426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
52181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
52191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
52201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
52211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
52231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
52241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52252235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
52261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
52281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
52291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
52301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
52311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
52321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
52348f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
52357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
52367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5237251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
52387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
52397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
52407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
52417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5245251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5246ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
5247ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5248ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5249ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5250ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
525130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
525230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
525330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
525430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
525530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
525630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
525730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
525830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
525930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
526030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
526130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
526230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
526330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
527126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
52725e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
52735e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5274ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
52755e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
52765e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
527726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
52785e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
52795e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
5281609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
5282777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
5283777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
5284777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5285777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
528626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
528726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
528826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
528926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
529026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
529126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
529226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
529326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
529490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
529526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
529626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5297e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5298e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
529990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
530090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
530190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
530290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
530390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
530490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
530590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
530690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
530790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
530890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
530926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
531026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
531126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
531226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
531326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
531426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
531526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53250af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
53260af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
53270af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
53280af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
53290af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
53300af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
53310af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
53320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
53330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
53340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
53350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
534515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
534615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5347609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
534815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
535015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5356609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
535815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
536515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
537115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
537215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
537590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
537690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
537790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
537890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
537990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
538090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
538190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
538290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
538390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
538490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
538590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5387777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5388777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
539390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
539490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
539590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
539690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
539790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
5401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ColorAspects aspects;
5402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mRange = (ColorAspects::Range)((data2 >> 24) & 0xFF);
5403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mPrimaries = (ColorAspects::Primaries)((data2 >> 16) & 0xFF);
5404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)((data2 >> 8) & 0xFF);
5405b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mTransfer = (ColorAspects::Transfer)(data2 & 0xFF);
5406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5408b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5412ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5418ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5420251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5421251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5422251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5423251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5424251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5425251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5426251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5432ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5433349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5434349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
54350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
54360806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
54370806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
54380806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
54390806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
544015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
544115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
544215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
54430806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
54440806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
544815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
544915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
545015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
545115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
545215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
545315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
545496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
545596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
545696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
545796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
545896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
545996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5471777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5473777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5474777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
5488d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
5489609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
54922d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
5495609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5506609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
55072d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
55095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5510a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
55115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55122d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
5513a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55167fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
55177fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
55187fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
55197fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
55207fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
55217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
55227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
55237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
55243831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
55252d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
55295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
55305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
55315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
55325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
55335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
55350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
55360806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
55370806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
55380806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
55390806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
55400806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
55410806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5549dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5550dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5551dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5552dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5560fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5561fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5562fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5563fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5564fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5565fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
55775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
55785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
55795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (buffer != info->mCodecData) {
5581ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
55845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                         buffer.get(), info->mCodecData.get());
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
55875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (converter == NULL) {
55885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
55895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
55905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
55915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
55925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
55930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
55940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5597078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5598ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5599078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
56005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5601ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
56025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5603078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5605ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5606ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5607d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5608ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5609ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5611078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5612349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5620054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5621054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5622054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5623054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5624054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5625054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5626054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5627054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5628054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5629054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
563215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
56330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
56340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode,
56350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    bufferID,
56360806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    0,
56375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info->mCodecData->size(),
56380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    flags,
563915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
564015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd);
564115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
56430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
56440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
56450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
56495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
56505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
56510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
56520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
56535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
56545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
56555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
56565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
56580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
56590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5660dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5661dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
56623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5663dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5664dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5666ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5667349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5668349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
566915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
56700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
56710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
56720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
56730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
56740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
56750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
567615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
567715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
567815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
56800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
56810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
56820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5686dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5690625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5691777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5692777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5693777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5694625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5695777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5696625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
573315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
573415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5735609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
57365778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5737349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
57390806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
57580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
57590806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
57600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
57610806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
57620806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
576315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
576415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
576515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
57660806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
57670806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
577390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
577490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
577590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
577690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
577790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
577890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
577990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
578090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
578115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
578215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
578315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
578415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
578515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
578615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
578715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5796a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5797a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5798609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
57995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5800349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
580115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
580215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
58030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
58040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
58060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
58095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
58105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
581131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5812577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
58131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
5814577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5815b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5816697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                // pretend that output format has changed on the first frame (we used to do this)
5817697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
58181734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
5819697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                }
5820b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
5821b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
58225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5823b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5824054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
5825054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
5826054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
5827054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
5828054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (info->mData->size() >= sizeof(grallocMeta)
5829054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
58307c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
5831054219874873b41f1c815552987c10465c34ba2bLajos Molnar                } else if (info->mData->size() >= sizeof(nativeMeta)
5832054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
58337c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
58347c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
58357c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
58367c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
5837054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
58387c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5839054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
5840308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
5841308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5842308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
58435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else if (info->mData == info->mCodecData) {
5844308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
58455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
58465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
58475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
58485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
58495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info->mCodecData, info->mData);
58505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
58515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
58535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
5854308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
5855496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
585621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
5857496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
5858496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
5859496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
58605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
586121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58638b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
58648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
58658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
58665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5869d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5870609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
58712d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
58725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5874609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
58795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
58805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
58835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
58845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
5886d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
5887dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5895777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
58960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
58970806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
58980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
59000806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5903777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5904777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5905777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5913609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
59150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
59160806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
59170806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
59180806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
59190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
59200806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
59210806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
59220806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5924577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
5925777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5926777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5927777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5928577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
5929577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5930b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t dataSpace;
5931b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (msg->findInt32("dataspace", &dataSpace)) {
5932b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = native_window_set_buffers_data_space(
5933b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
5934b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
5935b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5936b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
59396aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
594079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
59416fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
5942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
594490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
594590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
594690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
594790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
594890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
594990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
595090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
595190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5952fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
5953fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
5954c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
5955fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5956c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
5957fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
5958fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
5959fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
5960fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
59615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
5962fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
59630806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5964fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
596515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
59660806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
596715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
596815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
59690806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
5970cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5971cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
5972264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
5973251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5974cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
597515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
597615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
5977cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
59796fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
59806fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
598115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
598215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
59836fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
59846fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6014c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
6015609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
6016c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
601715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
601815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(
601915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                            mCodec->mNode, info->mBufferID, info->mFenceFd);
602015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
60210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
60220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
60230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
60240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
6026c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6031777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
60330806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
60340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
60350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60360806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6039777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6040777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6041777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6042777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6048f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6052c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
6053c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
6054ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6055ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
605623858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mCodec->mNodeBinder->unlinkToDeath(mDeathNotifier);
6057ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
6058ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
6059ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6060b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
6061ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
6062e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
6063ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
6064ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
6065ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
6066ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6067054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
6068054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
60695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
60705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6071ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6072c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6073c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6074f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
60875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
60885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
60895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
60905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
60915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
60925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6095c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6096c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6097c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
609854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
609954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
6100c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6102d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
6103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6106c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6112d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6116c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
612030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
612130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
612230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
612330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
612430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
612530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6135c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6136c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6137c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6138c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
61395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
61405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6141c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
61425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
61435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6144ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
61455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
614748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
614848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
614948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
615048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61541d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6155ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6156b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
61575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
6161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
61627791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
61635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6164b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6165b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6166b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6167afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
61685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
61695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
61705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
61715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
61725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
61735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
61745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6175b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
61765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
61775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6178b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6179e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
61805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
61811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
61821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6183ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
61841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6185201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
61861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
61871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6188b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6189b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6191da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6192078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6193078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
619423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node);
6195078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
61981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
61997a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
62007a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
62011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
62021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6203ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
62041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
62051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6206ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
62075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
62089f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
62099f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
62105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
62119f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
62125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6213c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
621452e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6216c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
621823858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
621923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    if (mCodec->mNodeBinder == NULL ||
622023858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen            mCodec->mNodeBinder->linkToDeath(mDeathNotifier) != OK) {
622123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // This was a local binder, if it dies so do we, we won't care
622223858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // about any notifications in the afterlife.
622323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mDeathNotifier.clear();
622423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
622523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
622626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
623090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6231ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6232ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6233ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6234ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
62351713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
62360167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6237ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6238ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6239afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
6240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
6242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
62445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6245d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
62465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
62475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
62485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
62535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
62545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6264f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6265f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6266f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6267f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6268f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6269054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6270054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6271a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6272e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6273e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
62744e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
6275054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
628454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6285f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6286f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6287c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6290c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
62910806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
6292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
629654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
629754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
6298d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
629954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
630054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
630154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
63157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
63167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
63177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
63187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
63197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
63207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
63217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
63228f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6323d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
63248f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6325d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6326d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6327d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6328d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6331c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6332c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6336c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6340c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
634254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6343c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6345c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6347c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6350c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6352d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
6354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6355c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6356c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6358c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6359c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6360c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6366c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
63675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
63685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
63695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6370ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
63715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
63720806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
63735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
63740806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
63750806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
63760806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
63770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
63780806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
63795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6380c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6381c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6382c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6383251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6384c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
63855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
63885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6389d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
6390e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
6391e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
63925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
63935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6394c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6395c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
63965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
63975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6398d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6399d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
6400a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6401d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
6402a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
6403a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
6404a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
6405a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
6406a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
6407a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
6408a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6409a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6410a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6411a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
6412a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
6413a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
6414d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6415a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6416a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6417a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6418d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
641994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
642094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
642194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
642294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
642394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
642494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
642594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
642694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
642794ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
642872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
642972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
6430d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
64312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
64322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
64332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6434d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
643537b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
643637b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
643737b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
643837b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
643937b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
644037b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
644137b2b389139ed638831e49708c947863eef631efRonghua Wu
644237b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
644337b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
644437b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
644537b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
6446d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
644737b2b389139ed638831e49708c947863eef631efRonghua Wu        }
644837b2b389139ed638831e49708c947863eef631efRonghua Wu    }
644937b2b389139ed638831e49708c947863eef631efRonghua Wu
6450d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
64512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
64522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
64532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
64542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
64552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
64562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
64572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
64582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
64592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
64602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
64612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
64622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
64632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
64642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
64652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
6466d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
64672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
64682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
646972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6470d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
647172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
647272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
647372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
647472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
647572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
647672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
647772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
647872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
647972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
648072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
648194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
648294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
6483d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
648494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
648594ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
648694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6487c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6488c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    if (mCodec->mOMX->getParameter(
6489c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6490c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6491c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6492c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6493c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6494c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6495b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6496b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
6497b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInternalOption(
6498b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, IOMX::INTERNAL_OPTION_COLOR_ASPECTS,
6499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                colorAspectsBuffer->base(), colorAspectsBuffer->capacity());
6500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6501b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6502b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6503b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6504b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6505b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6506d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6507d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6508d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6509d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6510d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6511d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6512d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6513d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6514d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
6515d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
652157fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar
6522d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->createInputSurface(
6525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, dataSpace, &bufferProducer, &mCodec->mInputMetadataType);
6526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6527d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6528d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6529d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6530d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6531d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
65327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
65337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
65347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
65357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
65367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
65377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
65387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
65397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
65407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
65417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
65427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
65437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
65447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
65457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
65468f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
6547d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
65488f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6549d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6550d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6551d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
6552d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6553d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6554d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6555d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6556d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
6562b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6563b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6564b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInputSurface(
6565b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
6566b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                &mCodec->mInputMetadataType);
6567b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6568d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6569d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6570b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        surface->getBufferConsumer()->setDefaultBufferDataSpace(dataSpace);
6571d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6572d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6573d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6574d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
6575d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6576d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6577d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
65788f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6579d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
6580d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
6581d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6582d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
6583d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6584d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6585c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
65865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
65875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
65880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
65890806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
65900806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
65910806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
65920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
65930806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6598f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6602f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
66033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6605cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6606cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
660729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6608cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6609cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6610cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6611251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
661291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6613c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        mCodec->mOMX->sendCommand(
6614c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6615c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6616c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6617c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6618c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6619c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6620c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6621c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
662291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6623cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6626f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
6634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6636f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
663872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
66466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
66476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
66486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
66496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
66506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
66516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
66526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
66536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
66546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
66556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66566463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
66576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
66586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
66596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
66606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
6661d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
66626463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
66636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
66646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6671f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
66760806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
66770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
66780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
66790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
66800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
66810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
66820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
66830806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66850806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
66860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
66870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
66880806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66900806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
66910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
66920806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
66930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
66940806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6706f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6710f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
67113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6714f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
671672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6723d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6724d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6725d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6726d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6727d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6728d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6729d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6730d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6731d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
6732d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6733d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6734d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
6735d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6736d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6737d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6738d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
67396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
67406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
67416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
67426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
67436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
67446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6750f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
67550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
67560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
67570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
67580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
67590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
67600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
67610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
67620806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6777f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6778349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6779349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6782f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6783ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6794054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
67984dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
67994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6800054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
68040806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
68090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
68100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
68110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
68120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
68130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
68140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
68200806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
68210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
68220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
68230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
68240806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68270806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6828349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
682915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
683015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
683115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
68320806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
68330806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
68340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
68350806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
68390806340688c937e7b78c2d89db3809274130df4eLajos Molnar
68400806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
68410806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68420806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6846c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6847054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6852f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6853349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
68540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6855349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6856349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6857349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68603cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6861777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6862777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6863777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6864777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
68653cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
68663cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
68673cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
68683cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
68693cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
68703cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6871349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6872349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6875f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
68763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
687890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
6880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6882f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6888c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6889c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6890c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6891c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6892c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
689354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6894c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6895c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6896349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6897349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
68980806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
68990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
69000806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
69010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
69020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
69040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
69050806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
69070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
69157a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
6916ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
6917d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
6918d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6919d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
6920d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6921d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
6922d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6923349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6924349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
69250806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
69260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
69270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69280806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
69300806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
6937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
6939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6944496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
6945496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
6946496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
6947496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
6948496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
6949496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
6950496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6951496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
6952496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
6953496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
6954496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6955a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
6956a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
6957a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
6958a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
6959a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6960a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
6961a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6962a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
6963a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
6964a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
6965a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
6966a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
6967a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6968a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
6969a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
6970a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6971a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
69727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
69737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
69746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
69757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
69767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
69777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
69787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
69794dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6980054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
69814dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
69824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
69834dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
6984054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
69854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
6986054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
69874dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
69884dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
69894dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
69904dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
69914dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7000a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
7001a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
7002530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
7003a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7004a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
7005a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
7006a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
7007a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7008a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
7009a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
7010a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
7011a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
7012a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
7013a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7014a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
7015a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7016a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
7017a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7018a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
7019a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7020a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
7021a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
702272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
702372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
702472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
702572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
702672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
702772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
702872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
702972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
703072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
703172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
703272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
703372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
703472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
703572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
703672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
703772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7038e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
7039e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
7040e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
7041e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
7042b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
7043b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
7044e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
7045e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
7046e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
7047e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
7048b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
7049b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7050b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7051b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7052b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7053b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7054b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
7055b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7056b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7057b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7058b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7059b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7060b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7061b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7062b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7063b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7064e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7065e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
70668db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
70678db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
70688db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
70698db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
70708db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
70718db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
70728db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
70738db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
70748db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7075870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7076870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7077870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7078870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7079870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7080870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7081870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7082870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7083870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7084870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7085870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
7086a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
7087a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7088a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
70896507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
70906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
7091d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
70926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
70936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
70946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
70956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
70966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
70976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
70986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
70996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
710090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
710190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
710290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
710390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
710490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7105f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7112b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7113b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
711431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7115054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
7117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
7118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7121349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7124b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7125b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7126ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7145f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7150f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7161f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7168349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7169e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7171349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
71723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7173349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7174349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7188f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
71893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
719490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
719590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
719690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
719790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
719890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7199f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
72050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
72060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
72070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
72080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
72130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
72140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
72150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
72160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
72170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
72180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
72190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
72220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
72230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
72240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
72270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
72280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
72290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
72300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7231cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
72320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7233251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7234d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7235755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7236755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7237755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7238755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7239755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7240755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7241755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7242755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7243cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7247777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7248777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7249777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7250777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7254349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7255349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7256349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7257349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7273f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
72745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
72755778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
72860806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7306f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
73073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
730831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
73095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7310b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7313f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
73180806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
73190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
73200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
73210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
73220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
73230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
73250806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
73285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7334349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7335349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7336349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7337349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7338349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7339349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7340349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
73450af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7346f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
73475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
73480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
73490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
73500806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
73510806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
73520806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
73530806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
73540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
73550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
73560806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73580167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
73590167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7360bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7361bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7362bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7363bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7364b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7365bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7366bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
73670806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
73680806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
73700806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
73710806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7376f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7383f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7392f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7396f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
74120806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7424f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
74253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7428f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
74330806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
74340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
74350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
74360806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
74370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
74380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
74390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
74400806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7454f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7458f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
74593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7464f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7489f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
7490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7491ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
7492ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
7493d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
74970806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
74980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
74990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
75000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
75010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
75020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
7505777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
7506777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
7507777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
7508777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
7509777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
7511e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
75120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
7513e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
7514e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
7515777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
7516777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
7517777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
7518777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
7519777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
7520777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7521777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
7524777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
7525777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
7526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7531349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7532349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
75331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
7534349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
7535609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
7536349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
7537349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
7538349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
7539349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
75403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
7541349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
7542349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7543349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
7544349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7545349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7546349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7547349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
7553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7555f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
7556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7561f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
7562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7567f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
7568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
7569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
7570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
75717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
75727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
75737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
75747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
757590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
757690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
7578d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
7579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
7580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
7582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
7583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7584dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
7585dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
7586f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
7587f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
7588f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
7589f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
7590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
7591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
75955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
75965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
75975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
75985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    const char *role = getComponentRole(isEncoder, mime.c_str());
75995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
76005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
76015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
76045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = client.connect();
76055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
76105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
76115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    IOMX::node_id node = 0;
76125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
761323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    err = omx->allocateNode(name.c_str(), observer, NULL, &node);
76145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
76165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    err = setComponentRole(omx, node, role);
76205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        omx->freeNode(node);
76225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
76235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
76275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
76285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
76305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
76315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
76325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
76335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76346e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76356e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
76365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
76385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
76395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
76436e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
76446e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
76456e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
76466e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
76476e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
76486e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
76495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
76525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
76535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
76545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
76555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
765636e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
76575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
76586e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76596e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
76605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
76615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoPortFormat,
76625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
76635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
76645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
76655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
76685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (isFlexibleColorFormat(
76695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    omx, node, portFormat.eColorFormat, false /* usingNativeWindow */,
76705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
76715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
76725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
76735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
76745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
76755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
76765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
76775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
76785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
76795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
76805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
76815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
76825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
76835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
76845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
76856e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
76866e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
76876e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
76886e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
76896e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
76906e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
76915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
76935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
76945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
76955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
76965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
76976e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76986e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
76995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
77005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
77015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
77025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
77035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
77045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
77055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
77065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
77076e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
77086e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
77096e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
77106e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
77116e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
77126e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
77135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
77165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
77175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
77185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
77195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
77235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
77245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->configureVideoTunnelMode(
77255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
77265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
77275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
77285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
77295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        } else if (omx->storeMetaDataInBuffers(
77305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE) == OK ||
77315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            omx->prepareForAdaptivePlayback(
77325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE,
77335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
77345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
77355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
77395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
77405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
77415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
77425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
77435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->getConfig(
77445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
77455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
77465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
77475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
77515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    omx->freeNode(node);
77525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
77535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
77545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
77555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7756a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
7757a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
7758a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
7759a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
7760a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
7761a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
7762a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
7763a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7764a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
7765a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7766a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7767a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7768a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
7769a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7770a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7771a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7772a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7773a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
7774a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7775a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7776a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
7777a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
7778a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7779a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
7780a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7781a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7782a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7783a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
7784a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
7785a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7786a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
7787a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7788a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7789a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7790a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7791a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7792a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7793a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7794a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
7795a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7796a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7797a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7798a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7799a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7800a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7801a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
7802a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7803a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
7804a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7805a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7806a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7807a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7808a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7809a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7810a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
7811a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
7812a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7813a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
7814a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
7815a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
7816a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7817a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
7818a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
7819a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
7821