ACodec.cpp revision 1d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ce
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"
567e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include "include/SharedMemoryBuffer.h"
5773dd808754c641fe798273d356ee38368715fa7bLajos Molnar#include "omx/OMXUtils.h"
58496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
596d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang#include <android/IGraphicBufferSource.h>
606d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
61f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangusing binder::Status;
646d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
656e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnarenum {
666e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar};
686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangstatic inline status_t statusFromBinderStatus(const Status &status) {
996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (status.isOk()) {
1006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return OK;
1016d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1026d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err;
1036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.serviceSpecificErrorCode()) != OK) {
1046d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.transactionError()) != OK) {
1076d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1086d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1096d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Other exception
1106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return UNKNOWN_ERROR;
1116d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
1126d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
114251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
117251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
12626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
12726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
12826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
129984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    virtual ~MessageList() {
130984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    }
13126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
13226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
13326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
13426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
13526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
13626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
13726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
1385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnarstatic sp<DataConverter> getCopyConverter() {
1395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
1405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static sp<DataConverter> sCopyConverter;        // zero-inited
1415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
1425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return sCopyConverter;
1435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar}
1445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
15326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
154984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        if (messages.empty()) {
155984a54322f7c70bc75e862d91bdd975814872affLajos Molnar            return;
156984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        }
157984a54322f7c70bc75e862d91bdd975814872affLajos Molnar
158984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        sp<AMessage> notify = mNotify->dup();
15926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
16126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
16226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
16526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
16626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
16726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
16826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
17026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
17126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
17226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
17326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
17626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
17726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
17826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
17926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
18026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
18326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
18426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
18626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
18826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
18926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
19126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
19226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
19426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
19526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
19626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
19726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
19826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
20026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
20126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
20490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
20590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
20690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
20790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
20890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
20990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
21090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
21190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
21226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
21326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
21426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
21526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
21626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
21726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
21826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
21926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
234090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
25726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
26126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
26226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
26326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
26426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
26526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
26615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
27215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
27315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
27690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
285090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit DeathNotifier(const sp<AMessage> &notify)
286ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
287ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
288ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
289ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
290ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
291ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
292ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
293ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
294ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
295ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
296ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
297ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
298ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
299ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
300ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
301ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
303090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit UninitializedState(ACodec *codec);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
314ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
321090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedState(ACodec *codec);
322c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
328c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3328f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
336d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
337d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
340c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
344090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedToIdleState(ACodec *codec);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
360090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToExecutingState(ACodec *codec);
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
374090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingState(ACodec *codec);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
377054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
385349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
386349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
39390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
396349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
397349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
404090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit OutputPortSettingsChangedState(ACodec *codec);
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
41290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
421090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingToIdleState(ACodec *codec);
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
443090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToLoadedState(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 Huberprivate:
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
458090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit FlushingState(ACodec *codec);
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
48015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
48115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
48215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
48315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
48415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
48515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
48615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
48915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
49015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
49115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
49215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
49315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
49415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
49515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
49615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
49715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
49815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
49915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
50015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
50215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
50315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
50415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
50515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
50615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
50815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
50915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
51015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
511f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
512b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    : mSampleRate(0),
513b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen      mQuirks(0),
514d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang      mNodeGeneration(0),
515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
516e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
517fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
5188db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
519c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
520346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5219806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
52254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
523f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang      mIsLegacyVP9Decoder(false),
5249806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5259806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
526e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5279806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
528054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
529054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
530054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mInputMetadataType(kMetadataBufferTypeInvalid),
531054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mOutputMetadataType(kMetadataBufferTypeInvalid),
532011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
533054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
53594ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
53737b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
5382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
539609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
540ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
5418338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
542db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
543db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0) {
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
545c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
558dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
560fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
561fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
565f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
572f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
578a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5791d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
580a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
581a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
582a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
583a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5905778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5921d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
6071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
6101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
6117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6138f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
614d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
6158f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
616d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
617d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
618d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
619d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6211d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6245778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
628f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6297a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6301d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
633f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6381d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
640c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
64130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
64230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6431d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
64430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
647496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
649496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
650496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6554dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
656054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
658054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
659054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
673e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
692e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
693098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    // no need to reconnect as we will not dequeue all buffers
694098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(
695098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            nativeWindow, &usageBits,
696098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            !storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment /* reconnect */);
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
701f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
702e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
703e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
704e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
705e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
706e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
707e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
737dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
738dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
739dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
745054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
746011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
748598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa            ALOGV("skipping buffer");
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
763054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
76515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
76915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
77015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
783484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
784484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
785484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
786484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
787484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
789e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
7901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
801054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()) {
802054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
812d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
815054219874873b41f1c815552987c10465c34ba2bLajos Molnar            MetadataBufferType type =
816054219874873b41f1c815552987c10465c34ba2bLajos Molnar                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
8175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
8183e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            if (type == kMetadataBufferTypeANWBuffer) {
819054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
8203e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            } else if (type == kMetadataBufferTypeNativeHandleSource) {
8213e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                bufSize = sizeof(VideoNativeHandleMetadata);
822054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
823054219874873b41f1c815552987c10465c34ba2bLajos Molnar
824054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // If using gralloc or native source input metadata buffers, allocate largest
825054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // metadata size as we prefer to generate native source metadata, but component
8265fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // may require gralloc source. For camera source, allocate at least enough
8275fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // size for native metadata buffers.
8285b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t allottedSize = bufSize;
8293e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            if (portIndex == kPortIndexInput && type == kMetadataBufferTypeANWBuffer) {
830054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
8315fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
8325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                bufSize = max(bufSize, sizeof(VideoNativeMetadata));
8335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
8345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8355b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
845054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
846054219874873b41f1c815552987c10465c34ba2bLajos Molnar
84728edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
84828edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            ALOGV("[%s] Allocating %u buffers of size %zu/%zu (from %u using %s) on %s port",
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
851054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8545b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
8555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
85628edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
85728edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
85828edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
85928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
86028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
86128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
8625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
8635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
86434e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
86534e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
86634e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
86728edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
8695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8717e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            const sp<AMessage> &format = portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
872054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
873054219874873b41f1c815552987c10465c34ba2bLajos Molnar                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
8745581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
875777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
876777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
878ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
879ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
88015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
88190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
882a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                info.mNativeHandle = NULL;
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
884afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
885afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
886b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        ? kRequiresAllocateBufferOnInputPorts
887b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        : kRequiresAllocateBufferOnOutputPorts;
8881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
889e33d922fd86699c664a15f09e6d8b2e422736a40Lajos Molnar                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
890ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
891ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
892a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
8931b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    sp<NativeHandle> native_handle;
894d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->allocateSecureBuffer(
895d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            portIndex, bufSize, &info.mBufferID,
896a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
897a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
898a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY: this representation is unorthodox, but ACodec requires
899a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // an ABuffer with a proper size to validate range offsets and lengths.
900a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // Since mData is never referenced for secure input, it is used to store
901a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // either the pointer to the secure buffer, or the opaque handle as on
902a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // some devices ptr is actually an opaque handle, not a pointer.
903a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
904a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY2: use native handle as the base of the ABuffer if received one,
905a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // because Widevine source only receives these base addresses.
9061b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    const native_handle_t *native_handle_ptr =
9071b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                        native_handle == NULL ? NULL : native_handle->handle();
9087e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    info.mData = new MediaCodecBuffer(format,
9097e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                            new ABuffer(ptr != NULL ? ptr : (void *)native_handle_ptr, bufSize));
9101b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    info.mNativeHandle = native_handle;
9115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = info.mData;
912ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
913d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->allocateBufferWithBackup(
914d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            portIndex, mem, &info.mBufferID, allottedSize);
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
916d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->useBuffer(portIndex, mem, &info.mBufferID, allottedSize);
917ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
918ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
919ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
9207e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    info.mCodecData = new SharedMemoryBuffer(format, mem);
9215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecRef = mem;
9225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
923054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (type == kMetadataBufferTypeANWBuffer) {
924054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
925054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
9265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
9275b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // if we require conversion, allocate conversion buffer for client use;
9285b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // otherwise, reuse codec buffer
9295b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (mConverter[portIndex] != NULL) {
9305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        CHECK_GT(conversionBufferSize, (size_t)0);
9315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mem = mDealer[portIndex]->allocate(conversionBufferSize);
9325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        if (mem == NULL|| mem->pointer() == NULL) {
9335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            return NO_MEMORY;
9345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        }
9357e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                        info.mData = new SharedMemoryBuffer(format, mem);
9365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = mem;
9375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else {
9385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = info.mCodecData;
9395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = info.mCodecRef;
9405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
9441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
9451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
953d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
956eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
957eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
958eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
960eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
961a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        desc->addBuffer(info.mBufferID, info.mData, info.mNativeHandle, info.mMemRef);
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
964eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
971098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
972098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        bool reconnect) {
9731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
977d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
978d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
9791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
9811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
985d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
9861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
9871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
9881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
9891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
9901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
9921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
9941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
9951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
997f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
998e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
999b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
1000fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
1001fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
1002fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
10031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
10041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
10051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
10061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
10071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
10081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
10091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
1010098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            usage,
1011098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            reconnect);
10121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
10131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
10151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
1016098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        OMX_U32 *minUndequeuedBuffers, bool preregister) {
1017098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar
10181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
10191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
10201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
10211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1022d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
1023d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
10241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
1026098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        err = setupNativeWindowSizeFormatAndUsage(
1027098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar                mNativeWindow.get(), &mNativeWindowUsageBits, preregister /* reconnect */);
10281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
1030e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
10311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
10321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1034ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
1035ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
1036ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
1037ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1038ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1039ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
1040d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1041d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1042ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1043ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
1044ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
1045ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
1046ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
1047ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1048ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1049054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
1050258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
1051258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1052054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
1053258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1054258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
105529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1056258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
1057258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
1058258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1059258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1060e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
1061e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
10621faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
10631faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1064e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1065e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
1066e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
1067e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1068e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
1069e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
1070e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
10711faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
10721faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1073e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
1074e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1075258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1076d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1077d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1078258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1079e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1080e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1081e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1082e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1083e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1084609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1085e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1086e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1087e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1088258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1089258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1090258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1091258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
109629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1109098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1112e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1113054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1114054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
11153298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
11163298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
11173298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
11183298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1119609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1124054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
11258ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
112615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
112715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
112929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
113474006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
113574006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
113615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
113715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
113890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
113974006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
114074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
114174006804065941841883c4b46ee785070164023fJamie Gennis
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
1143d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->useGraphicBuffer(
1144d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, graphicBuffer, &bufferId);
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1146609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
114774006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
115274006804065941841883c4b46ee785070164023fJamie Gennis
1153609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
116574006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1167054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1168054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
11743175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
11753175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
11763175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
11773175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
11783175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
11793fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1182054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
11833298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
11843298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
11853298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
11863298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1190054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1192054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1193098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers,
1194098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            mLegacyAdaptiveExperiment /* preregister */);
1195054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1196054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1197e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1198054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1199e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1200e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1201e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1202054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1203054219874873b41f1c815552987c10465c34ba2bLajos Molnar            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
120428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar    size_t totalSize = bufferCount * align(bufSize, MemoryDealer::getAllocationAlignment());
1205e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1206e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1207e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
1208e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1209e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1210e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
121115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
121290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1213e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1214e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1215e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1216054219874873b41f1c815552987c10465c34ba2bLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
12175581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
1218777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
1219777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1220054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1221054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1222054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
12237e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        info.mData = new SharedMemoryBuffer(mOutputFormat, mem);
12245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mMemRef = mem;
12255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
12265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecRef = mem;
1227e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1228e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
1229d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->useBuffer(
1230d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, mem, &info.mBufferID, mem->size());
1231e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1232e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1233e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1234e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1235e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1236e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1237011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1238e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1239011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1240011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1241011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1242011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1243011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1244011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1245011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1246011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1247011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1248e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1249e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1250011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
125115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd;
125215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1253011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1254011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1255011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1256011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1257011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1258011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1259d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            mOMXNode->updateGraphicBufferInMeta(
1260d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    kPortIndexOutput, graphicBuffer, info->mBufferID);
1261e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
126215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1263e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1264011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1265011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1266011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1267011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
12683175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (info->mStatus == BufferInfo::OWNED_BY_US) {
12693175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                status_t error = cancelBufferToNativeWindow(info);
12703175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                if (err == OK) {
12713175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                    err = error;
12723175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                }
1273011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1274011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1275011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1276011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1277011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1278011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1279011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1280054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1281054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1282054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1283054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1284054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1285054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1286054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1287054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1288054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1289054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
12900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1291054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
12920806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1293054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1294609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1295054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1296054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1297054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
129815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
1299d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
130015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1301777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1302777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1303777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1304054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1305777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1306054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1307054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
130815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
130915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
131015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
131115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
131215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
131315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
131415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
131515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
131615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
131715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
13180806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
13190806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
13200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
13210806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
13220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
13230806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
13240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
13250806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
13260806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
13270806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
13280806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13290806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13300806340688c937e7b78c2d89db3809274130df4eLajos Molnar
13310806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
13320806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
13330806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
13340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
13350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
13360806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
13370806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
13380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
13390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
13400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
13410806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13420806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13430806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1347609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
135215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
135315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13553fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
13563fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
13570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13603fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
136490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
136590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
136690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
136790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
136890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
136990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
137090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
137190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
137290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
137390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
137490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
137590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
137690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
137790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
137890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
137990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
138090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
138190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = mNotify->dup();
138290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
138390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
138490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
138590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
138690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
138790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
138890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1389604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1390604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1391604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1392604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1393604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1394604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
139590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
139690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
139790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
139890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
139990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->post();
140090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
140190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
140290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1403f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
14048ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1405054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1406ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1407ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1408ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1409ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1410ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1411ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1412ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1413346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1414346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1415346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1416346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1417346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
141815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1419dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
142015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
142115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
142215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1423dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1424dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1426dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1427b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1428b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1429dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1430dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1431dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
143290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1433dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1434dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1435dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1436dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1437dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1438dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1439dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1440dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1441dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1442dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1443dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1444dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
144590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1446dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1447dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
144815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
144990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1450dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1451dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1452dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1454dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1455dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1456dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1457dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1458dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1459054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1460dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1461dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1462dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1463dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1464dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1465dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1467dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1468054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1469dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1470dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1471b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1472b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1473dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1474dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1475054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1476054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1477054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14840806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
14850806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
14860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
14870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1488054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1489054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
14910806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
14920806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
149315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
149490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
149590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1496d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1497d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mOMXNode->updateGraphicBufferInMeta(
1498d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            kPortIndexOutput, oldest->mGraphicBuffer, oldest->mBufferID);
1499054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1500054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1501054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata *grallocMeta =
15027e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->data());
1503054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1504054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1505054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
15067c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)grallocMeta->pHandle,
15077e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                oldest->mGraphicBuffer->handle, oldest->mData->data());
1508054219874873b41f1c815552987c10465c34ba2bLajos Molnar    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1509054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata *nativeMeta =
15107e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->data());
1511054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1512054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1513054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
15147c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)nativeMeta->pBuffer,
15157e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->data());
1516054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
15190806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1523777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1524938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1525938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1526777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1527777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1528777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1529777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15320806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1534777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1537349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1538777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1539938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1540938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15442ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
15452ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
15462ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
15472ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1548777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1549777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1550777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1551777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1555777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
15600806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
156315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    MetadataBufferType type =
156415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
156515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
156615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
156715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
156815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
156915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
157015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
157115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
157215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
157315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
15740806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
15750806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
15760806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
15770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
15780806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
15790806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15810806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1582d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
15830806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
15840806340688c937e7b78c2d89db3809274130df4eLajos Molnar
15850806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
15860806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
15870806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
15880806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
159215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
159315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
159415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1595604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1596604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1597604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1598604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
159990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1600d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    // remove buffer even if mOMXNode->freeBuffer fails
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1602777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1605f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
16060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1618777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
16241ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime);
16255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
16265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
16275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
1628d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = SetComponentRole(mOMXNode, role);
16295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
16305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
16315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
16325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
16335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
16345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
16355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1643b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1644b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1645b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1646e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1649054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mInputMetadataType = kMetadataBufferTypeInvalid;
1650054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mOutputMetadataType = kMetadataBufferTypeInvalid;
16518db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
16592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
16602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
16612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
166596bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    // propagate bitrate to the output so that the muxer has it
166696bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    if (encoder && msg->findInt32("bitrate", &bitRate)) {
166796bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
166896bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
166996bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("bitrate", bitRate);
167096bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("max-bitrate", bitRate);
167196bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    }
167296bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar
1673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
16753e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
16763e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && storeMeta != kMetadataBufferTypeInvalid) {
16773e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mInputMetadataType = (MetadataBufferType)storeMeta;
1678d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->storeMetaDataInBuffers(
1679d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1681054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1682308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1684054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
16853e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        } else if (storeMeta == kMetadataBufferTypeANWBuffer
16863e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                && mInputMetadataType == kMetadataBufferTypeGrallocSource) {
16873e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            // IOMX translates ANWBuffers to gralloc source already.
16883e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mInputMetadataType = (MetadataBufferType)storeMeta;
1689054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1690c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1691c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1692d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
1693d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1694c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1695c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1696c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1697c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1698054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1700308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
17013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
17023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
17033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
17043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
1705d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getExtensionIndex(
1706d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
17073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
17093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
17103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
17113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
17123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1713d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(index, &params, sizeof(params));
17143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
17173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
17183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
17193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
17213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
17233a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1724308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1725308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1726308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1727308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
17288db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1729308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1730308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
17313e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
1732308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1733308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
17343e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mOutputMetadataType = kMetadataBufferTypeNativeHandleSource;
1735d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->storeMetaDataInBuffers(kPortIndexOutput, enable, &mOutputMetadataType);
1736308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1737308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1738308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1739308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1740a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1741a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1742a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1743a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1744a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1745a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
174694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
174794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
17482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
17492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
17502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
175137b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
175237b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
175337b2b389139ed638831e49708c947863eef631efRonghua Wu        }
175437b2b389139ed638831e49708c947863eef631efRonghua Wu
17552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
17562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
175794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
175872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
175972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
176072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
176172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
176272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
176372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1764308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1765308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
17663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
17680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
17693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1770b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1771011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1772e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
17741713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
17751713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
17761713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
17771713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
17781713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
17791713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
17801713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
17811713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
17821713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
17831713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1784a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1785a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        if (mFlags & kFlagIsSecure) {
1786a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            // use native_handles for secure input buffers
1787d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->enableNativeBuffers(
1788d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
1789a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            ALOGI_IF(err != OK, "falling back to non-native_handles");
1790a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = OK; // ignore error for now
1791a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1792e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
17933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
17941de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
17951de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
17965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17976597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
17986597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
17996597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
18006597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
18016597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
18026597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
18036597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
1804d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t temp = mOMXNode->setConfig(
1805d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
18066597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
18076597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
18086597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
18096597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
18106597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
18116597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
18126597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
18136597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
18146597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
18155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
18165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
18175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
18185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1819ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
18205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
182197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
182297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
18235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
18245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
18265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
182797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
18285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
18295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1830fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1831fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1832d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1833d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1834d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1835d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1836d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mOMXNode->prepareForAdaptivePlayback(
1837d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1838d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1839d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1840d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
18413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
18423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1843d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1844d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1845d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1846d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1847d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1848d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
18495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1850ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1851ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1852ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
18533fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
18543fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
18553fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
18563fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
18573fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
18583fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
18593fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
18603fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
18613fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
18625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
18633e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mOutputMetadataType = kMetadataBufferTypeANWBuffer;
1864d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->storeMetaDataInBuffers(
1865d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
18665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
18675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1868fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
18705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
18715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
18725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
18735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
18755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
18765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
18775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
18785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
18795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
18815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
18825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
18835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
18845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
18855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
18865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
18875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
18885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
18895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
18905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
18915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
18935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
18945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
18955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
18965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
18975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
18985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1899d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->prepareForAdaptivePlayback(
1900d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
19015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
19025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
19035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
19045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
19065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
19075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
19085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
19095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1910e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
19115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
19125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
19135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
19145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
19155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
1916054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
1917011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1918011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1919011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
19205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1921fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
19220167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
19235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
19245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
19255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
19265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
19275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
19280167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1929e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1930e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1931e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1932e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1933e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1934e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1935e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
19385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
19395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
19405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
19415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
1942308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
19433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
19443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
19453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
19463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
19473a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
19483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
1951b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1953b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
19573a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
19583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19593a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
19611de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
19623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
19653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1966777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1967777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1968777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1969777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
19703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
19723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
19733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
19743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
19753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1976777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1977777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1978777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1979777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
19813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1982777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1983777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
19873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
19881ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                if (!IsFlexibleColorFormat(
1989d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
19903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
19913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
19923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
19933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
19943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
1995e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
19963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
19973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
1998054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (storingMetadataInDecodedBuffers()) {
1999d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        err = mOMXNode->storeMetaDataInBuffers(
2000d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
2001054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
20023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
20033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
20043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
20053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
2007d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        err = mOMXNode->enableNativeBuffers(
2008d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
20093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
20113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
20123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
20133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
2014b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
2015b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
20183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
20193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
20223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
20233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
202442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
202542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
202642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
202742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
202842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
202942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
203042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
203142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
203242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
203342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
203442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
203542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
203642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
2037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2043aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
2044b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
20458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
20462965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
20478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
2048ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
2049ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
2050ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
2051aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
2052aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
2053aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
2054b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2055b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
2056b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
2057ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
20598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
20608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20612965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
20622965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
20632965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
20642965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
20658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
20668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
20688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
20708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
20728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
20748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
20768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
20788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
20808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
20828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
20848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2086ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
20874471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
20882965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
20892965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2091729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2093729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2095729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2096729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2097729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2098729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2099729de186450f78c099637e1fce743fe531862c52Andreas Huber
2100729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
210417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
210517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
210617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
210717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
210817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2111ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
21122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
21132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
21142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
21152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
21162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
21172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
21182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2119516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2120cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2121cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2122516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2123cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
21242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2125516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2126516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2127516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
21292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2130516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2131516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2132516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
21342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
21352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2136516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2137516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
21382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2139ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2140ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2141ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2142ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2143ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2144ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2145ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
21465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2147ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
214897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
214997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
215097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
215197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
215297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
215397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
215497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
215597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
215697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
21578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
21588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
21598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
21608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
21618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
21628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
21638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
21648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
21658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2167729de186450f78c099637e1fce743fe531862c52Andreas Huber
21684471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
21694471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
21704471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
21714471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
21728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
21738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
21748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
21759806555d3930be43e11106281dee354820ac1c88Andreas Huber
21768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
21778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
21788b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
21798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
21809806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
21819806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
21829806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
21839806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
21849806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
21859806555d3930be43e11106281dee354820ac1c88Andreas Huber
2186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21938b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
21948b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
21958b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
21968b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21978b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2198ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2199ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2200ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2201ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2202ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2203ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2204ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2205ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2206ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2207ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2208697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
22094e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2210b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // trigger a kWhatOutputFormatChanged msg on first buffer
2211b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
22124e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2213777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2214777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2215777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2216777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2217777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2218777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2219777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2220777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
22215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // create data converters if needed
22235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!video && err == OK) {
22245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
22255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (encoder) {
22265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22275b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
22285b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexInput] != NULL) {
22295b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
22305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        } else {
22325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
22345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexOutput] != NULL) {
22355b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
22365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
22385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
22395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
22448b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
22458b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
22468b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
22488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
22498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
2250d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t temp = mOMXNode->setConfig(
2251d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigPriority,
22528b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
22538b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
22548b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
22558b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22568b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
22578b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
22588b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2259ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2260ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2261ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2262ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2263ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2264ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2265ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2266ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2267ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2268ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2269ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2270ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2271ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2272ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2273ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2274ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2275ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2276ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2277ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2278d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2279d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2280ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2281ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2282ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2283ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2284ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2285ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2286ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2287870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2288870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2289870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2290870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2291d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getConfig(
2292d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2293870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2294870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2295870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2296870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2297870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2298870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2299870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2300870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2301870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2302870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2303d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2304d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2305870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2306870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2307870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2308870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2309870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2310870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2311870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2312870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2313870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2314870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2315870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2316d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2317d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2318870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2319870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2320870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2321870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2322870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2323870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2324870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2325870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2326870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2327870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2328870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2329870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2330870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2331870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2332870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2333870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2334870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2335d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2336d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2337870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2338870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2339870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2340870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2341870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2342870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2343870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2344870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2345870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2346870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2347870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2348870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2349870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2350870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2351870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2352870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2353870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2354870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2355870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2356870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2357870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2358870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2359870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2360870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2361870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2362870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2363d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2364d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
2365870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2366870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2367870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2368870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2369870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2370870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2371870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2372870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2373870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2374d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2375d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh,
2376d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &refreshParams, sizeof(refreshParams));
2377870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2378870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2379870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2380870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2381870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2382870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2383870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
23840f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnarstatus_t ACodec::configureTemporalLayers(
23850f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) {
23860f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!mIsVideo || !mIsEncoder) {
23870f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return INVALID_OPERATION;
23880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString tsSchema;
23910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!msg->findString("ts-schema", &tsSchema)) {
23920f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return OK;
23930f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23940f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23950f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numLayers = 0;
23960f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numBLayers = 0;
23970f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    int tags;
23980f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    char dummy;
23990f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
24000f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
24010f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
24020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0) {
24030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
24040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
24050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                    &numLayers, &dummy, &numBLayers, &dummy))
24060f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && (tags == 1 || (tags == 3 && dummy == '+'))
24070f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
24080f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        numLayers += numBLayers;
24090f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
24100f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
24110f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
24120f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
24130f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24140f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24150f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
24160f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    InitOMXParams(&layerParams);
24170f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    layerParams.nPortIndex = kPortIndexOutput;
24180f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2419d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2420d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2421d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &layerParams, sizeof(layerParams));
24220f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24230f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
24240f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
24250f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (!(layerParams.eSupportedPatterns & pattern)) {
24260f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
24270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numLayers = min(numLayers, layerParams.nLayerCountMax);
24300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numBLayers = min(numBLayers, layerParams.nBLayerCountMax);
24310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!inConfigure) {
24330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
24340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        InitOMXParams(&layerConfig);
24350f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPortIndex = kPortIndexOutput;
24360f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.ePattern = pattern;
24370f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPLayerCountActual = numLayers - numBLayers;
24380f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nBLayerCountActual = numBLayers;
24390f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
24400f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2441d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(
2442d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
24430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerConfig, sizeof(layerConfig));
24440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
24450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.ePattern = pattern;
24460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nPLayerCountActual = numLayers - numBLayers;
24470f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nBLayerCountActual = numBLayers;
24480f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.bBitrateRatiosSpecified = OMX_FALSE;
24490f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2450d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2451d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
24520f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerParams, sizeof(layerParams));
24530f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24540f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24550f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString configSchema;
24560f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) {
24570f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers);
24580f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
24590f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("webrtc.vp8.%u", numLayers);
24600f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24610f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24620f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
24630f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGW("Failed to set temporal layers to %s (requested %s)",
24640f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                configSchema.c_str(), tsSchema.c_str());
24650f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
24660f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24670f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2468d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2469d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
24700f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            &layerParams, sizeof(layerParams));
24710f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24720f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err == OK) {
24730f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)",
24740f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                tsSchema.c_str(), configSchema.c_str(),
24750f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                asString(layerParams.ePattern), layerParams.ePattern,
24760f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                layerParams.nPLayerCountActual, layerParams.nBLayerCountActual);
24770f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24780f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        if (outputFormat.get() == mOutputFormat.get()) {
24790f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            mOutputFormat = mOutputFormat->dup(); // trigger an output format change event
24800f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        }
24810f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        // assume we got what we configured
24820f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        outputFormat->setString("ts-schema", configSchema);
24830f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24840f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    return err;
24850f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar}
24860f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2492d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2493d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2505d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2506d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2512d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2513d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2519777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2520777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2521777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2522777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
25336e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
2535d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2536d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPortFormat, &format, sizeof(format));
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25456e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
25466e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
25476e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
25486e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
25496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
25506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
25516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2554d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2555d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPortFormat, &format, sizeof(format));
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2559aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
25608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
25612965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
25622965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2565ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2566ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2587d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2588d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2597d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2598d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2608d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2609d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2627aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2629b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2630b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2631b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2632b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2633b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2634b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2635b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2636b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2637b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2638b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2639b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2640b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2641b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2642b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2643b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2644b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2645b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2646b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2647b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2648b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2649b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2650b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2651b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2652b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2653b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2654b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2656d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2657d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2670d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2671d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
2672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2679ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2680ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2681ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2682ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2683ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2686dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
26878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
26888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
26898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
26908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
26918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
26928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
26932965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
26948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2695d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t res = mOMXNode->setParameter(
2696d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
26978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
26988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
2699d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mOMXNode->setParameter(
2700d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
27018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
27028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
27038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
27048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
2705b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    mSampleRate = sampleRate;
27068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
270997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
271097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
271197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
271297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
271397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
271497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
271597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
271697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
271797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
271897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
271997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
272097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
272197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
272297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
272397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
272497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
272597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
272697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2727d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2728d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
272997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
273097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
273197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
273297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
273397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
273497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
273597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
273697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2737d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2738d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
273997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
274097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
27418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
27428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
27438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
27448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
27458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
27478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
27488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
27518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
27528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
27538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
27568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
27578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
27588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2759d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2760d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
27618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
27638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
27648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
27678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
27688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2769d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2770d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
27718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
27728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2819729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2820729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2822729de186450f78c099637e1fce743fe531862c52Andreas Huber
2823d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2824d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2825729de186450f78c099637e1fce743fe531862c52Andreas Huber
2826729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2827729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2828729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2829729de186450f78c099637e1fce743fe531862c52Andreas Huber
2830729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2833d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2834d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2835729de186450f78c099637e1fce743fe531862c52Andreas Huber
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2839729de186450f78c099637e1fce743fe531862c52Andreas Huber
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2844729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2845729de186450f78c099637e1fce743fe531862c52Andreas Huber
284617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2847777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2848777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2849777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2851729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
285217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2853729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2854729de186450f78c099637e1fce743fe531862c52Andreas Huber
28552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
28562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
28572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
28592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
28602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
28612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
28622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
2864d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
28652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
28662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
28672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
28682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
28692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
2870d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
28712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
28722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
28732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
28742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
28752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
28762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
28782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
28792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
28802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
28812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
28822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2883729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
28845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
2885729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2886729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2887729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2888729de186450f78c099637e1fce743fe531862c52Andreas Huber
2889d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2890d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2891729de186450f78c099637e1fce743fe531862c52Andreas Huber
2892729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2893729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2894729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2895729de186450f78c099637e1fce743fe531862c52Andreas Huber
2896729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2897729de186450f78c099637e1fce743fe531862c52Andreas Huber
2898d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2899d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2900729de186450f78c099637e1fce743fe531862c52Andreas Huber
2901729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2902729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2903729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2904729de186450f78c099637e1fce743fe531862c52Andreas Huber
2905729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2906729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2907729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2908729de186450f78c099637e1fce743fe531862c52Andreas Huber
2909d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2910d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2911729de186450f78c099637e1fce743fe531862c52Andreas Huber
2912729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2913729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2914729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2915729de186450f78c099637e1fce743fe531862c52Andreas Huber
2916729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
29175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    switch (encoding) {
29185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm8bit:
29195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataUnsigned;
29205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 8;
29215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcmFloat:
29235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataFloat;
29245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 32;
29255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm16bit:
29275b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataSigned;
29285b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 16;
29295b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        default:
29315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            return BAD_VALUE;
29325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
2933729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2934729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2935729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2936729de186450f78c099637e1fce743fe531862c52Andreas Huber
2937c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2938c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2939729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2940729de186450f78c099637e1fce743fe531862c52Andreas Huber
2941d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2942d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
29435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // if we could not set up raw format to non-16-bit, try with 16-bit
29445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // NOTE: we will also verify this via readback, in case codec ignores these fields
29455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (err != OK && encoding != kAudioEncodingPcm16bit) {
29465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.eNumData = OMX_NumericalDataSigned;
29475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.nBitPerSample = 16;
2948d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2949d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
29505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
29515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return err;
2952729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2953729de186450f78c099637e1fce743fe531862c52Andreas Huber
29545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
295597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
29565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
29575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2958d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->configureVideoTunnelMode(
2959d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
29605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
29615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
29625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
29635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
29645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
29665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
29675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
29685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
29695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
29705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
29715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
29735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
29745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
29780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
29790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29866e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2988d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2989d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat,
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2996229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2997229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
29980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
29991ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
3000d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
30010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
3002229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
3003229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
3004229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
3005229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3006229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30316e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
30326e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
30336e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
30346e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
30356e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
30366e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3043d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
3044d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
30500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
30510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
30520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
30530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
30540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
30550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
30560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
30570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
30580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
30590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
30600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
30610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
30620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
30630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
30640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
30690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
30700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
30730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
3074d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3075d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat, &format, sizeof(format));
30760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
30770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
30780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
30790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
30800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
30810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
30820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
30830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
30850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
30860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
30880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
30910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
30920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
30930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
30940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
30950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
30960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
30990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
31000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
31011ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
3102d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
31030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
31040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
31050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
31060d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
31070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
3108d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
3109d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
3113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
3114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3115e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
3116e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
31172472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3118e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3119e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3120e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
312194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
312294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3123a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
3125e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3128e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3129e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3130e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3131e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3132e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3133e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3134e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3137e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3138e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3139e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3140e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3141e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3142e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3143e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3144e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3145e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3146e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3147e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3148e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3149e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3150e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3151e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3152e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3153e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3154e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3155e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
31565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3158a6bfb5060824f01041f956c733fec141504c280bHangyu Kuangstatus_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) {
3159a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
3160a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    InitOMXParams(&def);
3161a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nPortIndex = portIndex;
3162a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    status_t err;
3163a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
3164a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3165d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3166d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3167a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3168a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        return err;
3169a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3170a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nBufferCountActual = bufferNum;
3171d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3172d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3173a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3174a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        // Component could reject this request.
3175a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
3176a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3177a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3178a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    return OK;
3179a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang}
3180a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
31815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
31828338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3183b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
318489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
318589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
318689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
318789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
318889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
318989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3197f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    if (compressionFormat == OMX_VIDEO_CodingVP9) {
3198f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3199f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        InitOMXParams(&params);
3200f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nPortIndex = kPortIndexInput;
3201f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        // Check if VP9 decoder advertises supported profiles.
3202f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nProfileIndex = 0;
3203d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3204f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                OMX_IndexParamVideoProfileLevelQuerySupported,
3205d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
3206f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        mIsLegacyVP9Decoder = err != OK;
3207f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    }
3208f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
321789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
321889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
321989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
322089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
32210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
322289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
322389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
322489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
32250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
322689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
322789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
32280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
322989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3235a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component input buffer number to be |tmp|. If succeed,
3236a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set input port buffer number to be |tmp|. If fail,
3237a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3238a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-input-buffers", &tmp)) {
3239a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexInput, tmp);
3240a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3241a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3242a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3243a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
3244a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component output buffer number to be |tmp|. If succeed,
3245a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set output port buffer number to be |tmp|. If fail,
3246a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3247a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-output-buffers", &tmp)) {
3248a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexOutput, tmp);
3249a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3250a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3251a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3252a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
325378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
325478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
325578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
325678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
325778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
325878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
325978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
326078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
326178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
326378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3276b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3277b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3278b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
32798338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
32808338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3281db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3282db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3283db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return err;
3284db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3285db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
32865e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
3287db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
3288db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        err = OK;
3289db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3294d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3295d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3297b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3298b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3299b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3300b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
33018338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3302b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3303b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3304b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3305d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3306b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3307b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3308b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3309b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3310b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3311b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3312b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3313b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3314b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3315b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3316b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3317b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3318b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3319b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3320db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting color aspects failed even though codec advertises support",
3321b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
33228338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
33238338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
33248338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3325b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3326b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
33288338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
33298338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3330b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
33318338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3333b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3334b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3335b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3336b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3337b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3338b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
33398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3341b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
33428338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3343b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3345b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3346b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3347b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3348b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3349b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3350d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
33518338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3352b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3353b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3354b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3355b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3356b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3357b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3358b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3360b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3361b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3362b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3363b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3364b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3365b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3367b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3368b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
33698338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3377b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
33788338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3379b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3380b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3381b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3382b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3385b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3386b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3388b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3389b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3390b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3391b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3392b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3394b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
33988338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3405b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3408b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3411b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3412b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3414b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3415b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3416b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3417b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3418b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3419b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3420b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3424b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
34258338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
34278338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3434b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3435b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
34368338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
34398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
34408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3441b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3442b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3443b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3444b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3445b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3446b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3447b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3448b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3449b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3450b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3451b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3452b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3453b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3454b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3455b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3456b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3457b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3458b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3459b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3460b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3461b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3462b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3463b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3464b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3465b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3466b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3467b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3468b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
34698338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34708338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3471b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3472b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3473b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3474b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3475b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3476b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3477b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3478b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3479b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3480b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3481b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3482b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3483b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3484b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3485b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
34865e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::setHDRStaticInfoForVideoCodec(
34875e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
34885e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
34895e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34905e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    DescribeHDRStaticInfoParams params;
34915e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    InitOMXParams(&params);
34925e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
34935e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34945e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    HDRStaticInfo *info = &params.sInfo;
34955e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (getHDRStaticInfoFromFormat(configFormat, info)) {
34965e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
34975e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
34985e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34995e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    (void)initDescribeHDRStaticInfoIndex();
35005e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
35015e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    // communicate HDR static Info to codec
35025e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    return setHDRStaticInfo(params);
35035e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang}
35045e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
3505b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3506b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3507b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
35088338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
35098338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
35118338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
35128338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
35188338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
35218338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
35328338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
35338338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3535b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3536b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
35408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3545b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3546b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
35498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3550b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3552b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3553b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3554b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35575e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
35585e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3559db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    DescribeHDRStaticInfoParams params;
3560db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    InitOMXParams(&params);
35615e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
3562db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3563db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = getHDRStaticInfo(params);
3564db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == OK) {
3565db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        // we only set decodec output HDRStaticInfo if codec supports them
3566db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, format);
3567db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3568db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3569db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3570db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3571db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::initDescribeHDRStaticInfoIndex() {
3572d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3573d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
3574db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3575db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
3576db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3577db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3578db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3579db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3580db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
3581db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3582db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3583d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3584db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3585db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3586db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    const HDRStaticInfo *info = &params.sInfo;
3587db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
3588db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
3589db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str(),
3590db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
3591db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
3592db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
3593db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
3594db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3595db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3596db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting HDRStaticInfo failed even though codec advertises support",
3597db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3598db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3599db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3600db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3601db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
3602db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3603db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3604d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3605db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3606db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3607db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3608db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] getting HDRStaticInfo failed even though codec advertises support",
3609db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3610db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3611db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3612db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
36138338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3614b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3615b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
36295778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
36405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
36425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3643d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3644d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
36455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
36525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
36555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
36595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
36615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
36635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
36665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
36685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
36705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
36735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
36755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
36775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
36785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
36795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
36805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
36832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3688a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3689a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3690a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3691a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3692a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3694d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3695d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3725d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3726d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
37335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
37345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
37355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
37365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
37375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
37385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3739d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3740d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3749870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3750870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3751870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3752870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3753870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3754870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3755870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3756870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3757870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3758870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3759870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
37615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
37665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
37675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
37705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3773c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3774c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3775c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3776c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
377789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
377889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
37799bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            err = setupVPXEncoderParameters(msg, outputFormat);
378089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
378189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37860f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
37870f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
37880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
37890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
37908338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
37918338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3792b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3793b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
37948338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
37958338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
37968338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
37978338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
37985e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err != OK) {
37995e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        return err;
38005e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
38015e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
38025e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
38035e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
38045e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
38055e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        err = OK;
38065e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
38075e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
38080f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
38090f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
38100f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
38110f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38120f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    switch (compressionFormat) {
38130f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingAVC:
38140f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingHEVC:
38150f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat);
38160f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            if (err != OK) {
38170f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                err = OK; // ignore failure
38180f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            }
38190f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38200f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38210f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP8:
38220f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP9:
38230f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // TODO: do we need to support android.generic layering? webrtc layering is
38240f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // already set up in setupVPXEncoderParameters.
38250f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38260f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        default:
38280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
38300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
3831d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3832d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3833d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
38345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
38390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
38400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
38410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
38420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
38440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
38460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
38470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
38480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
38490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
38500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
38510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
38520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
38530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
38550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
38560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
38570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
38580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
38590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
38600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
38610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
38630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
38640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
38650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
38660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
38670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
38680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
3869d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
3870d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
38710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
38720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
38730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
3874f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnarstatic OMX_U32 setPFramesSpacing(
387563a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar        float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) {
3876f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // BFramesSpacing is the number of B frames between I/P frames
3877f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // PFramesSpacing (the value to be returned) is the number of P frames between I frames
3878f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3879f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1
3880f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                                     ^^^                            ^^^        ^^^
3881f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                              number of B frames                number of P    I frame
3882f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3883f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                  = (PFramesSpacing + 1) * (BFramesSpacing + 1)
3884f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3885f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // E.g.
3886f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //      I   P   I  : I-interval: 8, nPFrames 1, nBFrames 3
3887f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //       BBB BBB
3888f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
3889f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    if (iFramesInterval < 0) { // just 1 key frame
3890f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1
3891f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    } else if (iFramesInterval == 0) { // just key frames
38925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3894f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
3895f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // round down as key-frame-interval is an upper limit
3896f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval);
3897f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1);
3898f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    return ret > 0 ? ret - 1 : 0;
38995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
390196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
390296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
390396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
390496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
390596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
390696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
390796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
390896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
390996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
39105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
391163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
391263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
39135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
391463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
39155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
39165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
391896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
391996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
39225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
39235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
39275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
39315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
39325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3933d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
3934d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
39355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
39415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
39425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
39455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
39465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3947f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nBFrames = 0;
3948f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames);
39495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
39505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
39515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
39535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
39545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
39555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
39565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
39575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
39585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
39635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
39705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
39745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3976d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3977d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
39785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
398396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
399363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
399463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
39955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
399663a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
39975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
39985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
400096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
400196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
40025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
40035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
40045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
40055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
40065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
40075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
40095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
40125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
40135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
40145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4015d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4016d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
40175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
40235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
40245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4025f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nBFrames = 0;
4026f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames);
40275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
40285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
40295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
40325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
40335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
40345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
40355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
40365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
40395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
40415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
40425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
40465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
40495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
40505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
40515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
40525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4053d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4054d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
40555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
406096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
40615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
40675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4069a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
4070a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
4071a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
4072a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
4073a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
4074a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
4075a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
4076a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
4077a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
4078a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
4079a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
4080a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
4081a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4082a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4083a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
4084a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
4085a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
4086a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
4087a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
4088a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
4089a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4090a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
4091a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
4092a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
4093a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
4094a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
4095a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
4096a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
4097a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
4098a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
4099a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
4100a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
4101a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
4102a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
4103a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
4104a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
4105a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
4106a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
4107a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
4108a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
4109a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
4110a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4111a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
4112a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
4113a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
4114a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
4115a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
4116a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
4117a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4118a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
4119a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
4120a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
41215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
412263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
412363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
41245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
412563a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
41275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
412996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
413096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
41315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
41325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
41335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
41345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
41355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
41365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
41385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
41410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
41420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
41430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
41440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
41450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
41460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
41470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
41480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
41490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
41500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4155d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4156d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
41575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
41635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
41665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
41675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
41685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
41695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
41705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
41735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
41755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
41765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
41795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
4180e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else {
41818eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
41824c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#if 0   /* DON'T YET DEFAULT TO HIGHEST PROFILE */
41834c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar        // Use largest supported profile for AVC recording if profile is not specified.
4184826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        for (OMX_VIDEO_AVCPROFILETYPE profile : {
4185826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
4186826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            if (verifySupportForProfileAndLevel(profile, 0) == OK) {
4187826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                h264type.eProfile = profile;
4188826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                break;
4189826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            }
4190826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        }
41914c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#endif
41928eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    }
41938eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang
4194e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
4195e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            asString(h264type.eProfile), asString(h264type.eLevel));
4196e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
41995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
42005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
42015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
4202f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
42035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
42055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
42095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
42105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
42115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
42125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
42135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
4214e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
4215e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
4216e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nSliceHeaderSpacing = 0;
4217e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
4218e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefFrames = 2;
4219e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nBFrames = 1;
4220f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4221e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nAllowedPictureTypes =
4222e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
4223e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
4224e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
4225e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
4226e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
4227e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bconstIpred = OMX_TRUE;
4228e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
4229e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
4230e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nCabacInitIdc = 1;
42315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
42345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
42355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
42385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
42395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
42405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
42415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
42425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
42435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
42445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4245d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4246d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
42475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
42505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4252e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering
4253e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering
4254e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // is preferred.
4255e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    AString tsSchema;
4256e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    int32_t preferBFrames = (int32_t)false;
4257e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    if (msg->findString("ts-schema", &tsSchema)
4258e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) {
4259e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
4260e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        InitOMXParams(&layering);
4261e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        layering.nPortIndex = kPortIndexOutput;
4262d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
4263d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
4264e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                        &layering, sizeof(layering)) == OK
4265e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.eSupportedPatterns
4266e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.nBLayerCountMax == 0) {
4267e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nBFrames = 0;
4268e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4269e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
4270e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            ALOGI("disabling B-frames");
4271d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(
4272d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4273e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
4274e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            if (err != OK) {
4275e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                return err;
4276e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            }
4277e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        }
4278e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    }
4279e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
428096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
42815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4283c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
428463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
428563a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
4286c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
428763a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4288c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
4289c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4290c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4291c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
4292c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4293c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
4294c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
4295c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
4296c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
4297c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4298c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4299c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
4300c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4301c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4302c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4303c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4304c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4305c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4306c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4307d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4308d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4309c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4310c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4311c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4312c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4313c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4314c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4315c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4316c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4317c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4318c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4319c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4320c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
4321c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4322c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4323c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4324c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4325c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4326c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4327c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
43289aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
4329f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
4330c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4331d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4332d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4333c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4334c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4335c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4336c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4337c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
4338c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4339c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
43409bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnarstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
434189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
434263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval = 0;
43434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
43444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
43454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
43464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
43474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
43484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
43494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
43504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
43514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
43524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
435389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
435489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
435589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
435663a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    msg->findAsFloat("i-frame-interval", &iFrameInterval);
435789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
435889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
435989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
43604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
43614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
43624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
43634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
43644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
43654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
43664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
43674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
43684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
43694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
43709bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType =
43719bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
43729bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar
43734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
4374f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numLayers = 0;
4375f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numBLayers = 0;
4376f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        int tags;
4377f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        char dummy;
4378f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
4379f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0) {
43804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
43819bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
4382f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers;
4383f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
4384f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                        &numLayers, &dummy, &numBLayers, &dummy))
4385f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && (tags == 1 || (tags == 3 && dummy == '+'))
4386f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
43874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4388f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            // VPX does not have a concept of B-frames, so just count all layers
43899bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4390f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers + numBLayers;
43914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
4392f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
43934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
4394f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS);
43954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
43964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
43974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
43984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
43994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
4400d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4401d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
44024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
44034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
44044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
44054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
4406f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
44074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
44094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
44104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
44114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
44124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
44134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
44144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
44154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
44174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
44184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
44194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
4421d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
4422d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
44234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
44244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
44254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
44269bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
44279bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // advertise even single layer WebRTC layering, as it is defined
44289bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers));
44299bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsLayers > 0) {
44309bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid
44319bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers));
44324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
44344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
443589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
443689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
443789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
44385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
44405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
44415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
44425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
44435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44446e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
44456e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
4446d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
44475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
4448d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
44495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
44515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
44525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
44555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
44565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
44585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
44595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
44616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
44626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
44636e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
44646e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
44656e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
44665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
44685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
447096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
447196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
44725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
44735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
44745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
44755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4476d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4477d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
44785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
44805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
44815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
448396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
44845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
44855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4486d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4487d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
44885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
44915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
44925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
44935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
44945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4495d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4496d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
44975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
44985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
45005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
45015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
45045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
45055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
45065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
45075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
45085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4509d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4510d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
45115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
45125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
45135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
451678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
451778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4524d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4525d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4526777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4527777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4528777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4538777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4539777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4540777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4541777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
454978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
455078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
455178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4555d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
4562d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        return mOMXNode->enableNativeBuffers(kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4565d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mOMXNode->enableNativeBuffers(kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4570d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4571d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4572d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4573d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4574d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4575d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4576d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4577d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4578d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4579d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4580d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4581d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4582d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
45837e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
45847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
45857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
45877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
45887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
45907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
45917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
45927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
45937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
45957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
45967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45977e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
45987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
45997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
46007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
46017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4602e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
46037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4604c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4605054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4606054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4607c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
46087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
46097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
46107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4618609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4647e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4648777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
464931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
465031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4651e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
465231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4653d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
4654777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4655777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4656777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
465731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4658777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4659777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4660777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4661777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
466231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
466331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
466431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
466531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
466631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4667e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4668e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4669e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4670e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4671e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4672e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4673e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4674e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4675e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4676e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
46770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
467873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
46790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
46800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
46810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
46820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
46830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
46840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
46850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
46860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
4687d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (DescribeColorFormat(mOMXNode, describeParams)) {
46880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
46890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
46900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
46910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
46920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
46935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
469473dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
469573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
469673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
469773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
469873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
469973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
470073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
47010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
470203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
470303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4704b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4705b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4706b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4707b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4708b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4709b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4710b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4711b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4712d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (mOMXNode->getConfig(
4713b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4714b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4715b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4716b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4717b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4718b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4719b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4720b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4721b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
472291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4723b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4724b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4725b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4726b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4727b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4728b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4729b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4730b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4731b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4732b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
473331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4734b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4735b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4736b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4737b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4738b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4739b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4740b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4741b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4742b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4743b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4744b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4745b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4746b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4747b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4748b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4749b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4750b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
47515e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
4752b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4753b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
47545e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        if (mConfigFormat->contains("hdr-static-info")) {
47555e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                            (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
47565e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        }
4757777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4759e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4760e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
47614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
47624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
47634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
47644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
47654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
47664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
47674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
4768d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    status_t err = mOMXNode->getParameter(
47694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
47704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
47714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
47724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
47734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
47749bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                        if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC
47759bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount > 0
47769bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount
47779bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
47789bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            // advertise as android.generic if we configured for android.generic
47799bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            AString origSchema;
47809bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            if (notify->findString("ts-schema", &origSchema)
47819bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                    && origSchema.startsWith("android.generic")) {
47829bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
47839bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "android.generic.%u", vp8type.nTemporalLayerCount));
47849bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            } else {
47859bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
47869bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount));
47874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
47884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
47894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
47904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
47914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
47924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4793e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4794e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4795777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4796777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4797777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4798777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4799777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4800777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4801777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4802e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4804e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4806e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4809870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4810870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4811870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4812870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4813870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
481631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4817e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4818e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
48195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
48205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
48215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
48225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
482331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
482431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
482531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
482631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
482731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
482831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
482931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
483097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4835e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4837d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4838d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioPcm, &params, sizeof(params));
4839777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4840777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4841777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
484214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4843777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4844777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4845777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
48465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4847777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4848777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
48495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
4850777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4851777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4854e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
48565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
48575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
48585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
48595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
48605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
48615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
48625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
48635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
48645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
48655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
48665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
48675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
48685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
48695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
48705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
48715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
4872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
48758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
48778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
48789806555d3930be43e11106281dee354820ac1c88Andreas Huber
4879e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4881e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4882e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4883e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4884e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4885d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4886d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAac, &params, sizeof(params));
4887777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4888777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4889777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4890e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4891e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4892e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4893e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4894e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4895e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4896e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4897e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4898e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4899e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4900e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
49029806555d3930be43e11106281dee354820ac1c88Andreas Huber
4903d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4904d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAmr, &params, sizeof(params));
4905777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4906777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4907777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4908e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4909e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4910e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
49110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4912e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4913e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
49140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4915e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4916e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4917e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4918e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4919e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4920e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4921e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4922e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4923e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4924e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4925e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4926d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4927d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioFlac, &params, sizeof(params));
4928777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4929777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4931e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4932e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4933e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4934e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4935e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4936e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4937e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4938e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4939e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4940e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4941e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4942e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4943e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4944d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4945d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioMp3, &params, sizeof(params));
4946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4948777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4949e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4950e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4951e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4952e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4953e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4954e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4955e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4956e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4957e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4958e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4959e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4960e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4961e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4962d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4963d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioVorbis, &params, sizeof(params));
4964777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4965777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4966777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4967e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4969e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
497497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
497597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
497697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
497797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4978e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
497997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4980d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4981d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4982777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4983777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
498697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
498797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
498897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
498997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
499097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
499197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4992e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
49938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
49948a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
49958a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
49968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
49978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
49988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4999d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5000d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
5001777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5002777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5003777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5004777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
50058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
50068a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
50078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
50088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
50098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
50108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
50118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
50128c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
50138c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
50148c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
50158c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
50168c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
50178c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
5018d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5019d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
5020777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5021777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5022777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5023777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
50248c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
50258c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
50268c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
50278c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
50288c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
50298c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
50308c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
503110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
503210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
503310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
503410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
503510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
503610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
5037d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5038d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
5039777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5040777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5041777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
504210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
504310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
504410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
504510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
504610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
504710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
504810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
504910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
505010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
505110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
505210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
505310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
505478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
505510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
505610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
505741d3f579d2c166984958263533284209b90c87d5Marco Nelissen
505841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
505941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
50600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
506141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
506241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
506341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
5064d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5065d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                OMX_IndexParamAudioPcm, &params, sizeof(params));
5066777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5067777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5068777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
506941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
507041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
507141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
50720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
507341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
507410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
507510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
5076e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
5077777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
5078777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
5079777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
5080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
508131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
508231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
508331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
508431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
5085777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
5086777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
508731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
508831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5089e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
5090e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
5091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5092b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
5093b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
5094b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
5095b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
5096b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5097b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
5098b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5099b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
5100b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5101b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5102b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
5103b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5104b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5105b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
5106b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5107b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5108b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5109b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5110b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
5111b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5112b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5113b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
5114b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5115b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5116b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
5117b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5118b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5119b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5120b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5121b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
5122b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
5123b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
5124b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5125b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
5126b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
5127b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
5128b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
5129b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
5130b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
51311734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5132697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // store new output format, at the same time mark that this is no longer the first frame
5133b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
5134e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5135b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5136777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5137777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
5138777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5139e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
51401734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    if (expectedFormat != NULL) {
51411734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
51421734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
51431734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        if (changes->countEntries() != 0 || to->countEntries() != 0) {
51441734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
51451734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mComponentName.c_str(),
51461734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    changes->debugString(4).c_str(), to->debugString(4).c_str());
51471734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        }
51481734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    }
51491734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar
51505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
51515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
51525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
51535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
51545b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
51555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
51565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
51575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
51585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
51595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
51605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
51615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
5162b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
5163b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
5164b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5165b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5166b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5167b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> &notify) {
5168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
5169b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5171b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) {
5172b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // notify renderer of the crop change and dataspace change
5173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
5174b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t left, top, right, bottom;
5175b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
5176b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setRect("crop", left, top, right + 1, bottom + 1);
5177b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5178b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5179b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t dataSpace;
5180b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
5181b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setInt32("dataspace", dataSpace);
5182b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5183b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5184b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5185b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5186b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
5187b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
5188b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5189b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5190b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5191b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        int32_t channelCount, sampleRate;
519284d7e874983ee0d66db328c454fa603374d4635fMarco Nelissen        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5193b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
5194b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        if (mSampleRate != 0 && sampleRate != 0) {
5195b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderDelay = mEncoderDelay * sampleRate / mSampleRate;
5196b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderPadding = mEncoderPadding * sampleRate / mSampleRate;
5197b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mSampleRate = sampleRate;
5198b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        }
5199e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
5200e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
5201e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
5202ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
5204e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
5205b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5206e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
5207e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5208b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> notify = mNotify->dup();
5209b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
5210b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setMessage("format", mOutputFormat);
521131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
521231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5213b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5214b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
521531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
521631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
52175778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5218cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
5219d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
5220251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5221251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
5222251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
5223251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
5224251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
5225251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
5226251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
5227251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5228251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5229251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5230346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5231346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
5232346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
52335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
5234251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
5235cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
5236cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5237cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5238496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5239496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5240496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5241496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5242496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5243496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5244496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5245496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5246496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5247496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5248496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5249d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setConfig(
5250496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5251496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5252496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5253496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5254496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
52557e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim////////////////////////////////////////////////////////////////////////////////
52567e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
52577e34bf5af26f8752d4786d3098740cdf51e2438fWonsik KimACodec::PortDescription::PortDescription() {
52587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim}
52597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
5260eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
52617e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        IOMX::buffer_id id, const sp<MediaCodecBuffer> &buffer,
5262a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
5263eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
5264eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
5265a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mHandles.push_back(handle);
526686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    mMemRefs.push_back(memRef);
5267eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5268eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5269eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
5270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
5271eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5272eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5273eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
5274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
5275eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5276eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
52777e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimsp<MediaCodecBuffer> ACodec::PortDescription::bufferAt(size_t index) const {
5278eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
5279eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5280eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5281a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnarsp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
5282a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    return mHandles.itemAt(index);
5283a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar}
5284a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
528586b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wusp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
528686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    return mMemRefs.itemAt(index);
528786b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu}
528886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu
5289eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
5290eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5291f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5296ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5297ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
531526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
531626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
531726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
531826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
531926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5320e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5321e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5322e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5323e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5324e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5325e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
532826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
53321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
53331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
53341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
53351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
53371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
53381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53392235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
53401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
53421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
53431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
53441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
53451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
53461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
53488f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
53497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
53507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5351251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
53527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
53537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
53547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
53557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
53567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5357ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5358ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5359251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5360ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
53616d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            mCodec->mGraphicBufferSource.clear();
5362ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5363ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5364ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5365ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
536630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
536730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
536830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
536930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
5370d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->freeNode();
537130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
537230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
537330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
537430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
537530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
537630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
537730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
537830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
538626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
53875e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
53885e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5389d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode == NULL) {
53905e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
53915e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
539226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
53935e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
53945e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5395d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    int32_t generation;
5396d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(msg->findInt32("generation", (int32_t*)&generation));
5397d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (generation != mCodec->mNodeGeneration) {
5398d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        ALOGW("Unexpected message for component: %s, gen %u, cur %u",
5399d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
5400777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5401777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
540226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
540326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
540426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
540526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
540626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
540726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
540826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
540926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
541090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
541126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
541226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5413e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5414e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
541590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
541690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
541790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
541890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
541990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
542090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
542190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
542290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
542390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
542490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
542526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
542626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
542726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
542826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
542926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
543026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
543126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
54420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
54430af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
54440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
54450af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
54460af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
54470af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
54480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
54490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
54500af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
54510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
546115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
546215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5463609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
546415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
546615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5472609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
547415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
548115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
548715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
548815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
549190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
549290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
549390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
549490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
549590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
549690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
549790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
549890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
549990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
550090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
550190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5503777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5504777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
550890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
550990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
551090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
551190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
551290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
551390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
55176cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang        ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
5518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5524ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5530ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5532251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5533251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5534251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5535251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5536251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5537251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5538251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
554315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5544ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5545349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5546349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
55470806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
55480806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
55490806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
55500806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
55510806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
555215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
555315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
555415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
55550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
55560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
556015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
556115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
556215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
556315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
556415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
556515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
556696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
556796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
556896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
556996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
557096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
557196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5583777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5585777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5586777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
5600d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
5601609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
56047e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    notify->setObject("buffer", info->mData);
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
5607609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5618609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
56197e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
56215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5622a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
56235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
56247e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<RefBase> obj;
56257e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    if (!msg->findObject("buffer", &obj)) {
5626a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56297fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
56307fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
56317fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
56327fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
56337fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
56347fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
56357fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
56367fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
56373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
56382d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
56397e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    } else {
56407e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer = static_cast<MediaCodecBuffer *>(obj.get());
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
56445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
56455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
56465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
56475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
56485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
56500806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
56510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
56520806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
56530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
56540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
56550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
56560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5664dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5665dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5666dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5667dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5675fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5676fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5677fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5678fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5679fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5680fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5686d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                MetadataBufferType metaType = mCodec->mInputMetadataType;
5687d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                int32_t isCSD = 0;
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5689f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    if (mCodec->mIsLegacyVP9Decoder) {
5690f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
5691f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                            mCodec->mComponentName.c_str(), bufferID);
5692f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        postFillThisBuffer(info);
5693f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        break;
5694f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    }
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5696d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    metaType = kMetadataBufferTypeInvalid;
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
57005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
57015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
57025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (buffer != info->mCodecData) {
5704ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
57075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                         buffer.get(), info->mCodecData.get());
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
5710d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (converter == NULL || isCSD) {
57115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
57125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
57135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
57145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
57155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
57160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
57170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5720078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5721ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5722078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
57235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5724ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
57255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5726078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5727d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5728ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5729ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5730d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5731ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5732ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5733d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5734078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5735349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5736d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5737d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5738d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5739d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5743054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5747054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5748054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5752054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
575515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5756d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5757d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                status_t err2 = OK;
5758d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                switch (metaType) {
5759d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeInvalid:
5760d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5761d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5762d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeNativeHandleSource:
5763d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
5764d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeHandleMetadata *vnhmd =
5765d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            (VideoNativeHandleMetadata*)info->mCodecData->base();
5766d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        err2 = mCodec->mOMXNode->updateNativeHandleInMeta(
5767d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                mCodec->kPortIndexInput,
5768d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                NativeHandle::create(vnhmd->pHandle, false /* ownsHandle */),
5769d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                bufferID);
5770d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5771d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5772d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeANWBuffer:
5773d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
5774d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
5775d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        err2 = mCodec->mOMXNode->updateGraphicBufferInMeta(
5776d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                mCodec->kPortIndexInput,
5777d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                new GraphicBuffer(vnmd->pBuffer, false /* keepOwnership */),
5778d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                bufferID);
5779d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5780d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5781d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#endif
5782d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                default:
5783d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
5784d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            asString(metaType), info->mCodecData->size(),
5785d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            sizeof(buffer_handle_t) * 8);
5786d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    err2 = ERROR_UNSUPPORTED;
5787d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5788d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
5789d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5790d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                if (err2 == OK) {
5791d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err2 = mCodec->mOMXNode->emptyBuffer(
5792d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        bufferID,
5793d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        0,
5794d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        info->mCodecData->size(),
5795d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        flags,
5796d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        timeUs,
5797d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        info->mFenceFd);
5798d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
579915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
58000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
58010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
58020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
58030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
58075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
58085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
58090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
58100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
58115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
58125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
58135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
58145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
58160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
58170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5818dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5819dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
58203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5821dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5822dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5824ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5825349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5826349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
582715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5828d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                status_t err2 = mCodec->mOMXNode->emptyBuffer(
58290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
58300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
58310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
58320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
583315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
583415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
583515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
58360806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
58370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
58380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
58390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5843dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5847625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5848777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5849777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5850777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5851625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5852777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5853625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
589015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
589115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5892609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
58935778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5894349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
58960806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5897d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5898d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5899d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5900d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5901d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5902d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5903d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5904d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5905d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5906d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5907d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5908d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5909d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5910d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5911d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5912d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
59150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
59160806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
59170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
59180806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
59190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
592015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
592115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
592215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
59230806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
59240806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
592990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
593090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
593190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
593290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
593390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
593490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
593590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
593690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
593790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
593815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
593915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
594015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
594115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
594215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
594315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
594415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5953a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5954a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5955609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
59565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5957349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5958d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mCodec->mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
595915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
59600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
59610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
59630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
59665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
59675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
596831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5969577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
59701d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
59717e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            sp<MediaCodecBuffer> buffer = info->mData;
5972577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5973b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5974697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                // pretend that output format has changed on the first frame (we used to do this)
5975697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
59761734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
5977697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                }
5978b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
5979b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
5980fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            } else if (rangeLength > 0 && mCodec->mNativeWindow != NULL) {
5981fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                // If potentially rendering onto a surface, always save key format data (crop &
5982fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                // data space) so that we can set it if and once the buffer is rendered.
5983fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
59845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5985b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5986054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
5987054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
59883e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                VideoNativeHandleMetadata &nativeMeta =
59897e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    *(VideoNativeHandleMetadata *)buffer->data();
59907e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                if (buffer->size() >= sizeof(nativeMeta)
59913e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeNativeHandleSource) {
59927c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
59933e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    // handle is only valid on 32-bit/mediaserver process
59947c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
59957c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
59963e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    handle = (native_handle_t *)nativeMeta.pHandle;
59977c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5998054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
59997e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setPointer("handle", handle);
60007e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeOffset", rangeOffset);
60017e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeLength", rangeLength);
60027e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            } else if (buffer == info->mCodecData) {
60037e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->setRange(rangeOffset, rangeLength);
60045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
60055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
60065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
60075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
60087e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                        info->mCodecData, buffer);
60095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
60105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
60125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
6013308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
6014496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
601521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
6016496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
6017496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
6018496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
60195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
602021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60228b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
60237e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                mCodec->mSkipCutBuffer->submit(buffer);
60248b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
60257e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            buffer->meta()->setInt64("timeUs", timeUs);
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6028d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
6029609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
60307e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            notify->setObject("buffer", buffer);
60315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6033609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
60385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
60395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
60425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
60435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
6045d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
6046dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6054777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
60550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
60560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
60570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
60590806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6061777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6062777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6063777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6064777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
6072609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
60737e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<RefBase> obj;
60747e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer = nullptr;
60757e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    if (msg->findObject("buffer", &obj)) {
60767e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer = static_cast<MediaCodecBuffer *>(obj.get());
60777e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    }
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
60790806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
60800806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
60810806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
60820806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
60830806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
60840806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
60850806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
60860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6088577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
6089fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)
6090fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            && memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
6091fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar        mCodec->mLastNativeWindowCrop = crop;
6092777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
6093777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
6094577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
6095577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
6096b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t dataSpace;
6097fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    if (msg->findInt32("dataspace", &dataSpace)
6098fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            && dataSpace != mCodec->mLastNativeWindowDataSpace) {
6099b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = native_window_set_buffers_data_space(
6100b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
6101fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar        mCodec->mLastNativeWindowDataSpace = dataSpace;
6102b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
6103b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6104b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
6106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
61076aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
61087e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            && buffer != NULL && buffer->size() != 0) {
61096fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
6111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
611390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
61147e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
611590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
611690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
611790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
611890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
611990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6120fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
6121fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
6122c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
61237e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
6124c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
6125fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
6126fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
6127fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
6128fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
61295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
6130fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
61310806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
6132fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
613315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
61340806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
613515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
613615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
61370806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
6138cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
6139cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
6140264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
6141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6142cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
614315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
614415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
6145cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
61476fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
61487e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            (buffer == NULL || buffer->size() != 0)) {
614915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
615015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
61516fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
61526fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
6165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
6177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6182c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
6183609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
6184c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
618515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
6186d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    status_t err = mCodec->mOMXNode->fillBuffer(
6187d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            info->mBufferID, info->mFenceFd);
618815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
61890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
61900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
61910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
61920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
61930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
6194c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6199777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
62010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
62020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
62030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
62040806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6207777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6208777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6209777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6210777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
6211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6216f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
6217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
6221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
6222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
62241d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        if (mCodec->mOMXNode != NULL) {
62251d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang            sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
62261d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang            binder->unlinkToDeath(mDeathNotifier);
62271d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        }
6228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
6229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
6230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6231b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
6232ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
6233e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
6234ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
6235d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode.clear();
6236ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
6237ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6238054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
6239054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
62405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
62415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6242ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6245f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
62585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
62595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
62605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
62615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
62625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
62635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
626954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
627054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
6271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6273d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
6274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6277c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6283d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6287c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
629030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
629130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
629230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
629330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
629430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
629530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
629630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6304f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
63105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
63115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
63135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
63145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6315d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode == NULL);
63165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
631848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
631948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
632048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
632148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
6322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6326ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6327b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
63285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
6332d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
63337791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
63345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6335b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6336b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6337b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6338afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
63395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
63405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
63415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
63425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
63435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
63445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
63455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6346b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
63475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
63485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6349b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6350e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
63515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
63521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
63531065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6354d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
63551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6356201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
63571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
63581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6359b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6360b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6362da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6363078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6364078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
63651d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
6366078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
63691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
63707a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
63717a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
63721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
63731065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6374d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode = NULL;
63751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
63761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6377d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (omxNode == NULL) {
63785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
63799f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
63809f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
63815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
63829f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
63835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6384c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
638552e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6386c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6387c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
638923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
63901d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang    if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
639123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // This was a local binder, if it dies so do we, we won't care
639223858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // about any notifications in the afterlife.
639323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mDeathNotifier.clear();
639423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
639523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
639626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6397d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    notify->setInt32("generation", ++mCodec->mNodeGeneration);
6398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
640190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6402ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6403ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6404ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6405ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
64061713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
64070167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6408ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6409ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6410afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
6411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6412d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode = omxNode;
6413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
64155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6416d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
64175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
64185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
64195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6420c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6421c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6422c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6423c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
64245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
64255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6426c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6431c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6432c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6433c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6434c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6435f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6436f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6437f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6438f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6439f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6440054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6441054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6442a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6443e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6444e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
64454e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
64466d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    mCodec->mGraphicBufferSource.clear();
6447054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
645654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6457f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6458f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6459c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6460c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6461c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6462c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
6463d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        (void)mCodec->mOMXNode->freeNode();
6464c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6465c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6466c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6467c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
646854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
646954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
6470d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
647154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
647254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
647354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6474c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6475c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6476c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6477c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6478c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6482c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6484c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6485c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6486c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
64877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
64887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
64897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
64907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
64917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
64927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
64937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
64948f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6495d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
64968f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6497d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6498d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6499d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6500d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6501c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6504c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6506c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6507c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6508c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6509c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6510c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6511c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6512c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
651454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6515c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6516c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6517c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6519c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6520c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6521c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6522c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6523c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6524d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6525c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
6526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6527c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6535c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6536c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6537c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6538c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
65395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
65405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
65415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6542d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode != NULL);
65435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
65440806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
65455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
65460806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
65470806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
65480806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
65490806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
65500806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
65515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6552c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6553c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6554c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6555251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
65575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
65605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6561d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
6562e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
6563e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
65645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
65655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6566c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6567c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
65685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
65695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6570d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6571d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
6572a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6573d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
65746d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65756d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
65766d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mRepeatFrameDelayUs));
6577a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6578a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6579a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6580a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
65816d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6582d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6583a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6584a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6585a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6586d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
65876d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65886d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setMaxTimestampGapUs(
65896d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mMaxPtsGapUs));
659094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
659194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
659294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
65936d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6594d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
65952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
65962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
65972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6598d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
65996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
660137b2b389139ed638831e49708c947863eef631efRonghua Wu
660237b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
660337b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
66046d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6605d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
660637b2b389139ed638831e49708c947863eef631efRonghua Wu        }
660737b2b389139ed638831e49708c947863eef631efRonghua Wu    }
660837b2b389139ed638831e49708c947863eef631efRonghua Wu
6609d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
66102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
66116d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66126d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setTimeLapseConfig(
66136d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mTimePerFrameUs, mCodec->mTimePerCaptureUs));
66142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
66152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
66162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
66176d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6618d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
66192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
66202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
662172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6622d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
66236d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66246d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setSuspend(true));
662572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
662672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
662772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
66286d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6629d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
663094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
663194ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
663294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6633c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6634d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode->getParameter(
6635d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6636c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6637c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6638c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6639c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6640c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6641b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
66436d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
66446d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
66456d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
66466d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
66476d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66486d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
66496d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        *(ColorAspects *)colorAspectsBuffer->base())));
66506d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
6651b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6652b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6653b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6654b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6655b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6656b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6657d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6658d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6659d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6660d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6661d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6662d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6663d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6664d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6665d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
6666d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6667b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6668b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6669b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6670b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6671b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
667257fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar
6673d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6674b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
66753e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
6676d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mCodec->mOMXNode->createInputSurface(
6677d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                mCodec->kPortIndexInput, dataSpace,
66786d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                &bufferProducer, &mCodec->mGraphicBufferSource,
66793e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                &mCodec->mInputMetadataType);
66803e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        // framework uses ANW buffers internally instead of gralloc handles
66813e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        if (mCodec->mInputMetadataType == kMetadataBufferTypeGrallocSource) {
66823e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
66833e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        }
6684b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6685d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6686d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6687d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6688d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6689d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
66907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
66917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
66927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
66937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
66947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
66957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
66967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
66977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
66987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
66997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
67007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
67017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
67027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
67037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
67048f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
6705d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
67068f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6707d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6708d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6709d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
6710d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6711d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6712d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6713d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6714d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6715b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6716b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6717b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6718b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6719b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
6720b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6721b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
67223e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
6723d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mCodec->mOMXNode->setInputSurface(
6724d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                mCodec->kPortIndexInput,
67256d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                surface->getBufferConsumer(),
67266d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                &mCodec->mGraphicBufferSource,
6727b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                &mCodec->mInputMetadataType);
67283e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        // framework uses ANW buffers internally instead of gralloc handles
67293e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        if (mCodec->mInputMetadataType == kMetadataBufferTypeGrallocSource) {
67303e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
67313e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        }
6732b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6733d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6734d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6735b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        surface->getBufferConsumer()->setDefaultBufferDataSpace(dataSpace);
6736d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6737d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6738d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6739d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
6740d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6741d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6742d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
67438f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6744d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
6745d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
6746d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6747d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
6748d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6749d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
67515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
67525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6753d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
67540806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
67550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
67560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
67570806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
67580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6763f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6767f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
67683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6770cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6771cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
677229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6773cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6774cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6775cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6776251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
677791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6778d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mCodec->mOMXNode->sendCommand(
6779d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
6780c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6781c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6782c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6783c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6784c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6785c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6786c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
678791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6788cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6791f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
6799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6801f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
680372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
68116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
68126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
68136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
68146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
68156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
68166463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
68176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
68186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
68196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
68206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
68216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
68226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
68236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
68246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
68256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
6826d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
68276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
68286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
68296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
68306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6836f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
68410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
68420806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
68430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
68440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
68450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
68460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
68470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
68480806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
6851d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mCodec->mOMXNode->sendCommand(
6852d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateExecuting);
68530806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
68560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
68570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
68580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
68590806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6871f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6875f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
68763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6879f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
688172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6888d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6889d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6890d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6891d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6892d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6893d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6894d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6895d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6896d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
6897d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6898d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6899d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
6900d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6901d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6902d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6903d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
69046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
69056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
69066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
69076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
69086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
69096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6915f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
69200806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
69210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
69220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
69230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
69240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
69250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
69270806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6942f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6943349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6944349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6947f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6948ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6952054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6955054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6959054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6960054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6961054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6962054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
69634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
69644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6965054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
69690806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
69740806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
69750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
69760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
69770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
69780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
69790806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
69850806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
69860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
69870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
69880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
69890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6993349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
699415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
6995d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mCodec->mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
699615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
69970806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
69980806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
69990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
70000806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
7003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
70040806340688c937e7b78c2d89db3809274130df4eLajos Molnar
70050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
70060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
7008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7010054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
7011c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
7012054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
7013054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
7014054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
7015054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
7016054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
7017f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
7018349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
70190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
7020349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
7021349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
7022349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
7024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70253cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
7026777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
7027777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
7028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
7029777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
70303cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
70313cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
70323cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
70333cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
70343cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
70353cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
7036349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7037349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
7038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7040f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
70413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
7042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
704390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
7044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
7045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7047f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
7048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7053c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
7054c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
7055c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
7056c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
7057c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
705854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
7059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
7060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
7061349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
7062349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7063d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(
7064d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateIdle);
70650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
70660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
70670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
70690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
70700806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
70710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
70720806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
70807a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
7081ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
7082d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
7083d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
7084d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
7085d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
7086d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
7087d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7088349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
7089349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7090d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
70910806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
70920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70930806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
70940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
70950806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
7102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
7104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7109496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
7110496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
7111496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
7112496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
7113496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
7114496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
7115496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7116496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
7117496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
7118496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
7119496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7120a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
7121a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
7122a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
7123a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
7124a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7125a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
7126a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7127a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
7128a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
7129a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
7130a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
7131a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
7132a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7133a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
7134a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
7135a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7136a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
71377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
71387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
71396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
71407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
71417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
71427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
71437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
71444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7145054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
71464dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
71474dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
71484dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
7149054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
71504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
7151054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
71524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
71534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
71544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
71554dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
71564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
7157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7165a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
7166a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
7167530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
7168a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7169a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
7170a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
7171a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
7172a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7173d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->setConfig(
7174a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
7175a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
7176a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
7177a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7178a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
7179a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7180a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
7181a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7182a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
7183a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7184a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
7185a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
718661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    int64_t timeOffsetUs;
718761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
71886d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
71896d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set input buffer time offset without surface",
71906d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
71916d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
71926d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
71936d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
71946d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
71956d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
719661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
719761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        if (err != OK) {
719861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            ALOGE("[%s] Unable to set input buffer time offset (err %d)",
719961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                mComponentName.c_str(),
720061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                err);
720161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            return err;
720261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
720361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    }
720461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
720572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
720672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
72076d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
72086d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set start time without surface",
72096d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
72106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
72116d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
72126d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
72136d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
72146d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
721572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
721672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
721772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
721872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
721972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
722072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
722172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7222e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
7223e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
72246d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
72256d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set suspend without surface",
72266d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
72276d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
72286d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
7229e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
72306d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
72316d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setSuspend(dropInputFrames != 0));
7232b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7233b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7234b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7235b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7236b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7237b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
7238b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7239b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7240b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7241b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7242b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7243b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7244b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7245b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7246b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7247e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7248e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
72498db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
72508db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
72518db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
72528db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
72538db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
72548db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
72558db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
72568db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
72578db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7258870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7259870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7260870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7261870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7262870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7263870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7264870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7265870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7266870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7267870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7268870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
72690f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
72700f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
72710f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        err = OK; // ignore failure
72720f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
72730f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
72740f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    return err;
7275a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7276a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
72776507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
72786507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
7279d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
72806507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
72816d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err = INVALID_OPERATION;
72826d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (mGraphicBufferSource != NULL) {
72836d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
72846d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
72856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
72866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
72876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
72886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
72896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
72906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
729190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
729290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
729390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
729490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
729590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7303b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7304b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
730531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7306054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7307d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                CHECK_EQ(mCodec->mOMXNode->sendCommand(
7308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7314b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7315b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7316ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7335f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7340f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7358349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7359e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7361349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
73623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7363349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7364349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7378f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
73793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
738390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
738490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
738590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
738690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
738790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
738890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7389f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
73950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
73960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
73970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
73980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
74030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
74040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
74050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
74060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
74070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
74080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
74090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
7412d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mCodec->mOMXNode->sendCommand(
7413d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_CommandPortEnable, kPortIndexOutput);
74140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
74170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
74180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
74190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
74200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7421cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
74220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7423251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7424d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7425755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7426755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7427755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7428755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7429755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7430755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7431755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7432755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7433cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7437777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7438777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7439777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7440777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7444349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7445349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7446349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7447349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7463f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
74645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
74655778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7468f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
74760806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7496f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
74973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
749831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
74995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7500b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7503f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
75080806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
75090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
75100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
75110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
75120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
75130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
75140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
75150806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
75185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7526349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7528349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7529349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7530349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
75350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7536f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
75375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
7538d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mCodec->mOMXNode->sendCommand(
7539d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
75400806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
75410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
75420806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
75430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
75440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
75450806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
75460806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75480167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
75490167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7554b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7555bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7556bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
75570806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
75580806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
75590806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
75600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
75610806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7566f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7573f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7582f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7586f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
76020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7614f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
76153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7618f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
76230806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
76240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
76250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
76260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
76270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
76280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
76290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
76300806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7644f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7648f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
76493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7654f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7679f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
7680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7681ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
7682ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
7683d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
76870806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
76880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
76890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
76900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
76910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
76920806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
7695777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
7696777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
7697777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
7698777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
7699777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
7701e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
77020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
7703e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
7704e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
7705777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
7706777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
7707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
7708777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
7709777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
7710777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7711777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
7714777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
7715777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
7716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7721349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7722349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
77231d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
7724349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
7725d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            msg->setInt32("generation", mCodec->mNodeGeneration);
7726349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
7727349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
7728349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
7729349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
77303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
7731349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
7732349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7733349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
7734349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7735349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7736349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7737349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
7743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7745f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
7746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7751f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
7752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7757f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
7758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
7759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
7760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
77617e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
77627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
77637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
77647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
776590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
776690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
7768d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
7769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
7770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
7772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
7773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7774dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
7775dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
7776f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
7777f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
7778f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
7779f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
7780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
7781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
77855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
77865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
77875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
77881ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime.c_str());
77895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
77905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
77915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
77945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = client.connect();
77955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
77965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
77975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
78005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
7801d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
78025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78031d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang    err = omx->allocateNode(name.c_str(), observer, &omxNode);
78045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
78055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
78065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
78075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
78085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7809d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = SetComponentRole(omxNode, role);
78105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
7811d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode->freeNode();
78125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
78135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
78145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
78155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
78175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
78185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
78205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
78215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
78225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
78235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78246e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
78256e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
7826d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7827d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoProfileLevelQuerySupported,
78285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
78295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
78305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
78315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
78325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
78336e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
78346e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
78356e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
78366e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
78376e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
78386e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
78395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
78425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
78435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
78445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
78455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
784636e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
78475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
78486e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
78496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
7850d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7851d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoPortFormat,
78525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
78535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
78545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
78555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
78565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
78581ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim            if (IsFlexibleColorFormat(
7859d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
78605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
78615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
78625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
78635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
78645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
78655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
78665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
78675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
78685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
78695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
78705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
78715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
78725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
78735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
78745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
78756e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
78766e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
78776e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
78786e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
78796e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
78806e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
78815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
78835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
78845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
78855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
78865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
78876e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
78886e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
7889d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7890d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
78915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
78925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
78935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
78945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
78955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
78965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
78976e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
78986e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
78996e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
79006e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
79016e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
79026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
79035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
79045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
79055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
79065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
79075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
79085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
79095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
79105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
79115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
79125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
79135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
7914d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->configureVideoTunnelMode(
7915d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
79165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
79175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
79185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
7919d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        } else if (omxNode->storeMetaDataInBuffers(
7920d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE) == OK ||
7921d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                omxNode->prepareForAdaptivePlayback(
7922d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE,
79235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
79245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
79255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
79265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
79275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
79285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
79295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
79305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
79315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
79325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
7933d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->getConfig(
7934d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
79355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
79365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
79375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
79385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
79395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
79405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
7941d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    omxNode->freeNode();
79425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
79435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
79445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
79455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7946a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
7947a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
7948a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
7949a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
7950a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
7951a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
7952a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
7953a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7954a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
7955a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7956a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7957a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7958a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
7959a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7960a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7961a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7962a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7963a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
7964a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7965a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7966a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
7967a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
7968a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7969a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
7970a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7971a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7972a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7973a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
7974a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
7975a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7976a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
7977a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7978a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7979a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7980a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7981a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7982a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7983a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7984a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
7985a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7986a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7987a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7988a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7989a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7990a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7991a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
7992a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7993a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
7994a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7995a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7996a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7997a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7998a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7999a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
8000a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
8001a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
8002a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8003a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
8004a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
8005a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
8006a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
8007a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
8008a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
8009a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
8010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
8011