ACodec.cpp revision 349b8b4c47817a565ded94ff351caf48782f1252
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> 473fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang#include <media/OMXBuffer.h> 483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 4997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h> 504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h> 51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h> 5297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h> 53777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h> 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h" 565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar#include "include/DataConverter.h" 574811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim#include "include/SecureBuffer.h" 587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include "include/SharedMemoryBuffer.h" 5973dd808754c641fe798273d356ee38368715fa7bLajos Molnar#include "omx/OMXUtils.h" 60496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 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> ¬ify) 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), 513d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang mNodeGeneration(0), 514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mUsingNativeWindow(false), 515e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar mNativeWindowUsageBits(0), 516fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN), 5178db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu mIsVideo(false), 518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mIsEncoder(false), 519346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang mFatalError(false), 5209806555d3930be43e11106281dee354820ac1c88Andreas Huber mShutdownInProgress(false), 52154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar mExplicitShutdown(false), 522f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang mIsLegacyVP9Decoder(false), 5239806555d3930be43e11106281dee354820ac1c88Andreas Huber mEncoderDelay(0), 5249806555d3930be43e11106281dee354820ac1c88Andreas Huber mEncoderPadding(0), 525e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang mRotationDegrees(0), 5269806555d3930be43e11106281dee354820ac1c88Andreas Huber mChannelMaskPresent(false), 527054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mChannelMask(0), 528054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mDequeueCounter(0), 529054219874873b41f1c815552987c10465c34ba2bLajos Molnar mMetadataBuffersToSubmit(0), 5305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mNumUndequeuedBuffers(0), 53194ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatFrameDelayUs(-1ll), 5322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mMaxPtsGapUs(-1ll), 53337b2b389139ed638831e49708c947863eef631efRonghua Wu mMaxFps(-1), 5342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs(-1ll), 535609b815a3131d22da38b2f452faa9f89daad4039Andy Hung mTimePerCaptureUs(-1ll), 536ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad mCreateInputBuffersSuspended(false), 5378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar mTunneled(false), 538db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang mDescribeColorAspectsIndex((OMX_INDEXTYPE)0), 539db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0) { 540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUninitializedState = new UninitializedState(this); 541c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mLoadedState = new LoadedState(this); 542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLoadedToIdleState = new LoadedToIdleState(this); 543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mIdleToExecutingState = new IdleToExecutingState(this); 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mExecutingState = new ExecutingState(this); 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputPortSettingsChangedState = 547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new OutputPortSettingsChangedState(this); 548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mExecutingToIdleState = new ExecutingToIdleState(this); 550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mIdleToLoadedState = new IdleToLoadedState(this); 551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingState = new FlushingState(this); 552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 554dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mInputEOSResult = OK; 555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 556d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 557d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 558d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang 559fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop)); 560fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar 561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber changeState(mUninitializedState); 562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 564f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() { 565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 567f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) { 568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNotify = msg; 569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 571f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) { 572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setWhat(kWhatSetup); 5731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar msg->setTarget(this); 574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 577a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> ¶ms) { 5781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 579a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber msg->setMessage("params", params); 580a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber msg->post(); 581a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 582a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 5835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) { 5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setWhat(kWhatAllocateComponent); 5851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar msg->setTarget(this); 5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->post(); 5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) { 5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setWhat(kWhatConfigureComponent); 5911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar msg->setTarget(this); 5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->post(); 5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) { 5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> msg = new AMessage(kWhatSetSurface, this); 5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar msg->setObject("surface", surface); 5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> response; 6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = msg->postAndAwaitResponse(&response); 6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == OK) { 6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar (void)response->findInt32("err", &err); 6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 6071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 6087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() { 6091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatCreateInputSurface, this))->post(); 6107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 6117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 6128f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface( 613d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<PersistentSurface> &surface) { 6148f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 615d291c222357303b9611cab89d0c3b047584ef377Chong Zhang msg->setObject("input-surface", surface); 616d291c222357303b9611cab89d0c3b047584ef377Chong Zhang msg->post(); 617d291c222357303b9611cab89d0c3b047584ef377Chong Zhang} 618d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() { 6201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatSignalEndOfInputStream, this))->post(); 6217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 6227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 6235778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() { 6241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStart, this))->post(); 6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 627f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() { 6287a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong ALOGV("[%s] signalFlush", mComponentName.c_str()); 6291d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatFlush, this))->post(); 630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 632f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() { 6331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatResume, this))->post(); 634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) { 6371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatShutdown, this); 638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber msg->setInt32("keepComponentAllocated", keepComponentAllocated); 639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber msg->post(); 64030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar if (!keepComponentAllocated) { 64130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar // ensure shutdown completes in 3 seconds 6421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000); 64330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar } 644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 646496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() { 6471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatRequestIDRFrame, this))->post(); 648496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 649496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 6504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed. 6524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input 6534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port. For now keep submitting an output buffer if there was an 6544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port. 655054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() { 6564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] && 657054219874873b41f1c815552987c10465c34ba2bLajos Molnar mMetadataBuffersToSubmit > 0) { 658054219874873b41f1c815552987c10465c34ba2bLajos Molnar (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post(); 6594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar } 6604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar} 6614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar 6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) { 6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // allow keeping unset surface 6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (surface == NULL) { 6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mNativeWindow != NULL) { 6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGW("cannot unset a surface"); 6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return INVALID_OPERATION; 6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return OK; 6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 6711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 672e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar // cannot switch from bytebuffers to surface 6731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mNativeWindow == NULL) { 6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGW("component was not configured with a surface"); 6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return INVALID_OPERATION; 6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 6771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 6781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ANativeWindow *nativeWindow = surface.get(); 6791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // if we have not yet started the codec, we can simply set the native window 6801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mBuffers[kPortIndexInput].size() == 0) { 6811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mNativeWindow = surface; 6821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return OK; 6831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 6841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // we do not support changing a tunneled surface after start 6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mTunneled) { 6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGW("cannot change tunneled surface"); 6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return INVALID_OPERATION; 6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 691e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar int usageBits = 0; 692098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar // no need to reconnect as we will not dequeue all buffers 693098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar status_t err = setupNativeWindowSizeFormatAndUsage( 694d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang nativeWindow, &usageBits, !storingMetadataInDecodedBuffers()); 6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err != OK) { 6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 699f42917964a76720932b23e67a05d034cd0cf346bChong Zhang int ignoredFlags = kVideoGrallocUsage; 700e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar // New output surface is not allowed to add new usage flag except ignored ones. 701e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) { 702e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits); 703e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar return BAD_VALUE; 704e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar } 705e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar 7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // get min undequeued count. We cannot switch to a surface that has a higher 7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // undequeued count than we allocated. 7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar int minUndequeuedBuffers = 0; 7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = nativeWindow->query( 7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar &minUndequeuedBuffers); 7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err != 0) { 7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar strerror(-err), -err); 7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) { 7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)", 7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar minUndequeuedBuffers, mNumUndequeuedBuffers); 7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return BAD_VALUE; 7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // we cannot change the number of output buffers while OMX is running 7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // set up surface to the same count 7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput]; 7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGV("setting up surface for %zu buffers", buffers.size()); 7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = native_window_set_buffer_count(nativeWindow, buffers.size()); 7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err != 0) { 7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar -err); 7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 735dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // need to enable allocation when attaching 736dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar surface->getIGraphicBufferProducer()->allowAllocation(true); 737dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar 7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // for meta data mode, we move dequeud buffers to the new surface. 7391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // for non-meta mode, we must move all registered buffers 7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar for (size_t i = 0; i < buffers.size(); ++i) { 7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar const BufferInfo &info = buffers[i]; 7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // skip undequeued buffers for meta data mode 743054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (storingMetadataInDecodedBuffers() 7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 745598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa ALOGV("skipping buffer"); 7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar continue; 7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer()); 7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer()); 7511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err != OK) { 7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGE("failed to attach buffer %p to the new surface: %s (%d)", 7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar info.mGraphicBuffer->getNativeBuffer(), 7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar strerror(-err), -err); 7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // cancel undequeued buffers to new surface 760d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (!storingMetadataInDecodedBuffers()) { 7611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar for (size_t i = 0; i < buffers.size(); ++i) { 76215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar BufferInfo &info = buffers.editItemAt(i); 7631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer()); 7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = nativeWindow->cancelBuffer( 76615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd); 76715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info.mFenceFd = -1; 7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err != OK) { 7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGE("failed to cancel buffer %p to the new surface: %s (%d)", 7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar info.mGraphicBuffer->getNativeBuffer(), 7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar strerror(-err), -err); 7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // disallow further allocation 7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar (void)surface->getIGraphicBufferProducer()->allowAllocation(false); 7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 780484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar // push blank buffers to previous window if requested 781484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) { 782484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar pushBlankBuffersToNativeWindow(mNativeWindow.get()); 783484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar } 784484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar 7851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mNativeWindow = nativeWindow; 786e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar mNativeWindowUsageBits = usageBits; 7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return OK; 7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 790d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhangstatus_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) { 791d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang status_t err = mOMXNode->setPortMode(portIndex, mode); 792d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (err != OK) { 793d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang ALOGE("[%s] setPortMode on %s to %s failed w/ err %d", 794d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mComponentName.c_str(), 795d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang portIndex == kPortIndexInput ? "input" : "output", 796d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang asString(mode), 797d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err); 798d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang return err; 799d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } 800d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang 801d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mPortMode[portIndex] = mode; 802d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang return OK; 803d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang} 804d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang 805f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mDealer[portIndex] == NULL); 809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mBuffers[portIndex].isEmpty()); 810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 813d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (storingMetadataInDecodedBuffers()) { 814054219874873b41f1c815552987c10465c34ba2bLajos Molnar err = allocateOutputMetadataBuffers(); 815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } else { 816054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar err = allocateOutputBuffersFromNativeWindow(); 817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 8185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 8195778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 8205778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&def); 8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.nPortIndex = portIndex; 822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 823d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 824d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err == OK) { 827d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang const IOMX::PortMode &mode = mPortMode[portIndex]; 8285b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar size_t bufSize = def.nBufferSize; 829d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang // Always allocate VideoNativeMetadata if using ANWBuffer. 830d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang // OMX might use gralloc source internally, but we don't share 831d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang // metadata buffer with OMX, OMX has its own headers. 832d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (mode == IOMX::kPortModeDynamicANWBuffer) { 833054219874873b41f1c815552987c10465c34ba2bLajos Molnar bufSize = sizeof(VideoNativeMetadata); 834d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } else if (mode == IOMX::kPortModeDynamicNativeHandle) { 8353e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar bufSize = sizeof(VideoNativeHandleMetadata); 836054219874873b41f1c815552987c10465c34ba2bLajos Molnar } 837054219874873b41f1c815552987c10465c34ba2bLajos Molnar 8385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar size_t conversionBufferSize = 0; 8395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 8405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar sp<DataConverter> converter = mConverter[portIndex]; 8415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (converter != NULL) { 8425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // here we assume sane conversions of max 4:1, so result fits in int32 8435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (portIndex == kPortIndexInput) { 8445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar conversionBufferSize = converter->sourceSize(bufSize); 8455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } else { 8465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar conversionBufferSize = converter->targetSize(bufSize); 8475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 848054219874873b41f1c815552987c10465c34ba2bLajos Molnar } 849054219874873b41f1c815552987c10465c34ba2bLajos Molnar 85028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar size_t alignment = MemoryDealer::getAllocationAlignment(); 85128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar 852d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port", 8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber mComponentName.c_str(), 854d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode), 8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber portIndex == kPortIndexInput ? "input" : "output"); 856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // verify buffer sizes to avoid overflow in align() 8585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) { 85928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar ALOGE("b/22885421"); 86028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar return NO_MEMORY; 86128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar } 86228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar 86328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar // don't modify bufSize as OMX may not expect it to increase after negotiation 86428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar size_t alignedSize = align(bufSize, alignment); 8655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar size_t alignedConvSize = align(conversionBufferSize, alignment); 8665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) { 86734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen ALOGE("b/22885421"); 86834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen return NO_MEMORY; 86934e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen } 87028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar 8715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize); 872d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (mode != IOMX::kPortModePresetSecureBuffer) { 873d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec"); 874d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } 875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 876fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim const sp<AMessage> &format = 877fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim portIndex == kPortIndexInput ? mInputFormat : mOutputFormat; 878054219874873b41f1c815552987c10465c34ba2bLajos Molnar for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) { 879d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang sp<IMemory> mem; 880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 881ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber BufferInfo info; 882ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info.mStatus = BufferInfo::OWNED_BY_US; 88315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info.mFenceFd = -1; 88490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar info.mRenderInfo = NULL; 885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 886d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (mode == IOMX::kPortModePresetSecureBuffer) { 887a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar void *ptr = NULL; 8881b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar sp<NativeHandle> native_handle; 889d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->allocateSecureBuffer( 890d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang portIndex, bufSize, &info.mBufferID, 891a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar &ptr, &native_handle); 892a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar 8934811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim info.mData = (native_handle == NULL) 8944811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim ? new SecureBuffer(format, ptr, bufSize) 8954811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim : new SecureBuffer(format, native_handle, bufSize); 8965b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar info.mCodecData = info.mData; 8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 898d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mem = mDealer[portIndex]->allocate(bufSize); 899d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (mem == NULL || mem->pointer() == NULL) { 900d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang return NO_MEMORY; 901d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } 902ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 903d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = mOMXNode->useBuffer(portIndex, mem, &info.mBufferID); 9045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 905d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (mode == IOMX::kPortModeDynamicANWBuffer) { 906054219874873b41f1c815552987c10465c34ba2bLajos Molnar ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1; 907054219874873b41f1c815552987c10465c34ba2bLajos Molnar } 9085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 909d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang info.mCodecData = new SharedMemoryBuffer(format, mem); 910d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang info.mCodecRef = mem; 911d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang 9125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // if we require conversion, allocate conversion buffer for client use; 9135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // otherwise, reuse codec buffer 9145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (mConverter[portIndex] != NULL) { 9155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar CHECK_GT(conversionBufferSize, (size_t)0); 9165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mem = mDealer[portIndex]->allocate(conversionBufferSize); 9175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (mem == NULL|| mem->pointer() == NULL) { 9185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar return NO_MEMORY; 9195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 9207e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim info.mData = new SharedMemoryBuffer(format, mem); 9215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar info.mMemRef = mem; 9225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } else { 9235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar info.mData = info.mCodecData; 9245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar info.mMemRef = info.mCodecRef; 9255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber mBuffers[portIndex].push(info); 9291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 9301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> notify = mNotify->dup(); 938d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatBuffersAllocated); 9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->setInt32("portIndex", portIndex); 941eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 942eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber sp<PortDescription> desc = new PortDescription; 943eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 945eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber const BufferInfo &info = mBuffers[portIndex][i]; 9464811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim desc->addBuffer(info.mBufferID, info.mData); 947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 949eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber notify->setObject("portDesc", desc); 9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->post(); 9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 955e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage( 956098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */, 957098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar bool reconnect) { 9581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar OMX_PARAM_PORTDEFINITIONTYPE def; 9591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar InitOMXParams(&def); 9601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar def.nPortIndex = kPortIndexOutput; 9611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 962d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 963d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 9641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 9651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err != OK) { 9661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 9671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 9681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 9691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar OMX_U32 usage = 0; 970d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage); 9711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err != 0) { 9721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGW("querying usage flags from OMX IL component failed: %d", err); 9731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // XXX: Currently this error is logged, but not fatal. 9741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar usage = 0; 9751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 9761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar int omxUsage = usage; 9771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 9781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mFlags & kFlagIsGrallocUsageProtected) { 9791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar usage |= GRALLOC_USAGE_PROTECTED; 9801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 9811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 982f42917964a76720932b23e67a05d034cd0cf346bChong Zhang usage |= kVideoGrallocUsage; 983e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar *finalUsage = usage; 984b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 985fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop)); 986fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN; 987fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar 9881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage); 9891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return setNativeWindowSizeFormatAndUsage( 9901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar nativeWindow, 9911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar def.format.video.nFrameWidth, 9921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar def.format.video.nFrameHeight, 9931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar def.format.video.eColorFormat, 9941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mRotationDegrees, 995098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar usage, 996098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar reconnect); 9971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 9981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 9991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow( 10001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar OMX_U32 *bufferCount, OMX_U32 *bufferSize, 1001098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar OMX_U32 *minUndequeuedBuffers, bool preregister) { 1002098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar 10031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar OMX_PARAM_PORTDEFINITIONTYPE def; 10041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar InitOMXParams(&def); 10051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar def.nPortIndex = kPortIndexOutput; 10061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 1007d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 1008d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 10091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 10101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == OK) { 1011098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar err = setupNativeWindowSizeFormatAndUsage( 1012098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar mNativeWindow.get(), &mNativeWindowUsageBits, preregister /* reconnect */); 10131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 10141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err != OK) { 1015e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar mNativeWindowUsageBits = 0; 10161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 10171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 10181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 1019ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad // Exits here for tunneled video playback codecs -- i.e. skips native window 1020ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad // buffer allocation step as this is managed by the tunneled OMX omponent 1021ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad // itself and explicitly sets def.nBufferCountActual to 0. 1022ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad if (mTunneled) { 1023ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad ALOGV("Tunneled Playback: skipping native window buffer allocation."); 1024ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad def.nBufferCountActual = 0; 1025d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 1026d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 1027ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad 1028ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad *minUndequeuedBuffers = 0; 1029ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad *bufferCount = 0; 1030ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad *bufferSize = 0; 1031ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad return err; 1032ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad } 1033ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad 1034054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar *minUndequeuedBuffers = 0; 1035258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis err = mNativeWindow->query( 1036258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 1037054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar (int *)minUndequeuedBuffers); 1038258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis 1039258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (err != 0) { 104029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 1041258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis strerror(-err), -err); 1042258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis return err; 1043258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 1044258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis 1045e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar // FIXME: assume that surface is controlled by app (native window 1046e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar // returns the number for the case when surface is not controlled by app) 10471faa41704e0b976e546321effcb09a85767d51baLajos Molnar // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported 10481faa41704e0b976e546321effcb09a85767d51baLajos Molnar // For now, try to allocate 1 more buffer, but don't fail if unsuccessful 1049e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar 1050e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar // Use conservative allocation while also trying to reduce starvation 1051e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar // 1052e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the 1053e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar // minimum needed for the consumer to be able to work 1054e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar // 2. try to allocate two (2) additional buffers to reduce starvation from 1055e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar // the consumer 10561faa41704e0b976e546321effcb09a85767d51baLajos Molnar // plus an extra buffer to account for incorrect minUndequeuedBufs 10571faa41704e0b976e546321effcb09a85767d51baLajos Molnar for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { 1058e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar OMX_U32 newBufferCount = 1059e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers; 1060258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis def.nBufferCountActual = newBufferCount; 1061d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 1062d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 1063258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis 1064e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar if (err == OK) { 1065e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar *minUndequeuedBuffers += extraBuffers; 1066e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar break; 1067e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar } 1068e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar 1069609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGW("[%s] setting nBufferCountActual to %u failed: %d", 1070e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar mComponentName.c_str(), newBufferCount, err); 1071e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar /* exit condition */ 1072e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar if (extraBuffers == 0) { 1073258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis return err; 1074258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 1075258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 1076258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis 1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = native_window_set_buffer_count( 1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNativeWindow.get(), def.nBufferCountActual); 1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 108129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber -err); 1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar *bufferCount = def.nBufferCountActual; 1087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar *bufferSize = def.nBufferSize; 1088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return err; 1089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 1090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() { 1092d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang // This method only handles the non-metadata mode (or simulating legacy 1093d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang // mode with metadata, which is transparent to ACodec). 1094d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang CHECK(!storingMetadataInDecodedBuffers()); 10953fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang 1096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 1097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status_t err = configureOutputBuffersFromNativeWindow( 1098098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */); 1099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (err != 0) 1100054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return err; 1101e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar mNumUndequeuedBuffers = minUndequeuedBuffers; 1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 11033fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang static_cast<Surface*>(mNativeWindow.get()) 11043fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang ->getIGraphicBufferProducer()->allowAllocation(true); 11053298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia 1106609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGV("[%s] Allocating %u buffers from a native window of size %u on " 1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "output port", 1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mComponentName.c_str(), bufferCount, bufferSize); 1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Dequeue buffers and send them to OMX 1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar for (OMX_U32 i = 0; i < bufferCount; i++) { 11128ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev ANativeWindowBuffer *buf; 111315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar int fenceFd; 111415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 111629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 112174006804065941841883c4b46ee785070164023fJamie Gennis BufferInfo info; 112274006804065941841883c4b46ee785070164023fJamie Gennis info.mStatus = BufferInfo::OWNED_BY_US; 112315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info.mFenceFd = fenceFd; 112415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info.mIsReadFence = false; 112590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar info.mRenderInfo = NULL; 112674006804065941841883c4b46ee785070164023fJamie Gennis info.mGraphicBuffer = graphicBuffer; 11273fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang 11283fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode 11293fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang // OMX doesn't use the shared memory buffer, but some code still 11303fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang // access info.mData. Create an ABuffer as a placeholder. 1131d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize)); 1132d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang info.mCodecData = info.mData; 11333fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang 113474006804065941841883c4b46ee785070164023fJamie Gennis mBuffers[kPortIndexOutput].push(info); 113574006804065941841883c4b46ee785070164023fJamie Gennis 1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id bufferId; 11373fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId); 1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1139609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGE("registering GraphicBuffer %u with OMX IL component failed: " 114074006804065941841883c4b46ee785070164023fJamie Gennis "%d", i, err); 1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 114474006804065941841883c4b46ee785070164023fJamie Gennis mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId; 114574006804065941841883c4b46ee785070164023fJamie Gennis 1146609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)", 1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mComponentName.c_str(), 1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bufferId, graphicBuffer.get()); 1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 cancelStart; 1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 cancelEnd; 1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1154d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (err != OK) { 1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If an error occurred while dequeuing we need to cancel any buffers 11563fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang // that were dequeued. Also cancel all if we're in legacy metadata mode. 1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber cancelStart = 0; 115874006804065941841883c4b46ee785070164023fJamie Gennis cancelEnd = mBuffers[kPortIndexOutput].size(); 1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // Return the required minimum undequeued buffers to the native window. 1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar cancelStart = bufferCount - minUndequeuedBuffers; 1162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar cancelEnd = bufferCount; 1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 11673175d2babfcdcb64f41309157e0436d00375ae4bWei Jia if (info->mStatus == BufferInfo::OWNED_BY_US) { 11683175d2babfcdcb64f41309157e0436d00375ae4bWei Jia status_t error = cancelBufferToNativeWindow(info); 11693175d2babfcdcb64f41309157e0436d00375ae4bWei Jia if (err == 0) { 11703175d2babfcdcb64f41309157e0436d00375ae4bWei Jia err = error; 11713175d2babfcdcb64f41309157e0436d00375ae4bWei Jia } 11723fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia } 1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 11753fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang static_cast<Surface*>(mNativeWindow.get()) 11763fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang ->getIGraphicBufferProducer()->allowAllocation(false); 11773fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang 1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1181054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() { 1182d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang CHECK(storingMetadataInDecodedBuffers()); 11833fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang 1184054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 1185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status_t err = configureOutputBuffersFromNativeWindow( 1186098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar &bufferCount, &bufferSize, &minUndequeuedBuffers, 11873fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang false /* preregister */); 1188d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (err != OK) 1189054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return err; 1190e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar mNumUndequeuedBuffers = minUndequeuedBuffers; 1191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1192e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar ALOGV("[%s] Allocating %u meta buffers on output port", 1193e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar mComponentName.c_str(), bufferCount); 1194e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar 1195e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar for (OMX_U32 i = 0; i < bufferCount; i++) { 1196e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar BufferInfo info; 1197e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 119815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info.mFenceFd = -1; 119990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar info.mRenderInfo = NULL; 1200e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar info.mGraphicBuffer = NULL; 1201e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar info.mDequeuedAt = mDequeueCounter; 1202e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar 1203d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize)); 1204349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang 1205349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang // Initialize fence fd to -1 to avoid warning in freeBuffer(). 1206349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang ((VideoNativeMetadata *)info.mData->base())->nFenceFd = -1; 1207349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang 12085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar info.mCodecData = info.mData; 1209e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar 1210d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID); 1211e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar mBuffers[kPortIndexOutput].push(info); 1212e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar 1213d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang ALOGV("[%s] allocated meta buffer with ID %u", 1214d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mComponentName.c_str(), info.mBufferID); 1215e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar } 1216e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar 1217054219874873b41f1c815552987c10465c34ba2bLajos Molnar mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers; 1218054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return err; 1219054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 1220054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1221054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() { 1222054219874873b41f1c815552987c10465c34ba2bLajos Molnar CHECK(storingMetadataInDecodedBuffers()); 1223054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (mMetadataBuffersToSubmit == 0) 1224054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return OK; 1225054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1226054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar BufferInfo *info = dequeueBufferFromNativeWindow(); 12270806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (info == NULL) { 1228054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return ERROR_IO; 12290806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 1230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1231609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p", 1232054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get()); 1233054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1234054219874873b41f1c815552987c10465c34ba2bLajos Molnar --mMetadataBuffersToSubmit; 123515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->checkWriteFence("submitOutputMetadataBuffer"); 12363fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang return fillBuffer(info); 1237054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 1238054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 123915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) { 124015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar status_t res = OK; 124115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fd >= 0) { 124215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar sp<Fence> fence = new Fence(fd); 124315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar res = fence->wait(IOMX::kFenceTimeoutMs); 124415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg); 124515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 124615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar return res; 124715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar} 124815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 12490806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static 12500806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) { 12510806340688c937e7b78c2d89db3809274130df4eLajos Molnar switch (s) { 12520806340688c937e7b78c2d89db3809274130df4eLajos Molnar case BufferInfo::OWNED_BY_US: return "OUR"; 12530806340688c937e7b78c2d89db3809274130df4eLajos Molnar case BufferInfo::OWNED_BY_COMPONENT: return "COMPONENT"; 12540806340688c937e7b78c2d89db3809274130df4eLajos Molnar case BufferInfo::OWNED_BY_UPSTREAM: return "UPSTREAM"; 12550806340688c937e7b78c2d89db3809274130df4eLajos Molnar case BufferInfo::OWNED_BY_DOWNSTREAM: return "DOWNSTREAM"; 12560806340688c937e7b78c2d89db3809274130df4eLajos Molnar case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE"; 12570806340688c937e7b78c2d89db3809274130df4eLajos Molnar case BufferInfo::UNRECOGNIZED: return "UNRECOGNIZED"; 12580806340688c937e7b78c2d89db3809274130df4eLajos Molnar default: return "?"; 12590806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 12600806340688c937e7b78c2d89db3809274130df4eLajos Molnar} 12610806340688c937e7b78c2d89db3809274130df4eLajos Molnar 12620806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) { 12630806340688c937e7b78c2d89db3809274130df4eLajos Molnar CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 12640806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(), 12650806340688c937e7b78c2d89db3809274130df4eLajos Molnar portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size()); 12660806340688c937e7b78c2d89db3809274130df4eLajos Molnar for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 12670806340688c937e7b78c2d89db3809274130df4eLajos Molnar const BufferInfo &info = mBuffers[portIndex][i]; 12680806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGI(" slot %2zu: #%8u %p/%p %s(%d) dequeued:%u", 12690806340688c937e7b78c2d89db3809274130df4eLajos Molnar i, info.mBufferID, info.mGraphicBuffer.get(), 12700806340688c937e7b78c2d89db3809274130df4eLajos Molnar info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(), 12710806340688c937e7b78c2d89db3809274130df4eLajos Molnar _asString(info.mStatus), info.mStatus, info.mDequeuedAt); 12720806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 12730806340688c937e7b78c2d89db3809274130df4eLajos Molnar} 12740806340688c937e7b78c2d89db3809274130df4eLajos Molnar 1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1278609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGV("[%s] Calling cancelBuffer on buffer %u", 1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mComponentName.c_str(), info->mBufferID); 1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 128115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->checkWriteFence("cancelBufferToNativeWindow"); 1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int err = mNativeWindow->cancelBuffer( 128315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 128415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->mFenceFd = -1; 1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 12863fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window", 12873fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia mComponentName.c_str(), info->mBufferID); 12880806340688c937e7b78c2d89db3809274130df4eLajos Molnar // change ownership even if cancelBuffer fails 1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 12913fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia return err; 1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 129490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer( 129590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) { 129690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 129790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar info->mRenderInfo = 129890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mRenderTracker.updateInfoForDequeuedBuffer( 129990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]); 130090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 130190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // check for any fences already signaled 130290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo); 130390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar} 130490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 130590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 130690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) { 130790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mRenderTracker.dumpRenderQueue(); 130890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 130990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar} 131090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 131190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) { 131290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar sp<AMessage> msg = mNotify->dup(); 131390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar msg->setInt32("what", CodecBase::kWhatOutputFramesRendered); 131490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar std::list<FrameRenderTracker::Info> done = 131590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete); 131690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 131790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // unlink untracked frames 131890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin(); 131990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar it != done.cend(); ++it) { 1320604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar ssize_t index = it->getIndex(); 1321604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) { 1322604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL; 1323604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar } else if (index >= 0) { 1324604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar // THIS SHOULD NEVER HAPPEN 1325604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size()); 132690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 132790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 132890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 132990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (MediaCodec::CreateFramesRenderedMessage(done, msg)) { 133090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar msg->post(); 133190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 133290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar} 133390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 1334f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 13358ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev ANativeWindowBuffer *buf; 1336054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar CHECK(mNativeWindow.get() != NULL); 1337ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad 1338ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad if (mTunneled) { 1339ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel" 1340ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad " video playback mode mode!"); 1341ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad return NULL; 1342ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad } 1343ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad 1344346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang if (mFatalError) { 1345346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang ALOGW("not dequeuing from native window due to fatal error"); 1346346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang return NULL; 1347346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang } 1348346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang 134915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar int fenceFd = -1; 1350dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar do { 135115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 135215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (err != 0) { 135315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err); 1354dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar return NULL; 1355dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar } 1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1357dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar bool stale = false; 1358b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1359b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker i--; 1360dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1361dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar 1362dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar if (info->mGraphicBuffer != NULL && 136390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar info->mGraphicBuffer->handle == buf->handle) { 1364dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // Since consumers can attach buffers to BufferQueues, it is possible 1365dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // that a known yet stale buffer can return from a surface that we 1366dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // once used. We can simply ignore this as we have already dequeued 1367dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // this buffer properly. NOTE: this does not eliminate all cases, 1368dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // e.g. it is possible that we have queued the valid buffer to the 1369dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // NW, and a stale copy of the same buffer gets dequeued - which will 1370dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // be treated as the valid buffer by ACodec. 1371dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1372dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar ALOGI("dequeued stale buffer %p. discarding", buf); 1373dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar stale = true; 1374dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar break; 1375dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar } 137690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 1377dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer()); 1378dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar info->mStatus = BufferInfo::OWNED_BY_US; 137915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow"); 138090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar updateRenderInfoForDequeuedBuffer(buf, fenceFd, info); 1381dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar return info; 1382dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar } 1383dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar } 1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1385dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // It is also possible to receive a previously unregistered buffer 1386dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // in non-meta mode. These should be treated as stale buffers. The 1387dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // same is possible in meta mode, in which case, it will be treated 1388dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // as a normal buffer, which is not desirable. 1389dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // TODO: fix this. 1390d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (!stale && !storingMetadataInDecodedBuffers()) { 1391dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf); 1392dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar stale = true; 1393dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar } 1394dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar if (stale) { 1395dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // TODO: detach stale buffer, but there is no API yet to do it. 1396dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar buf = NULL; 1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1398dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar } while (buf == NULL); 1399054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1400dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar // get oldest undequeued buffer 1401dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar BufferInfo *oldest = NULL; 1402b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1403b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker i--; 1404dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar BufferInfo *info = 1405dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar &mBuffers[kPortIndexOutput].editItemAt(i); 1406054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW && 1407054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar (oldest == NULL || 1408054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // avoid potential issues from counter rolling over 1409054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mDequeueCounter - info->mDequeuedAt > 1410054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mDequeueCounter - oldest->mDequeuedAt)) { 1411054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar oldest = info; 1412054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 1413054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 1414054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 14150806340688c937e7b78c2d89db3809274130df4eLajos Molnar // it is impossible dequeue a buffer when there are no buffers with ANW 14160806340688c937e7b78c2d89db3809274130df4eLajos Molnar CHECK(oldest != NULL); 14170806340688c937e7b78c2d89db3809274130df4eLajos Molnar // it is impossible to dequeue an unknown buffer in non-meta mode, as the 14180806340688c937e7b78c2d89db3809274130df4eLajos Molnar // while loop above does not complete 1419054219874873b41f1c815552987c10465c34ba2bLajos Molnar CHECK(storingMetadataInDecodedBuffers()); 1420054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 14210806340688c937e7b78c2d89db3809274130df4eLajos Molnar // discard buffer in LRU info and replace with new buffer 14220806340688c937e7b78c2d89db3809274130df4eLajos Molnar oldest->mGraphicBuffer = new GraphicBuffer(buf, false); 14230806340688c937e7b78c2d89db3809274130df4eLajos Molnar oldest->mStatus = BufferInfo::OWNED_BY_US; 142415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest"); 142590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mRenderTracker.untrackFrame(oldest->mRenderInfo); 142690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar oldest->mRenderInfo = NULL; 1427d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar 1428d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p", 1429d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]), 1430d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mDequeueCounter - oldest->mDequeuedAt, 1431d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang oldest->mGraphicBuffer->getNativeBuffer()); 1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 143390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest); 14340806340688c937e7b78c2d89db3809274130df4eLajos Molnar return oldest; 1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 1438777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim status_t err = OK; 1439938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich for (size_t i = mBuffers[portIndex].size(); i > 0;) { 1440938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich i--; 1441777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim status_t err2 = freeBuffer(portIndex, i); 1442777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err == OK) { 1443777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim err = err2; 1444777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14470806340688c937e7b78c2d89db3809274130df4eLajos Molnar // clear mDealer even on an error 1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDealer[portIndex].clear(); 1449777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1452349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() { 1453777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim status_t err = OK; 1454938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1455938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich i--; 1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = 1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &mBuffers[kPortIndexOutput].editItemAt(i); 1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14592ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar // At this time some buffers may still be with the component 14602ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar // or being drained. 14612ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT && 14622ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) { 1463777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim status_t err2 = freeBuffer(kPortIndexOutput, i); 1464777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err == OK) { 1465777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim err = err2; 1466777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1470777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 14750806340688c937e7b78c2d89db3809274130df4eLajos Molnar status_t err = OK; 1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 147715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // there should not be any fences in the metadata 1478d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL 1479fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) { 1480fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd; 148115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 148215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ALOGW("unreleased fence (%d) in %s metadata buffer %zu", 148315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar fenceFd, portIndex == kPortIndexInput ? "input" : "output", i); 148415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 148515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 148615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 14870806340688c937e7b78c2d89db3809274130df4eLajos Molnar switch (info->mStatus) { 14880806340688c937e7b78c2d89db3809274130df4eLajos Molnar case BufferInfo::OWNED_BY_US: 14890806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (portIndex == kPortIndexOutput && mNativeWindow != NULL) { 14900806340688c937e7b78c2d89db3809274130df4eLajos Molnar (void)cancelBufferToNativeWindow(info); 14910806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 14920806340688c937e7b78c2d89db3809274130df4eLajos Molnar // fall through 1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14940806340688c937e7b78c2d89db3809274130df4eLajos Molnar case BufferInfo::OWNED_BY_NATIVE_WINDOW: 1495d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->freeBuffer(portIndex, info->mBufferID); 14960806340688c937e7b78c2d89db3809274130df4eLajos Molnar break; 14970806340688c937e7b78c2d89db3809274130df4eLajos Molnar 14980806340688c937e7b78c2d89db3809274130df4eLajos Molnar default: 14990806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus); 15000806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = FAILED_TRANSACTION; 15010806340688c937e7b78c2d89db3809274130df4eLajos Molnar break; 1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 150415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (info->mFenceFd >= 0) { 150515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(info->mFenceFd); 150615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 150715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 1508604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar if (portIndex == kPortIndexOutput) { 1509604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar mRenderTracker.untrackFrame(info->mRenderInfo, i); 1510604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar info->mRenderInfo = NULL; 1511604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar } 151290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 1513d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang // remove buffer even if mOMXNode->freeBuffer fails 1514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mBuffers[portIndex].removeAt(i); 1515777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 1516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1518f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID( 15190806340688c937e7b78c2d89db3809274130df4eLajos Molnar uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) { 1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mBufferID == bufferID) { 1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (index != NULL) { 1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *index = i; 1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return info; 1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1531777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("Could not find buffer with ID %u", bufferID); 1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return NULL; 1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 15353fd200feb657c157125e45e30c2a7262e3c0244dChong Zhangstatus_t ACodec::fillBuffer(BufferInfo *info) { 15363fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang status_t err; 1537d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (!storingMetadataInDecodedBuffers()) { 15383fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang err = mOMXNode->fillBuffer( 15393fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang info->mBufferID, OMXBuffer::sPreset, info->mFenceFd); 15403fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang } else { 15413fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang err = mOMXNode->fillBuffer( 15423fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang info->mBufferID, info->mGraphicBuffer, info->mFenceFd); 15433fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang } 15443fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang 15453fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang info->mFenceFd = -1; 15463fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang if (err == OK) { 15473fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 15483fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang } 15493fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang return err; 15503fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang} 15513fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang 15525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole( 1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool isEncoder, const char *mime) { 15541ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim const char *role = GetComponentRole(isEncoder, mime); 15555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (role == NULL) { 15565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return BAD_VALUE; 15575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 1558d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = SetComponentRole(mOMXNode, role); 15595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (err != OK) { 15605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar ALOGW("[%s] Failed to set standard component role '%s'.", 15615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar mComponentName.c_str(), role); 15625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 15635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return err; 15645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar} 15655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 15665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec( 1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime, const sp<AMessage> &msg) { 15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t encoder; 15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("encoder", &encoder)) { 15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber encoder = false; 15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1573b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar sp<AMessage> inputFormat = new AMessage; 1574b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar sp<AMessage> outputFormat = new AMessage; 1575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mConfigFormat = msg; 1576e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber mIsEncoder = encoder; 1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1579d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 1580d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 15818db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu 15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = setComponentRole(encoder /* isEncoder */, mime); 15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t bitRate = 0; 15892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // FLAC encoder doesn't need a bitrate, other encoders do 15902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) 15912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi && !msg->findInt32("bitrate", &bitRate)) { 15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 159596bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar // propagate bitrate to the output so that the muxer has it 159696bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar if (encoder && msg->findInt32("bitrate", &bitRate)) { 159796bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the 159896bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar // average bitrate. We've been setting both bitrate and max-bitrate to this same value. 159996bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar outputFormat->setInt32("bitrate", bitRate); 160096bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar outputFormat->setInt32("max-bitrate", bitRate); 160196bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar } 160296bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar 1603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t storeMeta; 1604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (encoder 16053e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar && msg->findInt32("android._input-metadata-buffer-type", &storeMeta) 16063e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar && storeMeta != kMetadataBufferTypeInvalid) { 1607d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang IOMX::PortMode mode; 1608d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (storeMeta == kMetadataBufferTypeNativeHandleSource) { 1609d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mode = IOMX::kPortModeDynamicNativeHandle; 1610d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } else if (storeMeta == kMetadataBufferTypeANWBuffer || 1611d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang storeMeta == kMetadataBufferTypeGrallocSource) { 1612d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mode = IOMX::kPortModeDynamicANWBuffer; 1613d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } else { 1614d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang return BAD_VALUE; 1615d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } 1616d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = setPortMode(kPortIndexInput, mode); 1617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 1618054219874873b41f1c815552987c10465c34ba2bLajos Molnar return err; 1619054219874873b41f1c815552987c10465c34ba2bLajos Molnar } 1620c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 1621c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar uint32_t usageBits; 1622d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (mOMXNode->getParameter( 1623d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 1624c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar &usageBits, sizeof(usageBits)) == OK) { 1625c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar inputFormat->setInt32( 1626c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 1627c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 1628054219874873b41f1c815552987c10465c34ba2bLajos Molnar } 1629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1630308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang int32_t prependSPSPPS = 0; 16313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (encoder 16323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS) 16333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber && prependSPSPPS != 0) { 16343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber OMX_INDEXTYPE index; 1635d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getExtensionIndex( 1636d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang "OMX.google.android.index.prependSPSPPSToIDRFrames", &index); 16373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 16383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (err == OK) { 16393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber PrependSPSPPSToIDRFramesParams params; 16403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber InitOMXParams(¶ms); 16413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber params.bEnable = OMX_TRUE; 16423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 1643d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter(index, ¶ms, sizeof(params)); 16443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 16453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 16463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (err != OK) { 16473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber ALOGE("Encoder could not be configured to emit SPS/PPS before " 16483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber "IDR frames. (err %d)", err); 16493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 16503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber return err; 16513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 16523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 16533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 1654308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang // Only enable metadata mode on encoder output if encoder can prepend 1655308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang // sps/pps to idr frames, since in metadata mode the bitstream is in an 1656308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang // opaque handle, to which we don't have access. 1657308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang int32_t video = !strncasecmp(mime, "video/", 6); 16588db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu mIsVideo = video; 1659308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (encoder && video) { 1660308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS 16613e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta) 1662308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang && storeMeta != 0); 1663d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (mFlags & kFlagIsSecure) { 1664d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang enable = OMX_TRUE; 1665d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } 1666308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 1667d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = setPortMode(kPortIndexOutput, enable ? 1668d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer); 1669308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (err != OK) { 1670d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang return err; 1671308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 1672a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1673a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (!msg->findInt64( 1674a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber "repeat-previous-frame-after", 1675a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber &mRepeatFrameDelayUs)) { 1676a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatFrameDelayUs = -1ll; 1677a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 167894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 16793604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang // only allow 32-bit value, since we pass it as U32 to OMX. 168094ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) { 16812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mMaxPtsGapUs = -1ll; 16823604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < 0) { 16833604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs); 16843604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang mMaxPtsGapUs = -1ll; 16852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 16862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 168737b2b389139ed638831e49708c947863eef631efRonghua Wu if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) { 168837b2b389139ed638831e49708c947863eef631efRonghua Wu mMaxFps = -1; 168937b2b389139ed638831e49708c947863eef631efRonghua Wu } 169037b2b389139ed638831e49708c947863eef631efRonghua Wu 16912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) { 16922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs = -1ll; 169394ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 169472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 169572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!msg->findInt32( 169672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang "create-input-buffers-suspended", 169772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (int32_t*)&mCreateInputBuffersSuspended)) { 169872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCreateInputBuffersSuspended = false; 169972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 1700308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 1701308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 17023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar // NOTE: we only use native window for video decoders 1703054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar sp<RefBase> obj; 17040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar bool haveNativeWindow = msg->findObject("native-window", &obj) 17053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar && obj != NULL && video && !encoder; 1706b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mUsingNativeWindow = haveNativeWindow; 1707e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if (video && !encoder) { 1708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar inputFormat->setInt32("adaptive-playback", false); 17091713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang 17101713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang int32_t usageProtected; 17111713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang if (msg->findInt32("protected", &usageProtected) && usageProtected) { 17121713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang if (!haveNativeWindow) { 17131713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang ALOGE("protected output buffers must be sent to an ANativeWindow"); 17141713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang return PERMISSION_DENIED; 17151713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang } 17161713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang mFlags |= kFlagIsGrallocUsageProtected; 17171713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 17181713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang } 1719a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar 1720a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar if (mFlags & kFlagIsSecure) { 1721a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar // use native_handles for secure input buffers 1722d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer); 1723d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang 1724d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (err != OK) { 1725d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang ALOGI("falling back to non-native_handles"); 1726d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer); 1727d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = OK; // ignore error for now 1728d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } 1729a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar } 1730e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 17313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (haveNativeWindow) { 17321de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar sp<ANativeWindow> nativeWindow = 17331de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get())); 17345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 17356597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar // START of temporary support for automatic FRC - THIS WILL BE REMOVED 17366597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar int32_t autoFrc; 17376597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar if (msg->findInt32("auto-frc", &autoFrc)) { 17386597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar bool enabled = autoFrc; 17396597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar OMX_CONFIG_BOOLEANTYPE config; 17406597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar InitOMXParams(&config); 17416597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar config.bEnabled = (OMX_BOOL)enabled; 1742d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t temp = mOMXNode->setConfig( 1743d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion, 17446597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar &config, sizeof(config)); 17456597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar if (temp == OK) { 17466597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar outputFormat->setInt32("auto-frc", enabled); 17476597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar } else if (enabled) { 17486597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar ALOGI("codec does not support requested auto-frc (err %d)", temp); 17496597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar } 17506597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar } 17516597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar // END of temporary support for automatic FRC 17526597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar 17535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad int32_t tunneled; 17545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (msg->findInt32("feature-tunneled-playback", &tunneled) && 17555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad tunneled != 0) { 17565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad ALOGI("Configuring TUNNELED video playback."); 1757ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad mTunneled = true; 17585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 175997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad int32_t audioHwSync = 0; 176097827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad if (!msg->findInt32("audio-hw-sync", &audioHwSync)) { 17615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad ALOGW("No Audio HW Sync provided for video tunnel"); 17625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } 17635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad err = configureTunneledVideoPlayback(audioHwSync, nativeWindow); 17645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (err != OK) { 176597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad ALOGE("configureTunneledVideoPlayback(%d,%p) failed!", 17665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad audioHwSync, nativeWindow.get()); 17675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad return err; 1768fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar } 1769fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar 1770d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad int32_t maxWidth = 0, maxHeight = 0; 1771d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad if (msg->findInt32("max-width", &maxWidth) && 1772d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad msg->findInt32("max-height", &maxHeight)) { 1773d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad 1774d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->prepareForAdaptivePlayback( 1775d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); 1776d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad if (err != OK) { 1777d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d", 1778d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad mComponentName.c_str(), err); 17793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar // allow failure 17803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar err = OK; 1781d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad } else { 1782d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad inputFormat->setInt32("max-width", maxWidth); 1783d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad inputFormat->setInt32("max-height", maxHeight); 1784d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad inputFormat->setInt32("adaptive-playback", true); 1785d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad } 1786d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad } 17875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } else { 1788ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad ALOGV("Configuring CPU controlled video playback."); 1789ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad mTunneled = false; 1790ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad 17913fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad // Explicity reset the sideband handle of the window for 17923fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad // non-tunneled video in case the window was previously used 17933fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad // for a tunneled video playback. 17943fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad err = native_window_set_sideband_stream(nativeWindow.get(), NULL); 17953fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad if (err != OK) { 17963fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad ALOGE("set_sideband_stream(NULL) failed! (err %d).", err); 17973fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad return err; 17983fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad } 17993fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad 1800d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer); 18015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (err != OK) { 18025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad // if adaptive playback has been requested, try JB fallback 18035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS 18045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad // LARGE MEMORY REQUIREMENT 18055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 18065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad // we will not do adaptive playback on software accessed 18075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad // surfaces as they never had to respond to changes in the 18085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad // crop window, and we don't trust that they will be able to. 18095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad int usageBits = 0; 18105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad bool canDoAdaptivePlayback; 18115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 18125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (nativeWindow->query( 18135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad nativeWindow.get(), 18145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad NATIVE_WINDOW_CONSUMER_USAGE_BITS, 18155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad &usageBits) != OK) { 18165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad canDoAdaptivePlayback = false; 18175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } else { 18185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad canDoAdaptivePlayback = 18195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad (usageBits & 18205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad (GRALLOC_USAGE_SW_READ_MASK | 18215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad GRALLOC_USAGE_SW_WRITE_MASK)) == 0; 18225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } 18235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 18245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad int32_t maxWidth = 0, maxHeight = 0; 18255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (canDoAdaptivePlayback && 18265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad msg->findInt32("max-width", &maxWidth) && 18275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad msg->findInt32("max-height", &maxHeight)) { 18285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)", 18295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad mComponentName.c_str(), maxWidth, maxHeight); 18305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 1831d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->prepareForAdaptivePlayback( 1832d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); 18335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad ALOGW_IF(err != OK, 18345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad "[%s] prepareForAdaptivePlayback failed w/ err %d", 18355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad mComponentName.c_str(), err); 18365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 18375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (err == OK) { 18385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad inputFormat->setInt32("max-width", maxWidth); 18395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad inputFormat->setInt32("max-height", maxHeight); 18405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad inputFormat->setInt32("adaptive-playback", true); 18415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } 1842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 1843d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang // Fall back to legacy mode (use fixed ANWBuffer) 1844d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer); 1845d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (err != OK) { 1846d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang return err; 1847d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } 18485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } else { 1849d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang ALOGV("[%s] setPortMode on output to %s succeeded", 1850d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer)); 1851054219874873b41f1c815552987c10465c34ba2bLajos Molnar CHECK(storingMetadataInDecodedBuffers()); 18525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad inputFormat->setInt32("adaptive-playback", true); 1853fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar } 18540167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber 18555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad int32_t push; 18565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (msg->findInt32("push-blank-buffers-on-shutdown", &push) 18575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad && push != 0) { 18585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 18595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } 18600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber } 1861e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang 1862e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang int32_t rotationDegrees; 1863e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang if (msg->findInt32("rotation-degrees", &rotationDegrees)) { 1864e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang mRotationDegrees = rotationDegrees; 1865e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang } else { 1866e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang mRotationDegrees = 0; 1867e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang } 1868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 1869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 18705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar AudioEncoding pcmEncoding = kAudioEncodingPcm16bit; 18715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding); 18725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // invalid encodings will default to PCM-16bit in setupRawAudioFormat. 18735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 1874308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (video) { 18753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar // determine need for software renderer 18763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar bool usingSwRenderer = false; 18773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) { 18783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar usingSwRenderer = true; 18793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar haveNativeWindow = false; 18803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 18813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar 18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (encoder) { 1883b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = setupVideoEncoder(mime, msg, outputFormat, inputFormat); 18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 1885b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat); 18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar 18883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (err != OK) { 18893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar return err; 18903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 18913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar 18923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (haveNativeWindow) { 18931de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar mNativeWindow = static_cast<Surface *>(obj.get()); 18943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 18953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar 18963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar // fallback for devices that do not handle flex-YUV for native buffers 18973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (haveNativeWindow) { 18983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar int32_t requestedColorFormat = OMX_COLOR_FormatUnused; 18993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (msg->findInt32("color-format", &requestedColorFormat) && 19003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) { 1901777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim status_t err = getPortFormat(kPortIndexOutput, outputFormat); 1902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 1903777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 1904777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 19053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar int32_t colorFormat = OMX_COLOR_FormatUnused; 19063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused; 1907777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (!outputFormat->findInt32("color-format", &colorFormat)) { 1908777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("ouptut port did not have a color format (wrong domain?)"); 1909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return BAD_VALUE; 1910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 19113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar ALOGD("[%s] Requested output format %#x and got %#x.", 19123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mComponentName.c_str(), requestedColorFormat, colorFormat); 19131ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim if (!IsFlexibleColorFormat( 1914d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent) 19153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar || flexibleEquivalent != (OMX_U32)requestedColorFormat) { 19163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar // device did not handle flex-YUV request for native window, fall back 19173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar // to SW renderer 19183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar ALOGI("[%s] Falling back to software renderer", mComponentName.c_str()); 19193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mNativeWindow.clear(); 1920e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar mNativeWindowUsageBits = 0; 19213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar haveNativeWindow = false; 19223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar usingSwRenderer = true; 1923d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang // TODO: implement adaptive-playback support for bytebuffer mode. 1924d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang // This is done by SW codecs, but most HW codecs don't support it. 1925d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer); 1926d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang inputFormat->setInt32("adaptive-playback", false); 19273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (mFlags & kFlagIsGrallocUsageProtected) { 19283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar // fallback is not supported for protected playback 19293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar err = PERMISSION_DENIED; 19303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } else if (err == OK) { 1931b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = setupVideoDecoder( 1932b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mime, msg, haveNativeWindow, usingSwRenderer, outputFormat); 19333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 19343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 19353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 19363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 19373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar 19383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (usingSwRenderer) { 19393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar outputFormat->setInt32("using-sw-renderer", 1); 19403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 194142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 194242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber int32_t numChannels, sampleRate; 194342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber if (!msg->findInt32("channel-count", &numChannels) 194442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber || !msg->findInt32("sample-rate", &sampleRate)) { 194542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber // Since we did not always check for these, leave them optional 194642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber // and have the decoder figure it all out. 194742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber err = OK; 194842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber } else { 194942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber err = setupRawAudioFormat( 195042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber encoder ? kPortIndexInput : kPortIndexOutput, 195142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber sampleRate, 195242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber numChannels); 195342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber } 1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t numChannels, sampleRate; 19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("channel-count", &numChannels) 19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber || !msg->findInt32("sample-rate", &sampleRate)) { 19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = INVALID_OPERATION; 19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 1960aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke int32_t isADTS, aacProfile; 1961b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi int32_t sbrMode; 19628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi int32_t maxOutputChannelCount; 19632965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang int32_t pcmLimiterEnable; 19648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi drcParams_t drc; 1965ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (!msg->findInt32("is-adts", &isADTS)) { 1966ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber isADTS = 0; 1967ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 1968aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (!msg->findInt32("aac-profile", &aacProfile)) { 1969aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke aacProfile = OMX_AUDIO_AACObjectNull; 1970aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke } 1971b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi if (!msg->findInt32("aac-sbr-mode", &sbrMode)) { 1972b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi sbrMode = -1; 1973b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi } 1974ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 19758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) { 19768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi maxOutputChannelCount = -1; 19778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi } 19782965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) { 19792965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang // value is unknown 19802965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang pcmLimiterEnable = -1; 19812965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang } 19828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) { 19838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi // value is unknown 19848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi drc.encodedTargetLevel = -1; 19858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi } 19868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) { 19878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi // value is unknown 19888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi drc.drcCut = -1; 19898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi } 19908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) { 19918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi // value is unknown 19928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi drc.drcBoost = -1; 19938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi } 19948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) { 19958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi // value is unknown 19968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi drc.heavyCompression = -1; 19978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi } 19988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) { 19998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi // value is unknown 20008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi drc.targetRefLevel = -1; 20018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi } 20028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi 2003ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber err = setupAACCodec( 20044471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber encoder, numChannels, sampleRate, bitRate, aacProfile, 20052965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang isADTS != 0, sbrMode, maxOutputChannelCount, drc, 20062965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang pcmLimiterEnable); 20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2008729de186450f78c099637e1fce743fe531862c52Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setupAMRCodec(encoder, false /* isWAMR */, bitRate); 2010729de186450f78c099637e1fce743fe531862c52Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setupAMRCodec(encoder, true /* isWAMR */, bitRate); 2012729de186450f78c099637e1fce743fe531862c52Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW) 2013729de186450f78c099637e1fce743fe531862c52Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) { 2014729de186450f78c099637e1fce743fe531862c52Andreas Huber // These are PCM-like formats with a fixed sample rate but 2015729de186450f78c099637e1fce743fe531862c52Andreas Huber // a variable number of channels. 2016729de186450f78c099637e1fce743fe531862c52Andreas Huber 2017729de186450f78c099637e1fce743fe531862c52Andreas Huber int32_t numChannels; 20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("channel-count", &numChannels)) { 20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = INVALID_OPERATION; 20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 202117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen int32_t sampleRate; 202217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen if (!msg->findInt32("sample-rate", &sampleRate)) { 202317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen sampleRate = 8000; 202417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen } 202517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen err = setupG711Codec(encoder, sampleRate, numChannels); 20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { 2028ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1; 20292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (encoder && 20302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi (!msg->findInt32("channel-count", &numChannels) 20312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi || !msg->findInt32("sample-rate", &sampleRate))) { 20322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("missing channel count or sample rate for FLAC encoder"); 20332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi err = INVALID_OPERATION; 20342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else { 20352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (encoder) { 2036516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (!msg->findInt32( 2037cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar "complexity", &compressionLevel) && 2038cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar !msg->findInt32( 2039516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber "flac-compression-level", &compressionLevel)) { 2040cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar compressionLevel = 5; // default FLAC compression level 20412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else if (compressionLevel < 0) { 2042516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber ALOGW("compression level %d outside [0..8] range, " 2043516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber "using 0", 2044516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber compressionLevel); 20452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi compressionLevel = 0; 20462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else if (compressionLevel > 8) { 2047516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber ALOGW("compression level %d outside [0..8] range, " 2048516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber "using 8", 2049516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber compressionLevel); 20502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi compressionLevel = 8; 20512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 20522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2053516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber err = setupFlacCodec( 2054516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber encoder, numChannels, sampleRate, compressionLevel); 20552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2056ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { 2057ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber int32_t numChannels, sampleRate; 2058ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber if (encoder 2059ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber || !msg->findInt32("channel-count", &numChannels) 2060ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber || !msg->findInt32("sample-rate", &sampleRate)) { 2061ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber err = INVALID_OPERATION; 2062ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber } else { 20635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding); 2064ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber } 206597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) { 206697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu int32_t numChannels; 206797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu int32_t sampleRate; 206897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (!msg->findInt32("channel-count", &numChannels) 206997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu || !msg->findInt32("sample-rate", &sampleRate)) { 207097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu err = INVALID_OPERATION; 207197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } else { 207297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu err = setupAC3Codec(encoder, numChannels, sampleRate); 207397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 20748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) { 20758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad int32_t numChannels; 20768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad int32_t sampleRate; 20778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad if (!msg->findInt32("channel-count", &numChannels) 20788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad || !msg->findInt32("sample-rate", &sampleRate)) { 20798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad err = INVALID_OPERATION; 20808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad } else { 20818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad err = setupEAC3Codec(encoder, numChannels, sampleRate); 20828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad } 20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2084729de186450f78c099637e1fce743fe531862c52Andreas Huber 20854471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber if (err != OK) { 20864471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber return err; 20874471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber } 20884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber 20898b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen if (!msg->findInt32("encoder-delay", &mEncoderDelay)) { 20908b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen mEncoderDelay = 0; 20918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen } 20929806555d3930be43e11106281dee354820ac1c88Andreas Huber 20938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen if (!msg->findInt32("encoder-padding", &mEncoderPadding)) { 20948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen mEncoderPadding = 0; 20958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen } 20968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen 20979806555d3930be43e11106281dee354820ac1c88Andreas Huber if (msg->findInt32("channel-mask", &mChannelMask)) { 20989806555d3930be43e11106281dee354820ac1c88Andreas Huber mChannelMaskPresent = true; 20999806555d3930be43e11106281dee354820ac1c88Andreas Huber } else { 21009806555d3930be43e11106281dee354820ac1c88Andreas Huber mChannelMaskPresent = false; 21019806555d3930be43e11106281dee354820ac1c88Andreas Huber } 21029806555d3930be43e11106281dee354820ac1c88Andreas Huber 2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t maxInputSize; 2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg->findInt32("max-input-size", &maxInputSize)) { 21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize); 2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) { 21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setMinBufferSize(kPortIndexInput, 8192); // XXX 2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21108b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu int32_t priority; 21118b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu if (msg->findInt32("priority", &priority)) { 21128b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu err = setPriority(priority); 21138b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu } 21148b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu 2115ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu int32_t rateInt = -1; 2116ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu float rateFloat = -1; 2117ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu if (!msg->findFloat("operating-rate", &rateFloat)) { 2118ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu msg->findInt32("operating-rate", &rateInt); 2119ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu rateFloat = (float)rateInt; // 16MHz (FLINTMAX) is OK for upper bound. 2120ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu } 2121ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu if (rateFloat > 0) { 2122ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu err = setOperatingRate(rateFloat, video); 2123ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu } 2124ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu 2125697aedf61d6180e72102068a969383018eedfa1eLajos Molnar // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame. 21264e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar mBaseOutputFormat = outputFormat; 2127b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar mLastOutputFormat.clear(); 21284e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar 2129777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim err = getPortFormat(kPortIndexInput, inputFormat); 2130777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err == OK) { 2131777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim err = getPortFormat(kPortIndexOutput, outputFormat); 2132777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err == OK) { 2133777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim mInputFormat = inputFormat; 2134777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim mOutputFormat = outputFormat; 2135777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 2136777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 21375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 21385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // create data converters if needed 21395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (!video && err == OK) { 21405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit; 21415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (encoder) { 21425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding); 21435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding); 21445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (mConverter[kPortIndexInput] != NULL) { 21455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mInputFormat->setInt32("pcm-encoding", pcmEncoding); 21465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 21475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } else { 21485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding); 21495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding); 21505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (mConverter[kPortIndexOutput] != NULL) { 21515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mOutputFormat->setInt32("pcm-encoding", pcmEncoding); 21525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 21535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 21545b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 21555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 2157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 21598b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) { 21608b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu if (priority < 0) { 21618b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu return BAD_VALUE; 21628b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu } 21638b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu OMX_PARAM_U32TYPE config; 21648b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu InitOMXParams(&config); 21658b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu config.nU32 = (OMX_U32)priority; 2166d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t temp = mOMXNode->setConfig( 2167d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexConfigPriority, 21688b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu &config, sizeof(config)); 21698b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu if (temp != OK) { 21708b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu ALOGI("codec does not support config priority (err %d)", temp); 21718b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu } 21728b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu return OK; 21738b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu} 21748b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu 2175ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) { 2176ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu if (rateFloat < 0) { 2177ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu return BAD_VALUE; 2178ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu } 2179ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu OMX_U32 rate; 2180ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu if (isVideo) { 2181ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu if (rateFloat > 65535) { 2182ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu return BAD_VALUE; 2183ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu } 2184ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f); 2185ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu } else { 2186ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu if (rateFloat > UINT_MAX) { 2187ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu return BAD_VALUE; 2188ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu } 2189ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu rate = (OMX_U32)(rateFloat); 2190ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu } 2191ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu OMX_PARAM_U32TYPE config; 2192ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu InitOMXParams(&config); 2193ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu config.nU32 = rate; 2194d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->setConfig( 2195d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate, 2196ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu &config, sizeof(config)); 2197ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu if (err != OK) { 2198ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu ALOGI("codec does not support config operating rate (err %d)", err); 2199ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu } 2200ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu return OK; 2201ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu} 2202ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu 2203870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) { 2204870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 2205870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang InitOMXParams(¶ms); 2206870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang params.nPortIndex = kPortIndexOutput; 2207d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getConfig( 2208d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, ¶ms, sizeof(params)); 2209870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (err == OK) { 2210870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang *intraRefreshPeriod = params.nRefreshPeriod; 2211870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return OK; 2212870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 2213870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2214870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang // Fallback to query through standard OMX index. 2215870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams; 2216870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang InitOMXParams(&refreshParams); 2217870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang refreshParams.nPortIndex = kPortIndexOutput; 2218870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic; 2219d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2220d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams)); 2221870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (err != OK || refreshParams.nCirMBs == 0) { 2222870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang *intraRefreshPeriod = 0; 2223870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return OK; 2224870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 2225870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2226870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang // Calculate period based on width and height 2227870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang uint32_t width, height; 2228870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang OMX_PARAM_PORTDEFINITIONTYPE def; 2229870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang InitOMXParams(&def); 2230870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2231870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang def.nPortIndex = kPortIndexOutput; 2232d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2233d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 2234870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (err != OK) { 2235870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang *intraRefreshPeriod = 0; 2236870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return err; 2237870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 2238870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang width = video_def->nFrameWidth; 2239870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang height = video_def->nFrameHeight; 2240870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang // Use H.264/AVC MacroBlock size 16x16 2241870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs); 2242870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2243870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return OK; 2244870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang} 2245870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2246870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) { 2247870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 2248870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang InitOMXParams(¶ms); 2249870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang params.nPortIndex = kPortIndexOutput; 2250870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang params.nRefreshPeriod = intraRefreshPeriod; 2251d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->setConfig( 2252d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, ¶ms, sizeof(params)); 2253870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (err == OK) { 2254870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return OK; 2255870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 2256870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2257870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang // Only in configure state, a component could invoke setParameter. 2258870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (!inConfigure) { 2259870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return INVALID_OPERATION; 2260870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } else { 2261870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str()); 2262870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 2263870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2264870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams; 2265870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang InitOMXParams(&refreshParams); 2266870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang refreshParams.nPortIndex = kPortIndexOutput; 2267870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic; 2268870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2269870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (intraRefreshPeriod == 0) { 2270870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang // 0 means disable intra refresh. 2271870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang refreshParams.nCirMBs = 0; 2272870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } else { 2273870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang // Calculate macroblocks that need to be intra coded base on width and height 2274870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang uint32_t width, height; 2275870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang OMX_PARAM_PORTDEFINITIONTYPE def; 2276870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang InitOMXParams(&def); 2277870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2278870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang def.nPortIndex = kPortIndexOutput; 2279d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2280d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 2281870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (err != OK) { 2282870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return err; 2283870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 2284870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang width = video_def->nFrameWidth; 2285870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang height = video_def->nFrameHeight; 2286870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang // Use H.264/AVC MacroBlock size 16x16 2287870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod); 2288870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 2289870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2290d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2291d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoIntraRefresh, 2292d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang &refreshParams, sizeof(refreshParams)); 2293870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (err != OK) { 2294870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return err; 2295870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 2296870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 2297870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang return OK; 2298870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang} 2299870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 23000f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnarstatus_t ACodec::configureTemporalLayers( 23010f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) { 23020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (!mIsVideo || !mIsEncoder) { 23030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return INVALID_OPERATION; 23040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 23050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23060f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar AString tsSchema; 23070f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (!msg->findString("ts-schema", &tsSchema)) { 23080f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return OK; 23090f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 23100f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23110f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar unsigned int numLayers = 0; 23120f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar unsigned int numBLayers = 0; 23130f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar int tags; 23140f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar char dummy; 23150f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern = 23160f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar OMX_VIDEO_AndroidTemporalLayeringPatternNone; 23170f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1 23180f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar && numLayers > 0) { 23190f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC; 23200f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c", 23210f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar &numLayers, &dummy, &numBLayers, &dummy)) 23220f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar && (tags == 1 || (tags == 3 && dummy == '+')) 23230f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) { 23240f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar numLayers += numBLayers; 23250f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid; 23260f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } else { 23270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str()); 23280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return BAD_VALUE; 23290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 23300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams; 23320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar InitOMXParams(&layerParams); 23330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerParams.nPortIndex = kPortIndexOutput; 23340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 2335d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 2336d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 2337d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang &layerParams, sizeof(layerParams)); 23380f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23390f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (err != OK) { 23400f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return err; 23410f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } else if (!(layerParams.eSupportedPatterns & pattern)) { 23420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return BAD_VALUE; 23430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 23440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar numLayers = min(numLayers, layerParams.nLayerCountMax); 23460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar numBLayers = min(numBLayers, layerParams.nBLayerCountMax); 23470f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23480f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (!inConfigure) { 23490f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig; 23500f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar InitOMXParams(&layerConfig); 23510f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerConfig.nPortIndex = kPortIndexOutput; 23520f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerConfig.ePattern = pattern; 23530f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerConfig.nPLayerCountActual = numLayers - numBLayers; 23540f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerConfig.nBLayerCountActual = numBLayers; 23550f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerConfig.bBitrateRatiosSpecified = OMX_FALSE; 23560f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 2357d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setConfig( 2358d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering, 23590f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar &layerConfig, sizeof(layerConfig)); 23600f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } else { 23610f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerParams.ePattern = pattern; 23620f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerParams.nPLayerCountActual = numLayers - numBLayers; 23630f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerParams.nBLayerCountActual = numBLayers; 23640f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerParams.bBitrateRatiosSpecified = OMX_FALSE; 23650f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 2366d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2367d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 23680f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar &layerParams, sizeof(layerParams)); 23690f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 23700f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23710f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar AString configSchema; 23720f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) { 23730f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers); 23740f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) { 23750f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar configSchema = AStringPrintf("webrtc.vp8.%u", numLayers); 23760f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 23770f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23780f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (err != OK) { 23790f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar ALOGW("Failed to set temporal layers to %s (requested %s)", 23800f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar configSchema.c_str(), tsSchema.c_str()); 23810f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return err; 23820f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 23830f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 2384d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2385d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 23860f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar &layerParams, sizeof(layerParams)); 23870f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (err == OK) { 23890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)", 23900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar tsSchema.c_str(), configSchema.c_str(), 23910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar asString(layerParams.ePattern), layerParams.ePattern, 23920f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar layerParams.nPLayerCountActual, layerParams.nBLayerCountActual); 23930f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 23940f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (outputFormat.get() == mOutputFormat.get()) { 23950f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar mOutputFormat = mOutputFormat->dup(); // trigger an output format change event 23960f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 23970f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar // assume we got what we configured 23980f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar outputFormat->setString("ts-schema", configSchema); 23990f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 24000f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return err; 24010f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar} 24020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) { 2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&def); 2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nPortIndex = portIndex; 2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2408d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 2409d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (def.nBufferSize >= size) { 2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferSize = size; 2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2421d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2422d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2428d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2429d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2435777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (def.nBufferSize < size) { 2436777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize); 2437777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return FAILED_TRANSACTION; 2438777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 24435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat( 24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) { 24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_AUDIO_PARAM_PORTFORMATTYPE format; 24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&format); 24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber format.nPortIndex = portIndex; 24496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber format.nIndex = index; 2451d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 2452d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioPortFormat, &format, sizeof(format)); 24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (format.eEncoding == desiredFormat) { 24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar 24626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar if (index == kMaxIndicesToCheck) { 24636e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar ALOGW("[%s] stopping checking formats after %u: %s(%x)", 24646e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar mComponentName.c_str(), index, 24656e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar asString(format.eEncoding), format.eEncoding); 24666e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar return ERROR_UNSUPPORTED; 24676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar } 24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2470d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang return mOMXNode->setParameter( 2471d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioPortFormat, &format, sizeof(format)); 24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec( 2475aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke bool encoder, int32_t numChannels, int32_t sampleRate, 24768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode, 24772965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang int32_t maxOutputChannelCount, const drcParams_t& drc, 24782965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang int32_t pcmLimiterEnable) { 2479ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (encoder && isADTS) { 2480ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return -EINVAL; 2481ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2482ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = setupRawAudioFormat( 24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber encoder ? kPortIndexInput : kPortIndexOutput, 24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber sampleRate, 24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber numChannels); 24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (encoder) { 24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC); 24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&def); 25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.nPortIndex = kPortIndexOutput; 25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2503d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2504d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.format.audio.bFlagErrorConcealment = OMX_TRUE; 25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2513d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2514d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_AUDIO_PARAM_AACPROFILETYPE profile; 25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&profile); 25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.nPortIndex = kPortIndexOutput; 25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2524d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2525d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioAac, &profile, sizeof(profile)); 25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.nChannels = numChannels; 25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.eChannelMode = 25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber (numChannels == 1) 25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo; 25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.nSampleRate = sampleRate; 25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.nBitRate = bitRate; 25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.nAudioBandWidth = 0; 25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.nFrameLength = 0; 25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.nAACtools = OMX_AUDIO_AACToolAll; 25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.nAACERtools = OMX_AUDIO_AACERNone; 2543aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile; 25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 2545b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi switch (sbrMode) { 2546b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi case 0: 2547b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi // disable sbr 2548b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 2549b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 2550b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi break; 2551b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi case 1: 2552b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi // enable single-rate sbr 2553b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 2554b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 2555b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi break; 2556b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi case 2: 2557b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi // enable dual-rate sbr 2558b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 2559b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 2560b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi break; 2561b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi case -1: 2562b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi // enable both modes -> the codec will decide which mode should be used 2563b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 2564b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 2565b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi break; 2566b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi default: 2567b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi // unsupported sbr mode 2568b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi return BAD_VALUE; 2569b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi } 2570b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi 25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2572d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2573d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioAac, &profile, sizeof(profile)); 25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&profile); 2584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber profile.nPortIndex = kPortIndexInput; 2585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2586d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2587d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 2590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber profile.nChannels = numChannels; 2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber profile.nSampleRate = sampleRate; 2595ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2596ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber profile.eAACStreamFormat = 2597ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber isADTS 2598ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ? OMX_AUDIO_AACStreamFormatMP4ADTS 2599ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber : OMX_AUDIO_AACStreamFormatMP4FF; 2600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 26018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation; 2602dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen InitOMXParams(&presentation); 26038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi presentation.nMaxOutputChannels = maxOutputChannelCount; 26048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi presentation.nDrcCut = drc.drcCut; 26058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi presentation.nDrcBoost = drc.drcBoost; 26068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi presentation.nHeavyCompression = drc.heavyCompression; 26078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi presentation.nTargetReferenceLevel = drc.targetRefLevel; 26088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi presentation.nEncodedTargetLevel = drc.encodedTargetLevel; 26092965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang presentation.nPCMLimiterEnable = pcmLimiterEnable; 26108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi 2611d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t res = mOMXNode->setParameter( 2612d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioAac, &profile, sizeof(profile)); 26138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi if (res == OK) { 26148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi // optional parameters, will not cause configuration failure 2615d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang mOMXNode->setParameter( 2616d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation, 26178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi &presentation, sizeof(presentation)); 26188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi } else { 26198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res); 26208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi } 2621b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen mSampleRate = sampleRate; 26228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi return res; 26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 262597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec( 262697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu bool encoder, int32_t numChannels, int32_t sampleRate) { 262797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu status_t err = setupRawAudioFormat( 262897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 262997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 263097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (err != OK) { 263197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu return err; 263297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 263397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 263497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (encoder) { 263597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu ALOGW("AC3 encoding is not supported."); 263697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu return INVALID_OPERATION; 263797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 263897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 263997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu OMX_AUDIO_PARAM_ANDROID_AC3TYPE def; 264097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu InitOMXParams(&def); 264197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu def.nPortIndex = kPortIndexInput; 264297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 2643d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2644d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def)); 264597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 264697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (err != OK) { 264797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu return err; 264897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 264997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 265097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu def.nChannels = numChannels; 265197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu def.nSampleRate = sampleRate; 265297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 2653d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang return mOMXNode->setParameter( 2654d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def)); 265597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu} 265697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 26578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec( 26588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad bool encoder, int32_t numChannels, int32_t sampleRate) { 26598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad status_t err = setupRawAudioFormat( 26608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 26618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 26628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad if (err != OK) { 26638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad return err; 26648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad } 26658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 26668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad if (encoder) { 26678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad ALOGW("EAC3 encoding is not supported."); 26688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad return INVALID_OPERATION; 26698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad } 26708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 26718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def; 26728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad InitOMXParams(&def); 26738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad def.nPortIndex = kPortIndexInput; 26748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 2675d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2676d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def)); 26778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 26788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad if (err != OK) { 26798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad return err; 26808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad } 26818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 26828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad def.nChannels = numChannels; 26838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad def.nSampleRate = sampleRate; 26848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 2685d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang return mOMXNode->setParameter( 2686d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def)); 26878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad} 26888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 26895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate( 26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool isAMRWB, int32_t bps) { 26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (isAMRWB) { 26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (bps <= 6600) { 26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB0; 26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 8850) { 26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB1; 26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 12650) { 26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB2; 26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 14250) { 26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB3; 27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 15850) { 27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB4; 27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 18250) { 27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB5; 27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 19850) { 27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB6; 27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 23050) { 27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB7; 27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber // 23850 bps 27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeWB8; 27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { // AMRNB 27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (bps <= 4750) { 27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeNB0; 27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 5150) { 27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeNB1; 27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 5900) { 27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeNB2; 27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 6700) { 27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeNB3; 27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 7400) { 27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeNB4; 27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 7950) { 27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeNB5; 27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (bps <= 10200) { 27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeNB6; 27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber // 12200 bps 27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OMX_AUDIO_AMRBandModeNB7; 27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 27345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) { 2735729de186450f78c099637e1fce743fe531862c52Andreas Huber OMX_AUDIO_PARAM_AMRTYPE def; 2736729de186450f78c099637e1fce743fe531862c52Andreas Huber InitOMXParams(&def); 27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput; 2738729de186450f78c099637e1fce743fe531862c52Andreas Huber 2739d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 2740d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioAmr, &def, sizeof(def)); 2741729de186450f78c099637e1fce743fe531862c52Andreas Huber 2742729de186450f78c099637e1fce743fe531862c52Andreas Huber if (err != OK) { 2743729de186450f78c099637e1fce743fe531862c52Andreas Huber return err; 2744729de186450f78c099637e1fce743fe531862c52Andreas Huber } 2745729de186450f78c099637e1fce743fe531862c52Andreas Huber 2746729de186450f78c099637e1fce743fe531862c52Andreas Huber def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate); 27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2749d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2750d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioAmr, &def, sizeof(def)); 2751729de186450f78c099637e1fce743fe531862c52Andreas Huber 27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2755729de186450f78c099637e1fce743fe531862c52Andreas Huber 27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber return setupRawAudioFormat( 27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber encoder ? kPortIndexInput : kPortIndexOutput, 27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber isWAMR ? 16000 : 8000 /* sampleRate */, 27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1 /* numChannels */); 2760729de186450f78c099637e1fce743fe531862c52Andreas Huber} 2761729de186450f78c099637e1fce743fe531862c52Andreas Huber 276217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) { 2763777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (encoder) { 2764777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return INVALID_OPERATION; 2765777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2767729de186450f78c099637e1fce743fe531862c52Andreas Huber return setupRawAudioFormat( 276817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen kPortIndexInput, sampleRate, numChannels); 2769729de186450f78c099637e1fce743fe531862c52Andreas Huber} 2770729de186450f78c099637e1fce743fe531862c52Andreas Huber 27712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec( 27722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) { 27732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 27742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (encoder) { 27752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_AUDIO_PARAM_FLACTYPE def; 27762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi InitOMXParams(&def); 27772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nPortIndex = kPortIndexOutput; 27782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 27792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // configure compression level 2780d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def)); 27812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (err != OK) { 27822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err); 27832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return err; 27842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 27852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nCompressionLevel = compressionLevel; 2786d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def)); 27872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (err != OK) { 27882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err); 27892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return err; 27902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 27912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 27922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 27932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return setupRawAudioFormat( 27942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi encoder ? kPortIndexInput : kPortIndexOutput, 27952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi sampleRate, 27962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi numChannels); 27972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 27982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2799729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat( 28005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) { 2801729de186450f78c099637e1fce743fe531862c52Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 2802729de186450f78c099637e1fce743fe531862c52Andreas Huber InitOMXParams(&def); 2803729de186450f78c099637e1fce743fe531862c52Andreas Huber def.nPortIndex = portIndex; 2804729de186450f78c099637e1fce743fe531862c52Andreas Huber 2805d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 2806d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 2807729de186450f78c099637e1fce743fe531862c52Andreas Huber 2808729de186450f78c099637e1fce743fe531862c52Andreas Huber if (err != OK) { 2809729de186450f78c099637e1fce743fe531862c52Andreas Huber return err; 2810729de186450f78c099637e1fce743fe531862c52Andreas Huber } 2811729de186450f78c099637e1fce743fe531862c52Andreas Huber 2812729de186450f78c099637e1fce743fe531862c52Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 2813729de186450f78c099637e1fce743fe531862c52Andreas Huber 2814d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2815d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 2816729de186450f78c099637e1fce743fe531862c52Andreas Huber 2817729de186450f78c099637e1fce743fe531862c52Andreas Huber if (err != OK) { 2818729de186450f78c099637e1fce743fe531862c52Andreas Huber return err; 2819729de186450f78c099637e1fce743fe531862c52Andreas Huber } 2820729de186450f78c099637e1fce743fe531862c52Andreas Huber 2821729de186450f78c099637e1fce743fe531862c52Andreas Huber OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 2822729de186450f78c099637e1fce743fe531862c52Andreas Huber InitOMXParams(&pcmParams); 2823729de186450f78c099637e1fce743fe531862c52Andreas Huber pcmParams.nPortIndex = portIndex; 2824729de186450f78c099637e1fce743fe531862c52Andreas Huber 2825d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 2826d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2827729de186450f78c099637e1fce743fe531862c52Andreas Huber 2828729de186450f78c099637e1fce743fe531862c52Andreas Huber if (err != OK) { 2829729de186450f78c099637e1fce743fe531862c52Andreas Huber return err; 2830729de186450f78c099637e1fce743fe531862c52Andreas Huber } 2831729de186450f78c099637e1fce743fe531862c52Andreas Huber 2832729de186450f78c099637e1fce743fe531862c52Andreas Huber pcmParams.nChannels = numChannels; 28335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar switch (encoding) { 28345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar case kAudioEncodingPcm8bit: 28355b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar pcmParams.eNumData = OMX_NumericalDataUnsigned; 28365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar pcmParams.nBitPerSample = 8; 28375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar break; 28385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar case kAudioEncodingPcmFloat: 28395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar pcmParams.eNumData = OMX_NumericalDataFloat; 28405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar pcmParams.nBitPerSample = 32; 28415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar break; 28425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar case kAudioEncodingPcm16bit: 28435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar pcmParams.eNumData = OMX_NumericalDataSigned; 28445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar pcmParams.nBitPerSample = 16; 28455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar break; 28465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar default: 28475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar return BAD_VALUE; 28485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 2849729de186450f78c099637e1fce743fe531862c52Andreas Huber pcmParams.bInterleaved = OMX_TRUE; 2850729de186450f78c099637e1fce743fe531862c52Andreas Huber pcmParams.nSamplingRate = sampleRate; 2851729de186450f78c099637e1fce743fe531862c52Andreas Huber pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 2852729de186450f78c099637e1fce743fe531862c52Andreas Huber 2853c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) { 2854c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber return OMX_ErrorNone; 2855729de186450f78c099637e1fce743fe531862c52Andreas Huber } 2856729de186450f78c099637e1fce743fe531862c52Andreas Huber 2857d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2858d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 28595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // if we could not set up raw format to non-16-bit, try with 16-bit 28605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // NOTE: we will also verify this via readback, in case codec ignores these fields 28615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (err != OK && encoding != kAudioEncodingPcm16bit) { 28625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar pcmParams.eNumData = OMX_NumericalDataSigned; 28635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar pcmParams.nBitPerSample = 16; 2864d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 2865d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 28665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 28675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar return err; 2868729de186450f78c099637e1fce743fe531862c52Andreas Huber} 2869729de186450f78c099637e1fce743fe531862c52Andreas Huber 28705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback( 287197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) { 28725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad native_handle_t* sidebandHandle; 28735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 2874d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->configureVideoTunnelMode( 2875d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle); 28765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (err != OK) { 28775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad ALOGE("configureVideoTunnelMode failed! (err %d).", err); 28785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad return err; 28795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } 28805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 28815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle); 28825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad if (err != OK) { 28835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", 28845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad sidebandHandle, err); 28855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad return err; 28865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad } 28875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 28885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad return OK; 28895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad} 28905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad 2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType( 2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 portIndex, 2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_CODINGTYPE compressionFormat, 28940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar OMX_COLOR_FORMATTYPE colorFormat, 28950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar bool usingNativeBuffers) { 2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PARAM_PORTFORMATTYPE format; 2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&format); 2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nPortIndex = portIndex; 2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nIndex = 0; 2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool found = false; 2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 29026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nIndex = index; 2904d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 2905d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoPortFormat, 2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &format, sizeof(format)); 2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2912229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar // substitute back flexible color format to codec supported format 2913229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar OMX_U32 flexibleEquivalent; 29140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar if (compressionFormat == OMX_VIDEO_CodingUnused 29151ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim && IsFlexibleColorFormat( 2916d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent) 29170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar && colorFormat == flexibleEquivalent) { 2918229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar ALOGI("[%s] using color format %#x in place of %#x", 2919229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar mComponentName.c_str(), format.eColorFormat, colorFormat); 2920229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar colorFormat = format.eColorFormat; 2921229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar } 2922229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar 2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // The following assertion is violated by TI's video decoder. 2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK_EQ(format.nIndex, index); 2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) { 2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexInput 2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && colorFormat == format.eColorFormat) { 2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // eCompressionFormat does not seem right. 2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber found = true; 2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexOutput 2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && compressionFormat == format.eCompressionFormat) { 2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // eColorFormat does not seem right. 2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber found = true; 2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (format.eCompressionFormat == compressionFormat 2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && format.eColorFormat == colorFormat) { 2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber found = true; 2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 29476e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar if (index == kMaxIndicesToCheck) { 29486e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)", 29496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar mComponentName.c_str(), index, 29506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar asString(format.eCompressionFormat), format.eCompressionFormat, 29516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar asString(format.eColorFormat), format.eColorFormat); 29526e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar } 2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!found) { 2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return UNKNOWN_ERROR; 2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2959d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->setParameter( 2960d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoPortFormat, &format, sizeof(format)); 2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 29650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order 29660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible 29670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use 29680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard 29690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV. 29700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// 29710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order: 29720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior) 29730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support) 29740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support) 29750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats 29760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// 29770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable 29780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format. 29790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) { 29800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat; 2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&format); 2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nPortIndex = kPortIndexOutput; 2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 29840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar InitOMXParams(&legacyFormat); 29850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar // this field will change when we find a suitable legacy format 29860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar legacyFormat.eColorFormat = OMX_COLOR_FormatUnused; 2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 29880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar for (OMX_U32 index = 0; ; ++index) { 29890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar format.nIndex = index; 2990d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 2991d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoPortFormat, &format, sizeof(format)); 29920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar if (err != OK) { 29930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar // no more formats, pick legacy format if found 29940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) { 29950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar memcpy(&format, &legacyFormat, sizeof(format)); 29960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar break; 29970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar } 29980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar return err; 29990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar } 30000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) { 30010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar return OMX_ErrorBadParameter; 30020d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar } 30030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar if (!getLegacyFlexibleFormat) { 30040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar break; 30050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar } 30060d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar // standard formats that were exposed to users before 30070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar 30080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar 30090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 30100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar 30110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 30120d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar break; 30130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar } 30140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar // find best legacy non-standard format 30150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar OMX_U32 flexibleEquivalent; 30160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused 30171ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim && IsFlexibleColorFormat( 3018d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang mOMXNode, format.eColorFormat, false /* usingNativeBuffers */, 30190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar &flexibleEquivalent) 30200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) { 30210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar memcpy(&legacyFormat, &format, sizeof(format)); 30220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar } 30230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar } 3024d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang return mOMXNode->setParameter( 3025d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoPortFormat, &format, sizeof(format)); 3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3028e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry { 3029e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const char *mMime; 3030e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber OMX_VIDEO_CODINGTYPE mVideoCodingType; 3031e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = { 3032e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC }, 30332472b1c0d63454e5d90a982bd6c555de6c3127bdRachad { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC }, 3034e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 }, 3035e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 }, 3036e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 }, 303794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 }, 303894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 }, 3039a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision }, 3040e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}; 3041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 30425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime( 30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber const char *mime, OMX_VIDEO_CODINGTYPE *codingType) { 3044e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber for (size_t i = 0; 3045e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 3046e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ++i) { 3047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) { 3048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber *codingType = kVideoCodingMapEntry[i].mVideoCodingType; 3049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return OK; 3050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3053e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber *codingType = OMX_VIDEO_CodingUnused; 3054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 3055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return ERROR_UNSUPPORTED; 3056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} 3057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 3058e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding( 3059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber OMX_VIDEO_CODINGTYPE codingType, AString *mime) { 3060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber for (size_t i = 0; 3061e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 3062e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ++i) { 3063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) { 3064e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber *mime = kVideoCodingMapEntry[i].mMime; 3065e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return OK; 3066e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 3067e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 3068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 3069e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mime->clear(); 3070e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 3071e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return ERROR_UNSUPPORTED; 30725778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 30735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3074a6bfb5060824f01041f956c733fec141504c280bHangyu Kuangstatus_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) { 3075a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang OMX_PARAM_PORTDEFINITIONTYPE def; 3076a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang InitOMXParams(&def); 3077a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang def.nPortIndex = portIndex; 3078a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang status_t err; 3079a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(), 3080a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang portIndex == kPortIndexInput ? "input" : "output", bufferNum); 3081d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 3082d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 3083a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang if (err != OK) { 3084a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang return err; 3085a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang } 3086a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang def.nBufferCountActual = bufferNum; 3087d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 3088d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 3089a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang if (err != OK) { 3090a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang // Component could reject this request. 3091a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(), 3092a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang portIndex == kPortIndexInput ? "input" : "output", bufferNum); 3093a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang } 3094a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang return OK; 3095a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang} 3096a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang 30975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder( 30988338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar const char *mime, const sp<AMessage> &msg, bool haveNativeWindow, 3099b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar bool usingSwRenderer, sp<AMessage> &outputFormat) { 310089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar int32_t width, height; 310189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar if (!msg->findInt32("width", &width) 310289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar || !msg->findInt32("height", &height)) { 310389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar return INVALID_OPERATION; 310489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar } 310589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar 31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_CODINGTYPE compressionFormat; 31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 31115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 31125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3113f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang if (compressionFormat == OMX_VIDEO_CodingVP9) { 3114f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 3115f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang InitOMXParams(¶ms); 3116f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang params.nPortIndex = kPortIndexInput; 3117f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang // Check if VP9 decoder advertises supported profiles. 3118f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang params.nProfileIndex = 0; 3119d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 3120f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang OMX_IndexParamVideoProfileLevelQuerySupported, 3121d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang ¶ms, sizeof(params)); 3122f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang mIsLegacyVP9Decoder = err != OK; 3123f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang } 3124f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang 31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setVideoPortFormatType( 3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 313289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar int32_t tmp; 313389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar if (msg->findInt32("color-format", &tmp)) { 313489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar OMX_COLOR_FORMATTYPE colorFormat = 313589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar static_cast<OMX_COLOR_FORMATTYPE>(tmp); 313689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar err = setVideoPortFormatType( 31370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow); 313889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar if (err != OK) { 313989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar ALOGW("[%s] does not support color format %d", 314089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar mComponentName.c_str(), colorFormat); 31410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */); 314289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar } 314389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar } else { 31440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */); 314589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar } 3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3151a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang // Set the component input buffer number to be |tmp|. If succeed, 3152a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang // component will set input port buffer number to be |tmp|. If fail, 3153a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang // component will keep the same buffer number as before. 3154a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang if (msg->findInt32("android._num-input-buffers", &tmp)) { 3155a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang err = setPortBufferNum(kPortIndexInput, tmp); 3156a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang if (err != OK) 3157a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang return err; 3158a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang } 3159a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang 3160a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang // Set the component output buffer number to be |tmp|. If succeed, 3161a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang // component will set output port buffer number to be |tmp|. If fail, 3162a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang // component will keep the same buffer number as before. 3163a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang if (msg->findInt32("android._num-output-buffers", &tmp)) { 3164a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang err = setPortBufferNum(kPortIndexOutput, tmp); 3165a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang if (err != OK) 3166a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang return err; 3167a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang } 3168a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang 316978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad int32_t frameRateInt; 317078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad float frameRateFloat; 317178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad if (!msg->findFloat("frame-rate", &frameRateFloat)) { 317278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad if (!msg->findInt32("frame-rate", &frameRateInt)) { 317378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad frameRateInt = -1; 317478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad } 317578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad frameRateFloat = (float)frameRateInt; 317678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad } 317778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad 3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = setVideoFormatOnPort( 317978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad kPortIndexInput, width, height, compressionFormat, frameRateFloat); 3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = setVideoFormatOnPort( 3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused); 3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3192b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = setColorAspectsForVideoDecoder( 3193b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat); 3194b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == ERROR_UNSUPPORTED) { // support is optional 31958338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar err = OK; 31968338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 3197db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 3198db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang if (err != OK) { 3199db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang return err; 3200db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang } 3201db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 32025e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat); 3203db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang if (err == ERROR_UNSUPPORTED) { // support is optional 3204db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang err = OK; 3205db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang } 3206b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3207b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 3208b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3209b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() { 3210d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getExtensionIndex( 3211d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex); 3212b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err != OK) { 3213b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0; 3214b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3215b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3216b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 32178338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3218b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams ¶ms, bool verify) { 3219b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = ERROR_UNSUPPORTED; 3220b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mDescribeColorAspectsIndex) { 3221d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setConfig(mDescribeColorAspectsIndex, ¶ms, sizeof(params)); 3222b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3223b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 3224b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str(), 3225b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mRange, asString(params.sAspects.mRange), 3226b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 3227b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 3228b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 3229b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err, asString(err)); 3230b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3231b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (verify && err == OK) { 3232b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = getCodecColorAspects(params); 3233b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3234b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3235b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex, 3236db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang "[%s] setting color aspects failed even though codec advertises support", 3237b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str()); 32388338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar return err; 32398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar} 32408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3241b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder( 3242b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t width, int32_t height, bool usingNativeWindow, 3243b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) { 32448338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar DescribeColorAspectsParams params; 32458338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar InitOMXParams(¶ms); 3246b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPortIndex = kPortIndexOutput; 32478338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3248b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar getColorAspectsFromFormat(configFormat, params.sAspects); 3249b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (usingNativeWindow) { 3250b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height); 3251b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // The default aspects will be set back to the output format during the 3252b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // getFormat phase of configure(). Set non-Unspecified values back into the 3253b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // format, in case component does not support this enumeration. 3254b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setColorAspectsIntoFormat(params.sAspects, outputFormat); 32558338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 32568338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3257b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (void)initDescribeColorAspectsIndex(); 32588338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3259b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // communicate color aspects to codec 3260b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return setCodecColorAspects(params); 3261b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 3262b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3263b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams ¶ms) { 3264b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = ERROR_UNSUPPORTED; 3265b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mDescribeColorAspectsIndex) { 3266d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getConfig(mDescribeColorAspectsIndex, ¶ms, sizeof(params)); 32678338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 3268b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 3269b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str(), 3270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mRange, asString(params.sAspects.mRange), 3271b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 3272b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 3273b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 3274b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err, asString(err)); 3275b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (params.bRequestingDataSpace) { 3276b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("for dataspace %#x", params.nDataSpace); 3277b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3278b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex 3279b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar && !params.bRequestingDataSpace && !params.bDataSpaceChanged) { 3280b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW("[%s] getting color aspects failed even though codec advertises support", 3281b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str()); 3282b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3283b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3284b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 32858338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3286b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) { 3287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar DescribeColorAspectsParams params; 3288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar InitOMXParams(¶ms); 3289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPortIndex = kPortIndexInput; 3290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = getCodecColorAspects(params); 3291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 3292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // we only set encoder input aspects if codec supports them 3293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setColorAspectsIntoFormat(params.sAspects, format, true /* force */); 32948338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 3295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 3297b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3298b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace( 3299b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar DescribeColorAspectsParams ¶ms, android_dataspace *dataSpace /* nonnull */, 3300b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar bool tryCodec) { 3301b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = OK; 3302b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (tryCodec) { 3303b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // request dataspace guidance from codec. 3304b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.bRequestingDataSpace = OMX_TRUE; 3305b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = getCodecColorAspects(params); 3306b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.bRequestingDataSpace = OMX_FALSE; 3307b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) { 3308b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar *dataSpace = (android_dataspace)params.nDataSpace; 3309b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3310b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } else if (err == ERROR_UNSUPPORTED) { 3311b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // ignore not-implemented error for dataspace requests 3312b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = OK; 3313b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 33148338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 3315b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3316b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // this returns legacy versions if available 3317b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */); 3318b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) " 3319b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar "and dataspace %#x", 3320b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str(), 3321b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mRange, asString(params.sAspects.mRange), 3322b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 3323b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 3324b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 3325b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar *dataSpace); 3326b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 3328b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3329b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3330b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder( 3331b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, 3332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar android_dataspace *dataSpace) { 3333b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar DescribeColorAspectsParams params; 3334b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar InitOMXParams(¶ms); 3335b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPortIndex = kPortIndexOutput; 3336b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3337b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // reset default format and get resulting format 3338b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar getColorAspectsFromFormat(configFormat, params.sAspects); 3339b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (dataSpace != NULL) { 3340b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height); 33418338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 3342b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = setCodecColorAspects(params, true /* readBack */); 33438338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // we always set specified aspects for decoders 3345b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setColorAspectsIntoFormat(params.sAspects, outputFormat); 3346b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3347b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (dataSpace != NULL) { 3348b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */); 3349b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 3350b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = res; 3351b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 33528338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 33538338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3354b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 33558338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar} 33568338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3357b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode 3358b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder( 3359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) { 3360b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // copy config to output format as this is not exposed via getFormat 3361b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar copyColorConfig(configFormat, outputFormat); 3362b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3363b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar DescribeColorAspectsParams params; 3364b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar InitOMXParams(¶ms); 3365b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPortIndex = kPortIndexInput; 3366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar getColorAspectsFromFormat(configFormat, params.sAspects); 3367b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3368b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (void)initDescribeColorAspectsIndex(); 3369b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t usingRecorder; 3371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) { 3372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar android_dataspace dataSpace = HAL_DATASPACE_BT709; 3373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t width, height; 3374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (configFormat->findInt32("width", &width) 3375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar && configFormat->findInt32("height", &height)) { 3376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height); 3377b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = getDataSpace( 3378b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */); 3379b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err != OK) { 3380b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3381b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3382b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setColorAspectsIntoFormat(params.sAspects, outputFormat); 3383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar inputFormat->setInt32("android._dataspace", (int32_t)dataSpace); 33858338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 33868338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // communicate color aspects to codec, but do not allow change of the platform aspects 3388b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ColorAspects origAspects = params.sAspects; 3389b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar for (int triesLeft = 2; --triesLeft >= 0; ) { 3390b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = setCodecColorAspects(params, true /* readBack */); 3391b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err != OK 3392b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem( 3393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects, origAspects, true /* usePlatformAspects */)) { 3394b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.", 3397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str()); 3398b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return OK; 3400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 3401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 34025e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::setHDRStaticInfoForVideoCodec( 34035e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) { 34045e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 34055e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang 34065e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang DescribeHDRStaticInfoParams params; 34075e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang InitOMXParams(¶ms); 34085e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang params.nPortIndex = portIndex; 34095e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang 34105e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang HDRStaticInfo *info = ¶ms.sInfo; 34115e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang if (getHDRStaticInfoFromFormat(configFormat, info)) { 34125e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang setHDRStaticInfoIntoFormat(params.sInfo, outputFormat); 34135e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang } 34145e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang 34155e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang (void)initDescribeHDRStaticInfoIndex(); 34165e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang 34175e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang // communicate HDR static Info to codec 34185e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang return setHDRStaticInfo(params); 34195e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang} 34205e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang 3421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode 3422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace( 3423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar android_dataspace *dataSpace /* nonnull */) { 34248338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar DescribeColorAspectsParams params; 34258338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar InitOMXParams(¶ms); 3426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPortIndex = kPortIndexInput; 34278338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar ColorAspects &aspects = params.sAspects; 34288338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // reset default format and store resulting format into both input and output formats 3430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar getColorAspectsFromFormat(mConfigFormat, aspects); 3431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t width, height; 3432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) { 3433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setDefaultCodecColorAspectsIfNeeded(aspects, width, height); 34348338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 3435b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setColorAspectsIntoFormat(aspects, mInputFormat); 3436b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar setColorAspectsIntoFormat(aspects, mOutputFormat); 34378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // communicate color aspects to codec, but do not allow any change 3439b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ColorAspects origAspects = aspects; 3440b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = OK; 3441b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) { 3442b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = setCodecColorAspects(params, true /* readBack */); 3443b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) { 3444b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar break; 3445b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 3446b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.", 3447b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str()); 34488338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 34498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 3450b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar *dataSpace = HAL_DATASPACE_BT709; 3451b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects = origAspects; // restore desired color aspects 3452b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t res = getDataSpace( 3453b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */); 3454b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 3455b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = res; 34568338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 3457b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace); 3458b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mInputFormat->setBuffer( 3459b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects))); 3460b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3461b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // update input format with codec supported color aspects (basically set unsupported 3462b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // aspects to Unspecified) 3463b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 3464b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (void)getInputColorAspectsForVideoEncoder(mInputFormat); 34658338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 3466b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3467b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("set default color aspects, updated input format to %s, output format to %s", 3468b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str()); 3469b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 3470b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 34735e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) { 34745e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 3475db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang DescribeHDRStaticInfoParams params; 3476db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang InitOMXParams(¶ms); 34775e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang params.nPortIndex = portIndex; 3478db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 3479db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang status_t err = getHDRStaticInfo(params); 3480db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang if (err == OK) { 3481db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang // we only set decodec output HDRStaticInfo if codec supports them 3482db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang setHDRStaticInfoIntoFormat(params.sInfo, format); 3483db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang } 3484db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang return err; 3485db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang} 3486db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 3487db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::initDescribeHDRStaticInfoIndex() { 3488d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getExtensionIndex( 3489d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex); 3490db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang if (err != OK) { 3491db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0; 3492db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang } 3493db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang return err; 3494db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang} 3495db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 3496db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams ¶ms) { 3497db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang status_t err = ERROR_UNSUPPORTED; 3498db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang if (mDescribeHDRStaticInfoIndex) { 3499d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, ¶ms, sizeof(params)); 3500db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang } 3501db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 3502db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang const HDRStaticInfo *info = ¶ms.sInfo; 3503db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang ALOGV("[%s] setting HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, " 3504db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)", 3505db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang mComponentName.c_str(), 3506db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y, 3507db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y, 3508db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance, 3509db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel); 3510db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 3511db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex, 3512db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang "[%s] setting HDRStaticInfo failed even though codec advertises support", 3513db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang mComponentName.c_str()); 3514db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang return err; 3515db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang} 3516db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 3517db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams ¶ms) { 3518db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang status_t err = ERROR_UNSUPPORTED; 3519db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang if (mDescribeHDRStaticInfoIndex) { 3520d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, ¶ms, sizeof(params)); 3521db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang } 3522db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 3523db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex, 3524db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang "[%s] getting HDRStaticInfo failed even though codec advertises support", 3525db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang mComponentName.c_str()); 3526db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang return err; 3527db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang} 3528db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang 35298338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder( 3530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar const char *mime, const sp<AMessage> &msg, 3531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) { 35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t tmp; 35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("color-format", &tmp)) { 35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35375778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_COLOR_FORMATTYPE colorFormat = 35385778822d86b0337407514b9372562b86edfa91cdAndreas Huber static_cast<OMX_COLOR_FORMATTYPE>(tmp); 35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = setVideoPortFormatType( 35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat); 35425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35435778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 35445778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGE("[%s] does not support color format %d", 35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber mComponentName.c_str(), colorFormat); 35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* Input port configuration */ 35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35525778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&def); 35545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35555778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 35565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35575778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.nPortIndex = kPortIndexInput; 35585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3559d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 3560d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35625778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 35635778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35665778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t width, height, bitrate; 35675778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("width", &width) 35685778822d86b0337407514b9372562b86edfa91cdAndreas Huber || !msg->findInt32("height", &height) 35695778822d86b0337407514b9372562b86edfa91cdAndreas Huber || !msg->findInt32("bitrate", &bitrate)) { 35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 35715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 35725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35735778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->nFrameWidth = width; 35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->nFrameHeight = height; 35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35765778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t stride; 35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("stride", &stride)) { 35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber stride = width; 35795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 35805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35815778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->nStride = stride; 35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t sliceHeight; 35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("slice-height", &sliceHeight)) { 35855778822d86b0337407514b9372562b86edfa91cdAndreas Huber sliceHeight = height; 35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 35875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35885778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->nSliceHeight = sliceHeight; 35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35905778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2; 35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber float frameRate; 35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findFloat("frame-rate", &frameRate)) { 35945778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t tmp; 35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("frame-rate", &tmp)) { 35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 35975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 35985778822d86b0337407514b9372562b86edfa91cdAndreas Huber frameRate = (float)tmp; 35992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs = (int64_t) (1000000.0f / frameRate); 36005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36025778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 3604a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar // this is redundant as it was already set up in setVideoPortFormatType 3605a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar // FIXME for now skip this only for flexible YUV formats 3606a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar if (colorFormat != OMX_COLOR_FormatYUV420Flexible) { 3607a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar video_def->eColorFormat = colorFormat; 3608a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar } 36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3610d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 3611d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGE("[%s] failed to set input port definition parameters.", 36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber mComponentName.c_str()); 36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* Output port configuration */ 36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_CODINGTYPE compressionFormat; 36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 36285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36295778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setVideoPortFormatType( 36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); 36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGE("[%s] does not support compression format %d", 36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber mComponentName.c_str(), compressionFormat); 36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber def.nPortIndex = kPortIndexOutput; 36405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3641d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 3642d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 36435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36445778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 36455778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 36465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 36475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36485778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->nFrameWidth = width; 36495778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->nFrameHeight = height; 36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->xFramerate = 0; 36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->nBitrate = bitrate; 36525778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->eCompressionFormat = compressionFormat; 36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber video_def->eColorFormat = OMX_COLOR_FormatUnused; 36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3655d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 3656d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 36575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 36595778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGE("[%s] failed to set output port definition parameters.", 36605778822d86b0337407514b9372562b86edfa91cdAndreas Huber mComponentName.c_str()); 36615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 36635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3665870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang int32_t intraRefreshPeriod = 0; 3666870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod) 3667870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang && intraRefreshPeriod >= 0) { 3668870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true); 3669870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (err != OK) { 3670870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional", 3671870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang mComponentName.c_str()); 3672870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang err = OK; 3673870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 3674870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 3675870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 36765778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (compressionFormat) { 36775778822d86b0337407514b9372562b86edfa91cdAndreas Huber case OMX_VIDEO_CodingMPEG4: 36785778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setupMPEG4EncoderParameters(msg); 36795778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 36805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber case OMX_VIDEO_CodingH263: 36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setupH263EncoderParameters(msg); 36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber case OMX_VIDEO_CodingAVC: 36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = setupAVCEncoderParameters(msg); 36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3689c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad case OMX_VIDEO_CodingHEVC: 3690c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad err = setupHEVCEncoderParameters(msg); 3691c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad break; 3692c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 369389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber case OMX_VIDEO_CodingVP8: 369489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber case OMX_VIDEO_CodingVP9: 36959bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar err = setupVPXEncoderParameters(msg, outputFormat); 369689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber break; 369789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber 36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 37020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (err != OK) { 37030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return err; 37040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 37050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 37068338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar // Set up color aspects on input, but propagate them to the output format, as they will 37078338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar // not be read back from encoder. 3708b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat); 3709b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == ERROR_UNSUPPORTED) { 37108338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str()); 37118338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar err = OK; 37128338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar } 37138338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar 37145e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang if (err != OK) { 37155e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang return err; 37165e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang } 37175e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang 37185e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat); 37195e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang if (err == ERROR_UNSUPPORTED) { // support is optional 37205e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str()); 37215e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang err = OK; 37225e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang } 37235e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang 37240f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (err != OK) { 37250f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return err; 37260f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 37270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 37280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar switch (compressionFormat) { 37290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar case OMX_VIDEO_CodingAVC: 37300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar case OMX_VIDEO_CodingHEVC: 37310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat); 37320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (err != OK) { 37330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar err = OK; // ignore failure 37340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 37350f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar break; 37360f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 37370f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar case OMX_VIDEO_CodingVP8: 37380f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar case OMX_VIDEO_CodingVP9: 37390f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar // TODO: do we need to support android.generic layering? webrtc layering is 37400f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar // already set up in setupVPXEncoderParameters. 37410f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar break; 37420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 37430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar default: 37440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar break; 37450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 37460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 3747d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu if (err == OK) { 3748d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu ALOGI("setupVideoEncoder succeeded"); 3749d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu } 37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 37515778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 37535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 37540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { 37550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; 37560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong InitOMXParams(¶ms); 37570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong params.nPortIndex = kPortIndexOutput; 37580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong 37590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode); 37600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong 37610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || 37620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 37630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong int32_t mbs; 37640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { 37650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong return INVALID_OPERATION; 37660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong } 37670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong params.nCirMBs = mbs; 37680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong } 37690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong 37700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || 37710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 37720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong int32_t mbs; 37730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { 37740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong return INVALID_OPERATION; 37750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong } 37760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong params.nAirMBs = mbs; 37770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong 37780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong int32_t ref; 37790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { 37800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong return INVALID_OPERATION; 37810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong } 37820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong params.nAirRef = ref; 37830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong } 37840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong 3785d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->setParameter( 3786d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoIntraRefresh, ¶ms, sizeof(params)); 37870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong return err; 37880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong} 37890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong 3790f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnarstatic OMX_U32 setPFramesSpacing( 379163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) { 3792f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // BFramesSpacing is the number of B frames between I/P frames 3793f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // PFramesSpacing (the value to be returned) is the number of P frames between I frames 3794f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // 3795f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1 3796f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // ^^^ ^^^ ^^^ 3797f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // number of B frames number of P I frame 3798f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // 3799f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // = (PFramesSpacing + 1) * (BFramesSpacing + 1) 3800f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // 3801f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // E.g. 3802f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // I P I : I-interval: 8, nPFrames 1, nBFrames 3 3803f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // BBB BBB 3804f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar 3805f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar if (iFramesInterval < 0) { // just 1 key frame 3806f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1 3807f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar } else if (iFramesInterval == 0) { // just key frames 38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3810f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar 3811f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar // round down as key-frame-interval is an upper limit 3812f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval); 3813f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1); 3814f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar return ret > 0 ? ret - 1 : 0; 38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 38165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 381796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) { 381896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber int32_t tmp; 381996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber if (!msg->findInt32("bitrate-mode", &tmp)) { 382096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber return OMX_Video_ControlRateVariable; 382196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber } 382296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber 382396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp); 382496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber} 382596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber 38265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) { 382763a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar int32_t bitrate; 382863a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar float iFrameInterval; 38295778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("bitrate", &bitrate) 383063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 383496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 383596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber 38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber float frameRate; 38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findFloat("frame-rate", &frameRate)) { 38385778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t tmp; 38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("frame-rate", &tmp)) { 38405778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 38415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38425778822d86b0337407514b9372562b86edfa91cdAndreas Huber frameRate = (float)tmp; 38435778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38455778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 38465778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&mpeg4type); 38475778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.nPortIndex = kPortIndexOutput; 38485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3849d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 3850d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 38515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38525778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 38535778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.nSliceHeaderSpacing = 0; 38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.bSVH = OMX_FALSE; 38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.bGov = OMX_FALSE; 38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.nAllowedPictureTypes = 38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3863f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar mpeg4type.nBFrames = 0; 3864f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames); 38655778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mpeg4type.nPFrames == 0) { 38665778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 38675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.nIDCVLCThreshold = 0; 38695778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.bACPred = OMX_TRUE; 38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.nMaxPacketSize = 256; 38715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.nTimeIncRes = 1000; 38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.nHeaderExtension = 0; 38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.bReversibleVLC = OMX_FALSE; 38745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38755778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t profile; 38765778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (msg->findInt32("profile", &profile)) { 38775778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t level; 38785778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("level", &level)) { 38795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38825778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = verifySupportForProfileAndLevel(profile, level); 38835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38845778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 38855778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 38865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38885778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile); 38895778822d86b0337407514b9372562b86edfa91cdAndreas Huber mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level); 38905778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3892d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 3893d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 38965778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 38975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 38985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 389996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber err = configureBitrate(bitrate, bitrateMode); 39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39015778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 39025778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 39035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber return setupErrorCorrectionParameters(); 39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 39075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { 390963a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar int32_t bitrate; 391063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar float iFrameInterval; 39115778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("bitrate", &bitrate) 391263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 39135778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 39145778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 391696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 391796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber 39185778822d86b0337407514b9372562b86edfa91cdAndreas Huber float frameRate; 39195778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findFloat("frame-rate", &frameRate)) { 39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t tmp; 39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("frame-rate", &tmp)) { 39225778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 39235778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber frameRate = (float)tmp; 39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39275778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PARAM_H263TYPE h263type; 39285778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&h263type); 39295778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.nPortIndex = kPortIndexOutput; 39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3931d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 3932d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 39335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 39355778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 39365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39385778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.nAllowedPictureTypes = 39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3941f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar h263type.nBFrames = 0; 3942f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames); 39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (h263type.nPFrames == 0) { 39445778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 39455778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39475778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t profile; 39485778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (msg->findInt32("profile", &profile)) { 39495778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t level; 39505778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("level", &level)) { 39515778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 39525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39545778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = verifySupportForProfileAndLevel(profile, level); 39555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39565778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 39575778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 39585778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile); 39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level); 39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.bPLUSPTYPEAllowed = OMX_FALSE; 39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.bForceRoundingTypeToZero = OMX_FALSE; 39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.nPictureHeaderRepetition = 0; 39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber h263type.nGOBHeaderInterval = 0; 39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3969d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 3970d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 39745778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 397696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber err = configureBitrate(bitrate, bitrateMode); 39775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39785778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 39795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 39805778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 39815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber return setupErrorCorrectionParameters(); 39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3985a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static 3986a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor( 3987a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar int width, int height, int rate, int bitrate, 3988a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar OMX_VIDEO_AVCPROFILETYPE profile) { 3989a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar // convert bitrate to main/baseline profile kbps equivalent 3990a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar switch (profile) { 3991a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar case OMX_VIDEO_AVCProfileHigh10: 3992a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar bitrate = divUp(bitrate, 3000); break; 3993a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar case OMX_VIDEO_AVCProfileHigh: 3994a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar bitrate = divUp(bitrate, 1250); break; 3995a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar default: 3996a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar bitrate = divUp(bitrate, 1000); break; 3997a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar } 3998a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar 3999a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar // convert size and rate to MBs 4000a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar width = divUp(width, 16); 4001a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar height = divUp(height, 16); 4002a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar int mbs = width * height; 4003a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar rate *= mbs; 4004a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar int maxDimension = max(width, height); 4005a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar 4006a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar static const int limits[][5] = { 4007a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar /* MBps MB dim bitrate level */ 4008a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 1485, 99, 28, 64, OMX_VIDEO_AVCLevel1 }, 4009a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 1485, 99, 28, 128, OMX_VIDEO_AVCLevel1b }, 4010a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 3000, 396, 56, 192, OMX_VIDEO_AVCLevel11 }, 4011a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 6000, 396, 56, 384, OMX_VIDEO_AVCLevel12 }, 4012a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 11880, 396, 56, 768, OMX_VIDEO_AVCLevel13 }, 4013a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 11880, 396, 56, 2000, OMX_VIDEO_AVCLevel2 }, 4014a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 19800, 792, 79, 4000, OMX_VIDEO_AVCLevel21 }, 4015a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 20250, 1620, 113, 4000, OMX_VIDEO_AVCLevel22 }, 4016a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 40500, 1620, 113, 10000, OMX_VIDEO_AVCLevel3 }, 4017a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 108000, 3600, 169, 14000, OMX_VIDEO_AVCLevel31 }, 4018a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 216000, 5120, 202, 20000, OMX_VIDEO_AVCLevel32 }, 4019a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 245760, 8192, 256, 20000, OMX_VIDEO_AVCLevel4 }, 4020a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 245760, 8192, 256, 50000, OMX_VIDEO_AVCLevel41 }, 4021a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 522240, 8704, 263, 50000, OMX_VIDEO_AVCLevel42 }, 4022a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5 }, 4023a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 }, 4024a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 }, 4025a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar }; 4026a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar 4027a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar for (size_t i = 0; i < ARRAY_SIZE(limits); i++) { 4028a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar const int (&limit)[5] = limits[i]; 4029a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2] 4030a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar && bitrate <= limit[3]) { 4031a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar return limit[4]; 4032a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar } 4033a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar } 4034a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar return 0; 4035a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar} 4036a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar 40375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { 403863a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar int32_t bitrate; 403963a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar float iFrameInterval; 40405778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("bitrate", &bitrate) 404163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 40425778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 404596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 404696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber 40475778822d86b0337407514b9372562b86edfa91cdAndreas Huber float frameRate; 40485778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findFloat("frame-rate", &frameRate)) { 40495778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t tmp; 40505778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("frame-rate", &tmp)) { 40515778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 40525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 40535778822d86b0337407514b9372562b86edfa91cdAndreas Huber frameRate = (float)tmp; 40545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 40555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong status_t err = OK; 40570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong int32_t intraRefreshMode = 0; 40580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { 40590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); 40600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong if (err != OK) { 40610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", 40620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong err, intraRefreshMode); 40630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong return err; 40640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong } 40650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong } 40660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong 40675778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PARAM_AVCTYPE h264type; 40685778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&h264type); 40695778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nPortIndex = kPortIndexOutput; 40705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4071d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4072d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 40735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40745778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 40755778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 40765778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 40775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40785778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nAllowedPictureTypes = 40795778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 40805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40815778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t profile; 40825778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (msg->findInt32("profile", &profile)) { 40835778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t level; 40845778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("level", &level)) { 40855778822d86b0337407514b9372562b86edfa91cdAndreas Huber return INVALID_OPERATION; 40865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 40875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40885778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = verifySupportForProfileAndLevel(profile, level); 40895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40905778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 40915778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 40925778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 40935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40945778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile); 40955778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level); 4096e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang } else { 40978eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 40984c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#if 0 /* DON'T YET DEFAULT TO HIGHEST PROFILE */ 40994c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar // Use largest supported profile for AVC recording if profile is not specified. 4100826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar for (OMX_VIDEO_AVCPROFILETYPE profile : { 4101826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) { 4102826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar if (verifySupportForProfileAndLevel(profile, 0) == OK) { 4103826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar h264type.eProfile = profile; 4104826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar break; 4105826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar } 4106826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar } 41074c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#endif 41088eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang } 41098eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang 4110e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]", 4111e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang asString(h264type.eProfile), asString(h264type.eLevel)); 4112e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang 41135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 41145778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nSliceHeaderSpacing = 0; 41155778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bUseHadamard = OMX_TRUE; 41165778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nRefFrames = 1; 41175778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nBFrames = 0; 4118f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 41195778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (h264type.nPFrames == 0) { 41205778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 41215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 41225778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nRefIdx10ActiveMinus1 = 0; 41235778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nRefIdx11ActiveMinus1 = 0; 41245778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bEntropyCodingCABAC = OMX_FALSE; 41255778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bWeightedPPrediction = OMX_FALSE; 41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bconstIpred = OMX_FALSE; 41275778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bDirect8x8Inference = OMX_FALSE; 41285778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bDirectSpatialTemporal = OMX_FALSE; 41295778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nCabacInitIdc = 0; 4130e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain || 4131e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.eProfile == OMX_VIDEO_AVCProfileHigh) { 4132e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.nSliceHeaderSpacing = 0; 4133e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.bUseHadamard = OMX_TRUE; 4134e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.nRefFrames = 2; 4135e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.nBFrames = 1; 4136f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 4137e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.nAllowedPictureTypes = 4138e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB; 4139e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.nRefIdx10ActiveMinus1 = 0; 4140e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.nRefIdx11ActiveMinus1 = 0; 4141e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.bEntropyCodingCABAC = OMX_TRUE; 4142e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.bWeightedPPrediction = OMX_TRUE; 4143e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.bconstIpred = OMX_TRUE; 4144e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.bDirect8x8Inference = OMX_TRUE; 4145e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.bDirectSpatialTemporal = OMX_TRUE; 4146e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang h264type.nCabacInitIdc = 1; 41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (h264type.nBFrames != 0) { 41505778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bEnableUEP = OMX_FALSE; 41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bEnableFMO = OMX_FALSE; 41555778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bEnableASO = OMX_FALSE; 41565778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bEnableRS = OMX_FALSE; 41575778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bFrameMBsOnly = OMX_TRUE; 41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.bMBAFF = OMX_FALSE; 41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 41605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4161d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 4162d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 41635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 41655778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 41665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 41675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4168e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering 4169e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering 4170e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar // is preferred. 4171e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar AString tsSchema; 4172e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar int32_t preferBFrames = (int32_t)false; 4173e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar if (msg->findString("ts-schema", &tsSchema) 4174e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) { 4175e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering; 4176e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar InitOMXParams(&layering); 4177e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar layering.nPortIndex = kPortIndexOutput; 4178d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (mOMXNode->getParameter( 4179d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 4180e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar &layering, sizeof(layering)) == OK 4181e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar && layering.eSupportedPatterns 4182e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar && layering.nBLayerCountMax == 0) { 4183e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar h264type.nBFrames = 0; 4184e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 4185e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB; 4186e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar ALOGI("disabling B-frames"); 4187d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 4188d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 4189e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar 4190e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar if (err != OK) { 4191e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar return err; 4192e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar } 4193e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar } 4194e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar } 4195e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar 419696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber return configureBitrate(bitrate, bitrateMode); 41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4199c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) { 420063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar int32_t bitrate; 420163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar float iFrameInterval; 4202c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad if (!msg->findInt32("bitrate", &bitrate) 420363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4204c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad return INVALID_OPERATION; 4205c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad } 4206c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4207c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4208c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4209c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad float frameRate; 4210c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad if (!msg->findFloat("frame-rate", &frameRate)) { 4211c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad int32_t tmp; 4212c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad if (!msg->findInt32("frame-rate", &tmp)) { 4213c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad return INVALID_OPERATION; 4214c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad } 4215c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad frameRate = (float)tmp; 4216c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad } 4217c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4218c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad OMX_VIDEO_PARAM_HEVCTYPE hevcType; 4219c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad InitOMXParams(&hevcType); 4220c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad hevcType.nPortIndex = kPortIndexOutput; 4221c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4222c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad status_t err = OK; 4223d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4224d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 4225c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad if (err != OK) { 4226c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad return err; 4227c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad } 4228c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4229c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad int32_t profile; 4230c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad if (msg->findInt32("profile", &profile)) { 4231c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad int32_t level; 4232c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad if (!msg->findInt32("level", &level)) { 4233c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad return INVALID_OPERATION; 4234c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad } 4235c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4236c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad err = verifySupportForProfileAndLevel(profile, level); 4237c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad if (err != OK) { 4238c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad return err; 4239c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad } 4240c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4241c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile); 4242c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level); 4243c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad } 42449aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // TODO: finer control? 4245f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1; 4246c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4247d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 4248d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 4249c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad if (err != OK) { 4250c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad return err; 4251c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad } 4252c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 4253c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad return configureBitrate(bitrate, bitrateMode); 4254c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad} 4255c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad 42569bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnarstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) { 425789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber int32_t bitrate; 425863a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar float iFrameInterval = 0; 42594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev size_t tsLayers = 0; 42604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern = 42614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev OMX_VIDEO_VPXTemporalLayerPatternNone; 42624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev static const uint32_t kVp8LayerRateAlloction 42634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] 42644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = { 42654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev {100, 100, 100}, // 1 layer 42664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev { 60, 100, 100}, // 2 layers {60%, 40%} 42674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev { 40, 60, 100}, // 3 layers {40%, 20%, 40%} 42684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev }; 426989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber if (!msg->findInt32("bitrate", &bitrate)) { 427089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber return INVALID_OPERATION; 427189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber } 427263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar msg->findAsFloat("i-frame-interval", &iFrameInterval); 427389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber 427489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 427589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber 42764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev float frameRate; 42774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev if (!msg->findFloat("frame-rate", &frameRate)) { 42784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev int32_t tmp; 42794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev if (!msg->findInt32("frame-rate", &tmp)) { 42804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev return INVALID_OPERATION; 42814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 42824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev frameRate = (float)tmp; 42834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 42844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev 42854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev AString tsSchema; 42869bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType = 42879bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar OMX_VIDEO_AndroidTemporalLayeringPatternNone; 42889bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar 42894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev if (msg->findString("ts-schema", &tsSchema)) { 4290f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar unsigned int numLayers = 0; 4291f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar unsigned int numBLayers = 0; 4292f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar int tags; 4293f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar char dummy; 4294f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1 4295f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar && numLayers > 0) { 42964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 42979bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC; 4298f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar tsLayers = numLayers; 4299f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c", 4300f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar &numLayers, &dummy, &numBLayers, &dummy)) 4301f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar && (tags == 1 || (tags == 3 && dummy == '+')) 4302f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) { 43034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 4304f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar // VPX does not have a concept of B-frames, so just count all layers 43059bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid; 4306f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar tsLayers = numLayers + numBLayers; 43074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } else { 4308f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str()); 43094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 4310f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS); 43114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 43124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev 43134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 43144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev InitOMXParams(&vp8type); 43154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev vp8type.nPortIndex = kPortIndexOutput; 4316d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 4317d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 43184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev &vp8type, sizeof(vp8type)); 43194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev 43204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev if (err == OK) { 43214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev if (iFrameInterval > 0) { 4322f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1; 43234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 43244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev vp8type.eTemporalPattern = pattern; 43254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev vp8type.nTemporalLayerCount = tsLayers; 43264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev if (tsLayers > 0) { 43274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) { 43284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev vp8type.nTemporalLayerBitrateRatio[i] = 43294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev kVp8LayerRateAlloction[tsLayers - 1][i]; 43304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 43314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 43324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev if (bitrateMode == OMX_Video_ControlRateConstant) { 43334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev vp8type.nMinQuantizer = 2; 43344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev vp8type.nMaxQuantizer = 63; 43354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 43364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev 4337d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 4338d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 43394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev &vp8type, sizeof(vp8type)); 43404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev if (err != OK) { 43414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev ALOGW("Extended VP8 parameters set failed: %d", err); 43429bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) { 43439bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar // advertise even single layer WebRTC layering, as it is defined 43449bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers)); 43459bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar } else if (tsLayers > 0) { 43469bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid 43479bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers)); 43484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 43494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev } 43504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev 435189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber return configureBitrate(bitrate, bitrateMode); 435289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber} 435389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber 43545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel( 43555778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t profile, int32_t level) { 43565778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 43575778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(¶ms); 43585778822d86b0337407514b9372562b86edfa91cdAndreas Huber params.nPortIndex = kPortIndexOutput; 43595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 43606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 43616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar params.nProfileIndex = index; 4362d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 43635778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_IndexParamVideoProfileLevelQuerySupported, 4364d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang ¶ms, sizeof(params)); 43655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 43665778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 43675778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 43685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 43695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 43705778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t supportedProfile = static_cast<int32_t>(params.eProfile); 43715778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t supportedLevel = static_cast<int32_t>(params.eLevel); 43725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 43735778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (profile == supportedProfile && level <= supportedLevel) { 43745778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 43755778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 43766e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar 43776e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar if (index == kMaxIndicesToCheck) { 43786e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar ALOGW("[%s] stopping checking profiles after %u: %x/%x", 43796e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar mComponentName.c_str(), index, 43806e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar params.eProfile, params.eLevel); 43816e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar } 43825778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 43836e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar return ERROR_UNSUPPORTED; 43845778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 43855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 438696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate( 438796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) { 43885778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 43895778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&bitrateType); 43905778822d86b0337407514b9372562b86edfa91cdAndreas Huber bitrateType.nPortIndex = kPortIndexOutput; 43915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4392d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 4393d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType)); 43945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 43955778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 43965778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 43975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 43985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 439996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber bitrateType.eControlRate = bitrateMode; 44005778822d86b0337407514b9372562b86edfa91cdAndreas Huber bitrateType.nTargetBitrate = bitrate; 44015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4402d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang return mOMXNode->setParameter( 4403d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType)); 44045778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 44055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 44065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() { 44075778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 44085778822d86b0337407514b9372562b86edfa91cdAndreas Huber InitOMXParams(&errorCorrectionType); 44095778822d86b0337407514b9372562b86edfa91cdAndreas Huber errorCorrectionType.nPortIndex = kPortIndexOutput; 44105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4411d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 4412d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoErrorCorrection, 44135778822d86b0337407514b9372562b86edfa91cdAndreas Huber &errorCorrectionType, sizeof(errorCorrectionType)); 44145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 44155778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 44165778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; // Optional feature. Ignore this failure 44175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 44185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 44195778822d86b0337407514b9372562b86edfa91cdAndreas Huber errorCorrectionType.bEnableHEC = OMX_FALSE; 44205778822d86b0337407514b9372562b86edfa91cdAndreas Huber errorCorrectionType.bEnableResync = OMX_TRUE; 44215778822d86b0337407514b9372562b86edfa91cdAndreas Huber errorCorrectionType.nResynchMarkerSpacing = 256; 44225778822d86b0337407514b9372562b86edfa91cdAndreas Huber errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 44235778822d86b0337407514b9372562b86edfa91cdAndreas Huber errorCorrectionType.bEnableRVLC = OMX_FALSE; 44245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4425d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang return mOMXNode->setParameter( 4426d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoErrorCorrection, 44275778822d86b0337407514b9372562b86edfa91cdAndreas Huber &errorCorrectionType, sizeof(errorCorrectionType)); 44285778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 44295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort( 4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 portIndex, 443278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat, 443378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad float frameRate) { 4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&def); 4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nPortIndex = portIndex; 4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4440d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 4441d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 4442777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4443777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4444777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexInput) { 4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // XXX Need a (much) better heuristic to compute input buffer sizes. 4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const size_t X = 64 * 1024; 4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (def.nBufferSize < X) { 4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferSize = X; 4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4454777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (def.eDomain != OMX_PortDomainVideo) { 4455777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain); 4456777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return FAILED_TRANSACTION; 4457777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameWidth = width; 4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameHeight = height; 4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexInput) { 4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->eCompressionFormat = compressionFormat; 4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->eColorFormat = OMX_COLOR_FormatUnused; 446578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad if (frameRate >= 0) { 446678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 446778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad } 4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4470d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->setParameter( 4471d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamPortDefinition, &def, sizeof(def)); 4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4476d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const { 4477d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber size_t n = 0; 4478d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 4479d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 4480d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber const BufferInfo &info = mBuffers[portIndex].itemAt(i); 4481d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 4482d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) { 4483d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber ++n; 4484d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber } 4485d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber } 4486d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 4487d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber return n; 4488d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber} 4489d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 44907e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const { 44917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber size_t n = 0; 44927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber 44937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 44947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i); 44957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber 44967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 44977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber ++n; 44987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber } 44997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber } 45007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber 45017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber return n; 45027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber} 45037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber 45047e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { 45057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber if (mNativeWindow == NULL) { 45067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber return; 45077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber } 45087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber 4509e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers 45107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber && dequeueBufferFromNativeWindow() != NULL) { 4511c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar // these buffers will be submitted as regular buffers; account for this 4512054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) { 4513054219874873b41f1c815552987c10465c34ba2bLajos Molnar --mMetadataBuffersToSubmit; 4514c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar } 45157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber } 45167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber} 45177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber 4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs( 4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 portIndex) { 4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mStatus != BufferInfo::OWNED_BY_US 4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4525609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGV("[%s] Buffer %u on port %u still has status %d", 4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mComponentName.c_str(), 4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mBufferID, portIndex, info->mStatus); 4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() { 4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return allYourBuffersAreBelongToUs(kPortIndexInput) 4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && allYourBuffersAreBelongToUs(kPortIndexOutput); 4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4540f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) { 4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDeferredQueue.push_back(msg); 4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4544f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() { 4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber List<sp<AMessage> > queue = mDeferredQueue; 4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDeferredQueue.clear(); 4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber List<sp<AMessage> >::iterator it = queue.begin(); 4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (it != queue.end()) { 4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onMessageReceived(*it++); 4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4554e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) { 4555777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output"; 455631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 455731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber InitOMXParams(&def); 4558e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar def.nPortIndex = portIndex; 455931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 4560d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def)); 4561777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4562777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4563777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 456431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 4565777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) { 4566777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex); 4567777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return BAD_VALUE; 4568777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 456931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 457031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber switch (def.eDomain) { 457131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber case OMX_PortDomainVideo: 457231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber { 457331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4574e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar switch ((int)videoDef->eCompressionFormat) { 4575e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar case OMX_VIDEO_CodingUnused: 4576e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar { 4577e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput)); 4578e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 4579e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 4580e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("stride", videoDef->nStride); 4581e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("slice-height", videoDef->nSliceHeight); 4582e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("color-format", videoDef->eColorFormat); 4583e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 45840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar if (mNativeWindow == NULL) { 458573dd808754c641fe798273d356ee38368715fa7bLajos Molnar DescribeColorFormat2Params describeParams; 45860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar InitOMXParams(&describeParams); 45870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar describeParams.eColorFormat = videoDef->eColorFormat; 45880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar describeParams.nFrameWidth = videoDef->nFrameWidth; 45890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar describeParams.nFrameHeight = videoDef->nFrameHeight; 45900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar describeParams.nStride = videoDef->nStride; 45910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar describeParams.nSliceHeight = videoDef->nSliceHeight; 45920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar describeParams.bUsingNativeBuffers = OMX_FALSE; 45930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar 4594d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (DescribeColorFormat(mOMXNode, describeParams)) { 45950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar notify->setBuffer( 45960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar "image-data", 45970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar ABuffer::CreateAsCopy( 45980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar &describeParams.sMediaImage, 45990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar sizeof(describeParams.sMediaImage))); 46005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar 460173dd808754c641fe798273d356ee38368715fa7bLajos Molnar MediaImage2 &img = describeParams.sMediaImage; 460273dd808754c641fe798273d356ee38368715fa7bLajos Molnar MediaImage2::PlaneInfo *plane = img.mPlane; 460373dd808754c641fe798273d356ee38368715fa7bLajos Molnar ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }", 460473dd808754c641fe798273d356ee38368715fa7bLajos Molnar mComponentName.c_str(), img.mWidth, img.mHeight, 460573dd808754c641fe798273d356ee38368715fa7bLajos Molnar plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc, 460673dd808754c641fe798273d356ee38368715fa7bLajos Molnar plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc, 460773dd808754c641fe798273d356ee38368715fa7bLajos Molnar plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc); 46080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar } 460903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 461003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar 4611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t width = (int32_t)videoDef->nFrameWidth; 4612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t height = (int32_t)videoDef->nFrameHeight; 4613b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 4614b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (portIndex == kPortIndexOutput) { 4615b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_CONFIG_RECTTYPE rect; 4616b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar InitOMXParams(&rect); 4617b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nPortIndex = portIndex; 4618b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 4619d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (mOMXNode->getConfig( 4620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (portIndex == kPortIndexOutput ? 4621b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_IndexConfigCommonOutputCrop : 4622b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_IndexConfigCommonInputCrop), 4623b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar &rect, sizeof(rect)) != OK) { 4624b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nLeft = 0; 4625b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nTop = 0; 4626b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nWidth = videoDef->nFrameWidth; 4627b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nHeight = videoDef->nFrameHeight; 4628b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 462991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar 4630b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (rect.nLeft < 0 || 4631b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nTop < 0 || 4632b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nLeft + rect.nWidth > videoDef->nFrameWidth || 4633b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nTop + rect.nHeight > videoDef->nFrameHeight) { 4634b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)", 4635b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nLeft, rect.nTop, 4636b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight, 4637b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar videoDef->nFrameWidth, videoDef->nFrameHeight); 4638b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return BAD_VALUE; 4639b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 464031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 4641b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar notify->setRect( 4642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar "crop", 4643b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nLeft, 4644b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nTop, 4645b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nLeft + rect.nWidth - 1, 4646b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar rect.nTop + rect.nHeight - 1); 4647b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 4648b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar width = rect.nWidth; 4649b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar height = rect.nHeight; 4650b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 4651b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; 4652b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (void)getColorAspectsAndDataSpaceForVideoDecoder( 4653b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar width, height, mConfigFormat, notify, 4654b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mUsingNativeWindow ? &dataSpace : NULL); 4655b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mUsingNativeWindow) { 4656b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar notify->setInt32("android._dataspace", dataSpace); 4657b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 46585e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify); 4659b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } else { 4660b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (void)getInputColorAspectsForVideoEncoder(notify); 46615e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang if (mConfigFormat->contains("hdr-static-info")) { 46625e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify); 46635e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang } 4664777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4666e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar break; 4667e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 46684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia 46694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia case OMX_VIDEO_CodingVP8: 46704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia case OMX_VIDEO_CodingVP9: 46714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia { 46724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 46734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia InitOMXParams(&vp8type); 46744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia vp8type.nPortIndex = kPortIndexOutput; 4675d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->getParameter( 46764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 46774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia &vp8type, 46784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia sizeof(vp8type)); 46794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia 46804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia if (err == OK) { 46819bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC 46829bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar && vp8type.nTemporalLayerCount > 0 46839bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar && vp8type.nTemporalLayerCount 46849bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) { 46859bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar // advertise as android.generic if we configured for android.generic 46869bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar AString origSchema; 46879bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar if (notify->findString("ts-schema", &origSchema) 46889bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar && origSchema.startsWith("android.generic")) { 46899bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar notify->setString("ts-schema", AStringPrintf( 46909bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar "android.generic.%u", vp8type.nTemporalLayerCount)); 46919bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar } else { 46929bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar notify->setString("ts-schema", AStringPrintf( 46939bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount)); 46944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia } 46954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia } 46964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia } 46974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia // Fall through to set up mime. 46984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia } 46994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia 4700e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar default: 4701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar { 4702777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (mIsEncoder ^ (portIndex == kPortIndexOutput)) { 4703777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim // should be CodingUnused 4704777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("Raw port video compression format is %s(%d)", 4705777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim asString(videoDef->eCompressionFormat), 4706777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim videoDef->eCompressionFormat); 4707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return BAD_VALUE; 4708777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar AString mime; 4710e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if (GetMimeTypeForVideoCoding( 4711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar videoDef->eCompressionFormat, &mime) != OK) { 4712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setString("mime", "application/octet-stream"); 4713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } else { 4714e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setString("mime", mime.c_str()); 4715e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 4716870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang uint32_t intraRefreshPeriod = 0; 4717870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK 4718870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang && intraRefreshPeriod > 0) { 4719870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang notify->setInt32("intra-refresh-period", intraRefreshPeriod); 4720870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 4721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar break; 4722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 472331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 4724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("width", videoDef->nFrameWidth); 4725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("height", videoDef->nFrameHeight); 47265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar ALOGV("[%s] %s format is %s", mComponentName.c_str(), 47275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar portIndex == kPortIndexInput ? "input" : "output", 47285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar notify->debugString().c_str()); 47295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar 473031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber break; 473131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 473231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 473331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber case OMX_PortDomainAudio: 473431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber { 473531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 473631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 473797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu switch ((int)audioDef->eEncoding) { 4738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber case OMX_AUDIO_CodingPCM: 4739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber { 4740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber OMX_AUDIO_PARAM_PCMMODETYPE params; 4741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber InitOMXParams(¶ms); 4742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar params.nPortIndex = portIndex; 4743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4744d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4745d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4746777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4747777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4748777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 474914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 4750777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (params.nChannels <= 0 4751777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim || (params.nChannels != 1 && !params.bInterleaved) 4752777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim || params.ePCMMode != OMX_AUDIO_PCMModeLinear) { 47535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar ALOGE("unsupported PCM port: %u channels%s, %u-bit", 4754777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim params.nChannels, 4755777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim params.bInterleaved ? " interleaved" : "", 47565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar params.nBitPerSample); 4757777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return FAILED_TRANSACTION; 4758777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 4761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("channel-count", params.nChannels); 4762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("sample-rate", params.nSamplingRate); 47635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 47645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar AudioEncoding encoding = kAudioEncodingPcm16bit; 47655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (params.eNumData == OMX_NumericalDataUnsigned 47665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar && params.nBitPerSample == 8u) { 47675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar encoding = kAudioEncodingPcm8bit; 47685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } else if (params.eNumData == OMX_NumericalDataFloat 47695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar && params.nBitPerSample == 32u) { 47705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar encoding = kAudioEncodingPcmFloat; 47715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } else if (params.nBitPerSample != 16u 47725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar || params.eNumData != OMX_NumericalDataSigned) { 47735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ", 47745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar asString(params.eNumData), params.eNumData, 47755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar asString(params.ePCMMode), params.ePCMMode); 47765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar return FAILED_TRANSACTION; 47775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 47785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar notify->setInt32("pcm-encoding", encoding); 4779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mChannelMaskPresent) { 4781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("channel-mask", mChannelMask); 47828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen } 4783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber break; 47848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen } 47859806555d3930be43e11106281dee354820ac1c88Andreas Huber 4786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber case OMX_AUDIO_CodingAAC: 4787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber { 4788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber OMX_AUDIO_PARAM_AACPROFILETYPE params; 4789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber InitOMXParams(¶ms); 4790e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar params.nPortIndex = portIndex; 4791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4792d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4793d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioAac, ¶ms, sizeof(params)); 4794777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4795777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4796777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 4799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("channel-count", params.nChannels); 4800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("sample-rate", params.nSampleRate); 4801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber break; 4802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 4803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber case OMX_AUDIO_CodingAMR: 4805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber { 4806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber OMX_AUDIO_PARAM_AMRTYPE params; 4807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber InitOMXParams(¶ms); 4808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar params.nPortIndex = portIndex; 48099806555d3930be43e11106281dee354820ac1c88Andreas Huber 4810d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4811d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioAmr, ¶ms, sizeof(params)); 4812777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4813777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4814777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("channel-count", 1); 4817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) { 48180806340688c937e7b78c2d89db3809274130df4eLajos Molnar notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 4819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("sample-rate", 16000); 4820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 48210806340688c937e7b78c2d89db3809274130df4eLajos Molnar notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 4822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("sample-rate", 8000); 4823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 4824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber break; 4825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 4826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber case OMX_AUDIO_CodingFLAC: 4828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber { 4829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber OMX_AUDIO_PARAM_FLACTYPE params; 4830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber InitOMXParams(¶ms); 4831e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar params.nPortIndex = portIndex; 4832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4833d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4834d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioFlac, ¶ms, sizeof(params)); 4835777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4836777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4837777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC); 4840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("channel-count", params.nChannels); 4841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber notify->setInt32("sample-rate", params.nSampleRate); 4842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber break; 4843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 4844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 4845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar case OMX_AUDIO_CodingMP3: 4846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar { 4847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar OMX_AUDIO_PARAM_MP3TYPE params; 4848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar InitOMXParams(¶ms); 4849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar params.nPortIndex = portIndex; 4850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 4851d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4852d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioMp3, ¶ms, sizeof(params)); 4853777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4854777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4855777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4856e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 4857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG); 4858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("channel-count", params.nChannels); 4859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("sample-rate", params.nSampleRate); 4860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar break; 4861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 4862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 4863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar case OMX_AUDIO_CodingVORBIS: 4864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar { 4865e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar OMX_AUDIO_PARAM_VORBISTYPE params; 4866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar InitOMXParams(¶ms); 4867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar params.nPortIndex = portIndex; 4868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 4869d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4870d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioVorbis, ¶ms, sizeof(params)); 4871777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4872777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4873777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 4874e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 4875e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS); 4876e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("channel-count", params.nChannels); 4877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setInt32("sample-rate", params.nSampleRate); 4878e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar break; 4879e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 4880e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 488197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu case OMX_AUDIO_CodingAndroidAC3: 488297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu { 488397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu OMX_AUDIO_PARAM_ANDROID_AC3TYPE params; 488497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu InitOMXParams(¶ms); 4885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar params.nPortIndex = portIndex; 488697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 4887d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4888d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 4889777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ¶ms, sizeof(params)); 4890777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4891777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4892777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 489397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 489497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3); 489597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu notify->setInt32("channel-count", params.nChannels); 489697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu notify->setInt32("sample-rate", params.nSampleRate); 489797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu break; 489897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 4899e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 49008a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad case OMX_AUDIO_CodingAndroidEAC3: 49018a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad { 49028a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params; 49038a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad InitOMXParams(¶ms); 49048a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad params.nPortIndex = portIndex; 49058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 4906d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4907d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 4908777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ¶ms, sizeof(params)); 4909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4911777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 49128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 49138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3); 49148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad notify->setInt32("channel-count", params.nChannels); 49158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad notify->setInt32("sample-rate", params.nSampleRate); 49168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad break; 49178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad } 49188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad 49198c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian case OMX_AUDIO_CodingAndroidOPUS: 49208c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian { 49218c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params; 49228c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian InitOMXParams(¶ms); 49238c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian params.nPortIndex = portIndex; 49248c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian 4925d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4926d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, 4927777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ¶ms, sizeof(params)); 4928777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4929777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 49318c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian 49328c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS); 49338c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian notify->setInt32("channel-count", params.nChannels); 49348c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian notify->setInt32("sample-rate", params.nSampleRate); 49358c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian break; 49368c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian } 49378c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian 493810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang case OMX_AUDIO_CodingG711: 493910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang { 494010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang OMX_AUDIO_PARAM_PCMMODETYPE params; 494110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang InitOMXParams(¶ms); 494210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang params.nPortIndex = portIndex; 494310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang 4944d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4945d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4948777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 494910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang 495010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang const char *mime = NULL; 495110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) { 495210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW; 495310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) { 495410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW; 495510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear 495610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang mime = MEDIA_MIMETYPE_AUDIO_RAW; 495710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang } 495810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang notify->setString("mime", mime); 495910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang notify->setInt32("channel-count", params.nChannels); 496010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang notify->setInt32("sample-rate", params.nSamplingRate); 496178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit); 496210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang break; 496310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang } 496441d3f579d2c166984958263533284209b90c87d5Marco Nelissen 496541d3f579d2c166984958263533284209b90c87d5Marco Nelissen case OMX_AUDIO_CodingGSMFR: 496641d3f579d2c166984958263533284209b90c87d5Marco Nelissen { 49670806340688c937e7b78c2d89db3809274130df4eLajos Molnar OMX_AUDIO_PARAM_PCMMODETYPE params; 496841d3f579d2c166984958263533284209b90c87d5Marco Nelissen InitOMXParams(¶ms); 496941d3f579d2c166984958263533284209b90c87d5Marco Nelissen params.nPortIndex = portIndex; 497041d3f579d2c166984958263533284209b90c87d5Marco Nelissen 4971d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mOMXNode->getParameter( 4972d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4973777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (err != OK) { 4974777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return err; 4975777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 497641d3f579d2c166984958263533284209b90c87d5Marco Nelissen 497741d3f579d2c166984958263533284209b90c87d5Marco Nelissen notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM); 497841d3f579d2c166984958263533284209b90c87d5Marco Nelissen notify->setInt32("channel-count", params.nChannels); 49790806340688c937e7b78c2d89db3809274130df4eLajos Molnar notify->setInt32("sample-rate", params.nSamplingRate); 498041d3f579d2c166984958263533284209b90c87d5Marco Nelissen break; 498110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang } 498210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang 4983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber default: 4984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("Unsupported audio coding: %s(%d)\n", 4985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim asString(audioDef->eEncoding), audioDef->eEncoding); 4986777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return BAD_TYPE; 4987e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 498831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber break; 498931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 499031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 499131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber default: 4992777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain); 4993777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return BAD_TYPE; 499431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 499531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 4996e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return OK; 4997e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar} 4998e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 4999b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) { 5000b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // aspects are normally communicated in ColorAspects 5001b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t range, standard, transfer; 5002b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer); 5003b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5004b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // if some aspects are unspecified, use dataspace fields 5005b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (range != 0) { 5006b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT; 5007b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5008b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (standard != 0) { 5009b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT; 5010b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5011b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (transfer != 0) { 5012b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT; 5013b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5014b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5015b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event 5016b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (range != 0) { 5017b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mOutputFormat->setInt32("color-range", range); 5018b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5019b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (standard != 0) { 5020b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mOutputFormat->setInt32("color-standard", standard); 5021b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5022b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (transfer != 0) { 5023b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mOutputFormat->setInt32("color-transfer", transfer); 5024b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5025b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5026b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) " 5027b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar "(R:%d(%s), S:%d(%s), T:%d(%s))", 5028b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar dataSpace, 5029b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mRange, asString(aspects.mRange), 5030b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mPrimaries, asString(aspects.mPrimaries), 5031b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 5032b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mTransfer, asString(aspects.mTransfer), 5033b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar range, asString((ColorRange)range), 5034b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar standard, asString((ColorStandard)standard), 5035b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar transfer, asString((ColorTransfer)transfer)); 5036b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 5037b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 50381734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) { 5039697aedf61d6180e72102068a969383018eedfa1eLajos Molnar // store new output format, at the same time mark that this is no longer the first frame 5040b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar mOutputFormat = mBaseOutputFormat->dup(); 5041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 5042b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) { 5043777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str()); 5044777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return; 5045777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 5046e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 50471734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar if (expectedFormat != NULL) { 50481734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat); 50491734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat); 50501734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar if (changes->countEntries() != 0 || to->countEntries() != 0) { 50511734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s", 50521734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar mComponentName.c_str(), 50531734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar changes->debugString(4).c_str(), to->debugString(4).c_str()); 50541734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar } 50551734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar } 50561734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar 50575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (!mIsVideo && !mIsEncoder) { 50585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar AudioEncoding pcmEncoding = kAudioEncodingPcm16bit; 50595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding); 50605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit; 50615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding); 50625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 50635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding); 50645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (mConverter[kPortIndexOutput] != NULL) { 50655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mOutputFormat->setInt32("pcm-encoding", pcmEncoding); 50665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 50675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 50685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar 5069b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar if (mTunneled) { 5070b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar sendFormatChange(); 5071b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar } 5072b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar} 5073b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar 5074b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> ¬ify) { 5075e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar AString mime; 5076b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar CHECK(mOutputFormat->findString("mime", &mime)); 5077e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 5078b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) { 5079b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // notify renderer of the crop change and dataspace change 5080e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar // NOTE: native window uses extended right-bottom coordinate 5081b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t left, top, right, bottom; 5082b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { 5083b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar notify->setRect("crop", left, top, right + 1, bottom + 1); 5084b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5085b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5086b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t dataSpace; 5087b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) { 5088b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar notify->setInt32("dataspace", dataSpace); 5089b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5090b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar } 5091b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar} 5092b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar 5093b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() { 5094b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar AString mime; 5095b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar CHECK(mOutputFormat->findString("mime", &mime)); 5096b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar 5097b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) { 5098b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen int32_t channelCount, sampleRate; 509984d7e874983ee0d66db328c454fa603374d4635fMarco Nelissen CHECK(mOutputFormat->findInt32("channel-count", &channelCount)); 5100b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate)); 5101b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen if (mSampleRate != 0 && sampleRate != 0) { 5102b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen mEncoderDelay = mEncoderDelay * sampleRate / mSampleRate; 5103b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen mEncoderPadding = mEncoderPadding * sampleRate / mSampleRate; 5104b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen mSampleRate = sampleRate; 5105b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen } 5106e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if (mSkipCutBuffer != NULL) { 5107e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar size_t prevbufsize = mSkipCutBuffer->size(); 5108e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if (prevbufsize != 0) { 5109ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 5110e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 5111e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 5112b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount); 5113e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 5114e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 5115b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar // mLastOutputFormat is not used when tunneled; doing this just to stay consistent 5116b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar mLastOutputFormat = mOutputFormat; 511731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber} 511831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 51195778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 5120cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber sp<AMessage> notify = mNotify->dup(); 5121d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatError); 5122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 5123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung 5124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (internalError == UNKNOWN_ERROR) { // find better error code 5125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t omxStatus = statusFromOMXError(error); 5126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (omxStatus != 0) { 5127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung internalError = omxStatus; 5128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else { 5129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung ALOGW("Invalid OMX error %#x", error); 5130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 5131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 5132346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang 5133346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang mFatalError = true; 5134346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang 51355778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->setInt32("err", internalError); 5136251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error. 5137cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber notify->post(); 5138cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber} 5139cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber 5140496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() { 5141496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (!mIsEncoder) { 5142496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber return ERROR_UNSUPPORTED; 5143496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 5144496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 5145496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber OMX_CONFIG_INTRAREFRESHVOPTYPE params; 5146496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber InitOMXParams(¶ms); 5147496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 5148496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber params.nPortIndex = kPortIndexOutput; 5149496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber params.IntraRefreshVOP = OMX_TRUE; 5150496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 5151d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang return mOMXNode->setConfig( 5152496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber OMX_IndexConfigVideoIntraVOPRefresh, 5153496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber ¶ms, 5154496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber sizeof(params)); 5155496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 5156496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 51577e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim//////////////////////////////////////////////////////////////////////////////// 51587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim 51597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik KimACodec::PortDescription::PortDescription() { 51607e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim} 51617e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim 5162eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer( 51634811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim IOMX::buffer_id id, const sp<MediaCodecBuffer> &buffer) { 5164eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber mBufferIDs.push_back(id); 5165eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber mBuffers.push_back(buffer); 5166eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber} 5167eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 5168eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() { 5169eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber return mBufferIDs.size(); 5170eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber} 5171eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 5172eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const { 5173eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber return mBufferIDs.itemAt(index); 5174eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber} 5175eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 51767e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimsp<MediaCodecBuffer> ACodec::PortDescription::bufferAt(size_t index) const { 5177eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber return mBuffers.itemAt(index); 5178eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber} 5179eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 5180eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber//////////////////////////////////////////////////////////////////////////////// 5181eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 5182f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : AState(parentState), 5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec(codec) { 5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5187ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 5188ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber OMX_U32 /* portIndex */) { 5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return KEEP_BUFFERS; 5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatInputBufferFilled: 5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onInputBufferFilled(msg); 5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatOutputBufferDrained: 5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onOutputBufferDrained(msg); 5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 520626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar case ACodec::kWhatOMXMessageList: 520726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar { 520826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar return checkOMXMessage(msg) ? onOMXMessageList(msg) : true; 520926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar } 521026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar 5211e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar case ACodec::kWhatOMXMessageItem: 5212e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar { 5213e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar // no need to check as we already did it for kWhatOMXMessageList 5214e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar return onOMXMessage(msg); 5215e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar } 5216e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar 5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case ACodec::kWhatOMXMessage: 5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 521926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar return checkOMXMessage(msg) ? onOMXMessage(msg) : true; 5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 52221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case ACodec::kWhatSetSurface: 52231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar { 52241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AReplyToken> replyID; 52251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 52261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 52271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<RefBase> obj; 52281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar CHECK(msg->findObject("surface", &obj)); 52291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 52302235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get())); 52311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 52321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> response = new AMessage; 52331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar response->setInt32("err", err); 52341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar response->postReply(replyID); 52351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar break; 52361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 52371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 52387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case ACodec::kWhatCreateInputSurface: 52398f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang case ACodec::kWhatSetInputSurface: 52407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case ACodec::kWhatSignalEndOfInputStream: 52417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 5242251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung // This may result in an app illegal state exception. 52437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGE("Message 0x%x was not handled", msg->what()); 52447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 52457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return true; 52467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 52477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 5248ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber case ACodec::kWhatOMXDied: 5249ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber { 5250251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung // This will result in kFlagSawMediaServerDie handling in MediaCodec. 5251ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber ALOGE("OMX/mediaserver died, signalling error!"); 52526d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mGraphicBufferSource.clear(); 5253ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 5254ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber break; 5255ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber } 5256ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber 525730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar case ACodec::kWhatReleaseCodecInstance: 525830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar { 525930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar ALOGI("[%s] forcing the release of codec", 526030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar mCodec->mComponentName.c_str()); 5261d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mCodec->mOMXNode->freeNode(); 526230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar ALOGE_IF("[%s] failed to release codec instance: err=%d", 526330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar mCodec->mComponentName.c_str(), err); 526430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar sp<AMessage> notify = mCodec->mNotify->dup(); 5265349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang notify->setInt32("what", CodecBase::kWhatReleaseCompleted); 526630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar notify->post(); 526730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar break; 526830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar } 526930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar 5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 5271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 527726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) { 52785e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar // there is a possibility that this is an outstanding message for a 52795e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar // codec that we have already destroyed 5280d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (mCodec->mOMXNode == NULL) { 52815e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar ALOGI("ignoring message as already freed component: %s", 52825e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar msg->debugString().c_str()); 528326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar return false; 52845e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar } 52855e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar 5286d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang int32_t generation; 5287d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang CHECK(msg->findInt32("generation", (int32_t*)&generation)); 5288d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (generation != mCodec->mNodeGeneration) { 5289d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang ALOGW("Unexpected message for component: %s, gen %u, cur %u", 5290d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang msg->debugString().c_str(), generation, mCodec->mNodeGeneration); 5291777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return false; 5292777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 529326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar return true; 529426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar} 529526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar 529626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) { 529726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar sp<RefBase> obj; 529826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar CHECK(msg->findObject("messages", &obj)); 529926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar sp<MessageList> msgList = static_cast<MessageList *>(obj.get()); 530026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar 530190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar bool receivedRenderedEvents = false; 530226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin(); 530326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar it != msgList->getList().cend(); ++it) { 5304e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar (*it)->setWhat(ACodec::kWhatOMXMessageItem); 5305e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar mCodec->handleMessage(*it); 530690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar int32_t type; 530790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar CHECK((*it)->findInt32("type", &type)); 530890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (type == omx_message::FRAME_RENDERED) { 530990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar receivedRenderedEvents = true; 531090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 531190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 531290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 531390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (receivedRenderedEvents) { 531490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // NOTE: all buffers are rendered in this case 531590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mCodec->notifyOfRenderedFrames(); 531626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar } 531726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar return true; 531826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar} 531926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar 532026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 532126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar int32_t type; 532226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar CHECK(msg->findInt32("type", &type)); 5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (type) { 5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case omx_message::EVENT: 5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t event, data1, data2; 5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("event", &event)); 5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("data1", &data1)); 5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("data2", &data2)); 5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 53320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber if (event == OMX_EventCmdComplete 53330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber && data1 == OMX_CommandFlush 53340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber && data2 == (int32_t)OMX_ALL) { 53350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber // Use of this notification is not consistent across 53360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber // implementations. We'll drop this notification and rely 53370af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber // on flush-complete notifications on the individual port 53380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber // indices instead. 53390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber 53400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber return true; 53410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber } 53420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber 5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return onOMXEvent( 5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber static_cast<OMX_EVENTTYPE>(event), 5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber static_cast<OMX_U32>(data1), 5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber static_cast<OMX_U32>(data2)); 5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case omx_message::EMPTY_BUFFER_DONE: 5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id bufferID; 535215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar int32_t fenceFd; 535315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 5354609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 535515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar CHECK(msg->findInt32("fence_fd", &fenceFd)); 5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 535715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar return onOMXEmptyBufferDone(bufferID, fenceFd); 5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case omx_message::FILL_BUFFER_DONE: 5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id bufferID; 5363609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 536515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar int32_t rangeOffset, rangeLength, flags, fenceFd; 5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t timeUs; 5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("range_offset", &rangeOffset)); 5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("range_length", &rangeLength)); 5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("flags", &flags)); 5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt64("timestamp", &timeUs)); 537215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar CHECK(msg->findInt32("fence_fd", &fenceFd)); 5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return onOMXFillBufferDone( 5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bufferID, 5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (size_t)rangeOffset, (size_t)rangeLength, 5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (OMX_U32)flags, 537815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar timeUs, 537915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar fenceFd); 5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 538290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar case omx_message::FRAME_RENDERED: 538390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar { 538490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar int64_t mediaTimeUs, systemNano; 538590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 538690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar CHECK(msg->findInt64("media_time_us", &mediaTimeUs)); 538790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar CHECK(msg->findInt64("system_nano", &systemNano)); 538890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 538990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar return onOMXFrameRendered( 539090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mediaTimeUs, systemNano); 539190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 539290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 5394777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("Unexpected message type: %d", type); 5395777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return false; 5396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 539990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered( 540090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) { 540190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // ignore outside of Executing and PortSettingsChanged states 540290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar return true; 540390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar} 540490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent( 5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (event == OMX_EventDataSpaceChanged) { 54086cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang ColorAspects aspects = ColorUtils::unpackToColorAspects(data2); 5409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mCodec->onDataSpaceChanged((android_dataspace)data1, aspects); 5411b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return true; 5412b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (event != OMX_EventError) { 5415ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mComponentName.c_str(), event, data1, data2); 5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5421ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5423251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung // verify OMX component sends back an error we expect. 5424251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 5425251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isOMXError(omxError)) { 5426251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung ALOGW("Invalid OMX error %#x", omxError); 5427251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung omxError = OMX_ErrorUndefined; 5428251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 5429251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mCodec->signalError(omxError); 5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 543415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) { 5435ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] onOMXEmptyBufferDone %u", 5436349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mCodec->mComponentName.c_str(), bufferID); 5437349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 54380806340688c937e7b78c2d89db3809274130df4eLajos Molnar BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 54390806340688c937e7b78c2d89db3809274130df4eLajos Molnar BufferInfo::Status status = BufferInfo::getSafeStatus(info); 54400806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (status != BufferInfo::OWNED_BY_COMPONENT) { 54410806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 54420806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->dumpBuffers(kPortIndexInput); 544315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 544415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 544515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 54460806340688c937e7b78c2d89db3809274130df4eLajos Molnar return false; 54470806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = BufferInfo::OWNED_BY_US; 5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 545015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // input buffers cannot take fences, so wait for any fence now 545115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone"); 545215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar fenceFd = -1; 545315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 545415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // still save fence for completeness 545515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->setWriteFence(fenceFd, "onOMXEmptyBufferDone"); 545615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 545796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia // We're in "store-metadata-in-buffers" mode, the underlying 545896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia // OMX component had access to data that's implicitly refcounted 545996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia // by this "MediaBuffer" object. Now that the OMX component has 546096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia // told us that it's done with the input buffer, we can decrement 546196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia // the mediaBuffer's reference count. 546296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia info->mData->setMediaBufferBase(NULL); 5463d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber PortMode mode = getPortMode(kPortIndexInput); 5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (mode) { 5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case KEEP_BUFFERS: 5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case RESUBMIT_BUFFERS: 5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postFillThisBuffer(info); 5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5474777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim case FREE_BUFFERS: 5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 5476777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers"); 5477777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return false; 5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5483f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCodec->mPortEOS[kPortIndexInput]) { 5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 5491d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatFillThisBuffer); 5492609b815a3131d22da38b2f452faa9f89daad4039Andy Hung notify->setInt32("buffer-id", info->mBufferID); 5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5494ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim info->mData->setFormat(mCodec->mInputFormat); 5495ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim notify->setObject("buffer", info->mData); 5496fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim info->mData.clear(); 5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 54981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec); 5499609b815a3131d22da38b2f452faa9f89daad4039Andy Hung reply->setInt32("buffer-id", info->mBufferID); 5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setMessage("reply", reply); 5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5508f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id bufferID; 5510609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 55117e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> buffer; 5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t err = OK; 55135778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool eos = false; 5514a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar PortMode mode = getPortMode(kPortIndexInput); 55155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 55167e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<RefBase> obj; 55177e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim if (!msg->findObject("buffer", &obj)) { 5518a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar /* these are unfilled buffers returned by client */ 5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("err", &err)); 5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar if (err == OK) { 55227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar /* buffers with no errors are returned on MediaCodec.flush */ 55237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar mode = KEEP_BUFFERS; 55247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar } else { 55257fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar ALOGV("[%s] saw error %d instead of an input buffer", 55267fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar mCodec->mComponentName.c_str(), err); 55277fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar eos = true; 55287fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar } 55297e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim } else { 55307e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim buffer = static_cast<MediaCodecBuffer *>(obj.get()); 5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55335778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t tmp; 55345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 55355778822d86b0337407514b9372562b86edfa91cdAndreas Huber eos = true; 55365778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = ERROR_END_OF_STREAM; 55375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 55385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 55400806340688c937e7b78c2d89db3809274130df4eLajos Molnar BufferInfo::Status status = BufferInfo::getSafeStatus(info); 55410806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (status != BufferInfo::OWNED_BY_UPSTREAM) { 55420806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID); 55430806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->dumpBuffers(kPortIndexInput); 55440806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 55450806340688c937e7b78c2d89db3809274130df4eLajos Molnar return; 55460806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = BufferInfo::OWNED_BY_US; 5549fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim info->mData = buffer; 5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (mode) { 5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case KEEP_BUFFERS: 5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 55545778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (eos) { 5555dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber if (!mCodec->mPortEOS[kPortIndexInput]) { 5556dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mCodec->mPortEOS[kPortIndexInput] = true; 5557dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mCodec->mInputEOSResult = err; 5558dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber } 5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case RESUBMIT_BUFFERS: 5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 55655778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 5566fd866b3aa0d97375de08f8888b95669026c83361Wei Jia // Do not send empty input buffer w/o EOS to the component. 5567fd866b3aa0d97375de08f8888b95669026c83361Wei Jia if (buffer->size() == 0 && !eos) { 5568fd866b3aa0d97375de08f8888b95669026c83361Wei Jia postFillThisBuffer(info); 5569fd866b3aa0d97375de08f8888b95669026c83361Wei Jia break; 5570fd866b3aa0d97375de08f8888b95669026c83361Wei Jia } 5571fd866b3aa0d97375de08f8888b95669026c83361Wei Jia 5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t timeUs; 5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5577d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar int32_t isCSD = 0; 5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 5579f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang if (mCodec->mIsLegacyVP9Decoder) { 5580f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data", 5581f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang mCodec->mComponentName.c_str(), bufferID); 5582f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang postFillThisBuffer(info); 5583f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang break; 5584f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang } 5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flags |= OMX_BUFFERFLAG_CODECCONFIG; 5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55885778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (eos) { 55895778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= OMX_BUFFERFLAG_EOS; 55905778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 55915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5592fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim size_t size = buffer->size(); 5593fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim if (buffer->base() != info->mCodecData->base()) { 5594ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 5595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCodec->mComponentName.c_str(), 5596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bufferID, 5597fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim buffer->base(), info->mCodecData->base()); 5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput]; 5600d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar if (converter == NULL || isCSD) { 56015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar converter = getCopyConverter(); 56025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 56035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar status_t err = converter->convert(buffer, info->mCodecData); 56045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (err != OK) { 56055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mCodec->signalError(OMX_ErrorUndefined, err); 56060806340688c937e7b78c2d89db3809274130df4eLajos Molnar return; 56070806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 5608fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim size = info->mCodecData->size(); 56093fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang } else { 56103fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang info->mCodecData->setRange(0, size); 5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5613078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 5614ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 5615078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mCodec->mComponentName.c_str(), bufferID); 56165778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (flags & OMX_BUFFERFLAG_EOS) { 5617ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] calling emptyBuffer %u w/ EOS", 56185778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->mComponentName.c_str(), bufferID); 5619078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 5620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING 5621ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 5622ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else 5624ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 5625ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif 5627078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 5628349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 5629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING 5630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ACodec::BufferStats stats; 5631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 5632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber stats.mFillBufferDoneTimeUs = -1ll; 5633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCodec->mBufferStats.add(timeUs, stats); 5634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif 5635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5636054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (mCodec->storingMetadataInDecodedBuffers()) { 5637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // try to submit an output buffer for each input buffer 5638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar PortMode outputMode = getPortMode(kPortIndexOutput); 5639054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 5640054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGV("MetadataBuffersToSubmit=%u portMode=%s", 5641054219874873b41f1c815552987c10465c34ba2bLajos Molnar mCodec->mMetadataBuffersToSubmit, 5642054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar (outputMode == FREE_BUFFERS ? "FREE" : 5643054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 5644054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (outputMode == RESUBMIT_BUFFERS) { 5645054219874873b41f1c815552987c10465c34ba2bLajos Molnar mCodec->submitOutputMetadataBuffer(); 5646054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 5647054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 564815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->checkReadFence("onInputBufferFilled"); 5649d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar 5650d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar status_t err2 = OK; 5651d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang switch (mCodec->mPortMode[kPortIndexInput]) { 5652d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang case IOMX::kPortModePresetByteBuffer: 5653d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang case IOMX::kPortModePresetANWBuffer: 5654d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang case IOMX::kPortModePresetSecureBuffer: 56553fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang { 56563fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang err2 = mCodec->mOMXNode->emptyBuffer( 56573fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang bufferID, info->mCodecData, flags, timeUs, info->mFenceFd); 56583fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang } 5659d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar break; 5660d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5661d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang case IOMX::kPortModeDynamicNativeHandle: 5662d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) { 5663d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar VideoNativeHandleMetadata *vnhmd = 5664d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar (VideoNativeHandleMetadata*)info->mCodecData->base(); 56653fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang sp<NativeHandle> handle = NativeHandle::create( 56663fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang vnhmd->pHandle, false /* ownsHandle */); 56673fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang err2 = mCodec->mOMXNode->emptyBuffer( 56683fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang bufferID, handle, flags, timeUs, info->mFenceFd); 5669d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar } 5670d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar break; 5671d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang case IOMX::kPortModeDynamicANWBuffer: 5672d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) { 5673d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base(); 56743fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang sp<GraphicBuffer> graphicBuffer = new GraphicBuffer( 56753fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang vnmd->pBuffer, false /* keepOwnership */); 56763fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang err2 = mCodec->mOMXNode->emptyBuffer( 56773fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang bufferID, graphicBuffer, flags, timeUs, info->mFenceFd); 5678d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar } 5679d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar break; 5680d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#endif 5681d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar default: 5682d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode", 5683d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang asString(mCodec->mPortMode[kPortIndexInput]), 5684d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang info->mCodecData->size(), 5685d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar sizeof(buffer_handle_t) * 8); 5686d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar err2 = ERROR_UNSUPPORTED; 5687d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar break; 5688d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar } 5689d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar 569015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->mFenceFd = -1; 56910806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err2 != OK) { 56920806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 56930806340688c937e7b78c2d89db3809274130df4eLajos Molnar return; 56940806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5696fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim // Hold the reference while component is using the buffer. 5697fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim info->mData = buffer; 5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 56990806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (!eos && err == OK) { 57005778822d86b0337407514b9372562b86edfa91cdAndreas Huber getMoreInputDataIfPossible(); 57015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 57020806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGV("[%s] Signalled EOS (%d) on the input port", 57030806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->mComponentName.c_str(), err); 57045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 57055778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->mPortEOS[kPortIndexInput] = true; 57065778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->mInputEOSResult = err; 57075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!mCodec->mPortEOS[kPortIndexInput]) { 57090806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK && err != ERROR_END_OF_STREAM) { 57100806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGV("[%s] Signalling EOS on the input port due to error %d", 5711dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mCodec->mComponentName.c_str(), err); 5712dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber } else { 57133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Signalling EOS on the input port", 5714dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mCodec->mComponentName.c_str()); 5715dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber } 5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5717ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] calling emptyBuffer %u signalling EOS", 5718349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mCodec->mComponentName.c_str(), bufferID); 5719349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 572015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->checkReadFence("onInputBufferFilled"); 5721d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err2 = mCodec->mOMXNode->emptyBuffer( 57223fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd); 572315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->mFenceFd = -1; 57240806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err2 != OK) { 57250806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 57260806340688c937e7b78c2d89db3809274130df4eLajos Molnar return; 57270806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mPortEOS[kPortIndexInput] = true; 5731dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mCodec->mInputEOSResult = err; 5732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5735625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih 5736777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim case FREE_BUFFERS: 5737777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim break; 5738777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim 5739625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih default: 5740777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("invalid port mode: %d", mode); 5741625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih break; 5742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5745f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() { 5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCodec->mPortEOS[kPortIndexInput]) { 5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *eligible = NULL; 5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0 5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // There's already a "read" pending. 5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mStatus == BufferInfo::OWNED_BY_US) { 5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber eligible = info; 5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (eligible == NULL) { 5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postFillThisBuffer(eligible); 5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone( 5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id bufferID, 5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t rangeOffset, size_t rangeLength, 5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 flags, 577815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar int64_t timeUs, 577915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar int fenceFd) { 5780609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 57815778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 5782349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 5783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ssize_t index; 57840806340688c937e7b78c2d89db3809274130df4eLajos Molnar status_t err= OK; 5785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING 5787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber index = mCodec->mBufferStats.indexOfKey(timeUs); 5788d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (index >= 0) { 5789d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 5790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 5791d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("frame PTS %lld: %lld", 5793d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber timeUs, 5794d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 5795d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5796d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCodec->mBufferStats.removeItemsAt(index); 5797d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber stats = NULL; 5798d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 5799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif 5800d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = 5802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 58030806340688c937e7b78c2d89db3809274130df4eLajos Molnar BufferInfo::Status status = BufferInfo::getSafeStatus(info); 58040806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (status != BufferInfo::OWNED_BY_COMPONENT) { 58050806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 58060806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->dumpBuffers(kPortIndexOutput); 58070806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 580815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 580915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 581015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 58110806340688c937e7b78c2d89db3809274130df4eLajos Molnar return true; 58120806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar info->mDequeuedAt = ++mCodec->mDequeueCounter; 5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = BufferInfo::OWNED_BY_US; 5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 581790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (info->mRenderInfo != NULL) { 581890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // The fence for an emptied buffer must have signaled, but there still could be queued 581990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these, 582090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // as we will soon requeue this buffer to the surface. While in theory we could still keep 582190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // track of buffers that are requeued to the surface, it is better to add support to the 582290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // buffer-queue to notify us of released buffers and their fences (in the future). 582390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mCodec->notifyOfRenderedFrames(true /* dropIncomplete */); 582490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 582590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 582615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // byte buffers cannot take fences, so wait for any fence now 582715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (mCodec->mNativeWindow == NULL) { 582815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone"); 582915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar fenceFd = -1; 583015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 583115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->setReadFence(fenceFd, "onOMXFillBufferDone"); 583215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber PortMode mode = getPortMode(kPortIndexOutput); 5834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (mode) { 5836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case KEEP_BUFFERS: 5837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case RESUBMIT_BUFFERS: 5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 5841a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 5842a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar || mCodec->mPortEOS[kPortIndexOutput])) { 5843609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGV("[%s] calling fillBuffer %u", 58445778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->mComponentName.c_str(), info->mBufferID); 5845349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 58463fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang err = mCodec->fillBuffer(info); 58470806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 58480806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 58490806340688c937e7b78c2d89db3809274130df4eLajos Molnar return true; 58500806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 58515778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 58525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 585331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 5854577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar sp<AMessage> reply = 58551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatOutputBufferDrained, mCodec); 5856ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim sp<MediaCodecBuffer> buffer = info->mData; 5857577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar 5858b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) { 5859697aedf61d6180e72102068a969383018eedfa1eLajos Molnar // pretend that output format has changed on the first frame (we used to do this) 5860697aedf61d6180e72102068a969383018eedfa1eLajos Molnar if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) { 58611734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar mCodec->onOutputFormatChanged(mCodec->mOutputFormat); 5862697aedf61d6180e72102068a969383018eedfa1eLajos Molnar } 5863b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar mCodec->addKeyFormatChangesToRenderBufferNotification(reply); 5864b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar mCodec->sendFormatChange(); 5865fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar } else if (rangeLength > 0 && mCodec->mNativeWindow != NULL) { 5866fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar // If potentially rendering onto a surface, always save key format data (crop & 5867fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar // data space) so that we can set it if and once the buffer is rendered. 5868fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar mCodec->addKeyFormatChangesToRenderBufferNotification(reply); 58695778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5870ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim buffer->setFormat(mCodec->mOutputFormat); 5871b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar 5872d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (mCodec->usingSecureBufferOnEncoderOutput()) { 5873054219874873b41f1c815552987c10465c34ba2bLajos Molnar native_handle_t *handle = NULL; 5874d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get()); 5875d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang if (secureBuffer != NULL) { 58767c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 58773e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar // handle is only valid on 32-bit/mediaserver process 58787c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar handle = NULL; 58797c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else 5880d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang handle = (native_handle_t *)secureBuffer->getDestinationPointer(); 58817c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif 5882054219874873b41f1c815552987c10465c34ba2bLajos Molnar } 58837e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim buffer->meta()->setPointer("handle", handle); 58847e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim buffer->meta()->setInt32("rangeOffset", rangeOffset); 58857e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim buffer->meta()->setInt32("rangeLength", rangeLength); 5886fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim } else if (buffer->base() == info->mCodecData->base()) { 58877e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim buffer->setRange(rangeOffset, rangeLength); 58885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } else { 58895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar info->mCodecData->setRange(rangeOffset, rangeLength); 58905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar // in this case we know that mConverter is not null 58915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar status_t err = mCodec->mConverter[kPortIndexOutput]->convert( 58927e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim info->mCodecData, buffer); 58935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar if (err != OK) { 58945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 58955b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar return true; 58965b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar } 5897308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 5898496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0 589921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen if (mCodec->mNativeWindow == NULL) { 5900496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (IsIDR(info->mData)) { 5901496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber ALOGI("IDR frame"); 5902496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 59035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 590421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif 5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 59068b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen if (mCodec->mSkipCutBuffer != NULL) { 59077e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim mCodec->mSkipCutBuffer->submit(buffer); 59088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen } 59097e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim buffer->meta()->setInt64("timeUs", timeUs); 5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 59115778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 5912d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatDrainThisBuffer); 5913609b815a3131d22da38b2f452faa9f89daad4039Andy Hung notify->setInt32("buffer-id", info->mBufferID); 59147e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim notify->setObject("buffer", buffer); 5915fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim info->mData.clear(); 59165778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->setInt32("flags", flags); 5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5918609b815a3131d22da38b2f452faa9f89daad4039Andy Hung reply->setInt32("buffer-id", info->mBufferID); 5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 59205778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->setMessage("reply", reply); 5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 59225778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->post(); 59235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 59245778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (flags & OMX_BUFFERFLAG_EOS) { 59275778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 59285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 5930d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatEOS); 5931dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber notify->setInt32("err", mCodec->mInputEOSResult); 5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mPortEOS[kPortIndexOutput] = true; 5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5939777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim case FREE_BUFFERS: 59400806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = mCodec->freeBuffer(kPortIndexOutput, index); 59410806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 59420806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 59430806340688c937e7b78c2d89db3809274130df4eLajos Molnar return true; 59440806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 5946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim 5947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim default: 5948777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("Invalid port mode: %d", mode); 5949777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return false; 5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5955f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id bufferID; 5957609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 59587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<RefBase> obj; 59597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> buffer = nullptr; 59607e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim if (msg->findObject("buffer", &obj)) { 59617e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim buffer = static_cast<MediaCodecBuffer *>(obj.get()); 59627e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim } 5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ssize_t index; 59640806340688c937e7b78c2d89db3809274130df4eLajos Molnar BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 59650806340688c937e7b78c2d89db3809274130df4eLajos Molnar BufferInfo::Status status = BufferInfo::getSafeStatus(info); 59660806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 59670806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 59680806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->dumpBuffers(kPortIndexOutput); 59690806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 59700806340688c937e7b78c2d89db3809274130df4eLajos Molnar return; 59710806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 5972fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim info->mData = buffer; 5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5974577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar android_native_rect_t crop; 5975fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom) 5976fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar && memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) { 5977fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar mCodec->mLastNativeWindowCrop = crop; 5978777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 5979777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 5980577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar } 5981577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar 5982b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t dataSpace; 5983fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar if (msg->findInt32("dataspace", &dataSpace) 5984fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar && dataSpace != mCodec->mLastNativeWindowDataSpace) { 5985b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = native_window_set_buffers_data_space( 5986b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mCodec->mNativeWindow.get(), (android_dataspace)dataSpace); 5987fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar mCodec->mLastNativeWindowDataSpace = dataSpace; 5988b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err); 5989b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 5990b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t render; 5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCodec->mNativeWindow != NULL 59936aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen && msg->findInt32("render", &render) && render != 0 59947e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim && buffer != NULL && buffer->size() != 0) { 59956fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar ATRACE_NAME("render"); 5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // The client wants this buffer to be rendered. 5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 599890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // save buffers sent to the surface so we can get render time when they return 599990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar int64_t mediaTimeUs = -1; 60007e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim buffer->meta()->findInt64("timeUs", &mediaTimeUs); 600190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (mediaTimeUs >= 0) { 600290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mCodec->mRenderTracker.onFrameQueued( 600390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd))); 600490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 600590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 6006fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar int64_t timestampNs = 0; 6007fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (!msg->findInt64("timestampNs", ×tampNs)) { 6008c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar // use media timestamp if client did not request a specific render timestamp 60097e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim if (buffer->meta()->findInt64("timeUs", ×tampNs)) { 6010c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar ALOGV("using buffer PTS of %lld", (long long)timestampNs); 6011fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar timestampNs *= 1000; 6012fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 6013fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 6014fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 60155778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 6016fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 60170806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 6018fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 601915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->checkReadFence("onOutputBufferDrained before queueBuffer"); 60200806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = mCodec->mNativeWindow->queueBuffer( 602115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 602215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->mFenceFd = -1; 60230806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err == OK) { 6024cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 6025cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber } else { 6026264bac95912efe121d6a60026612617f04f42966Lajos Molnar ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err); 6027251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6028cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber info->mStatus = BufferInfo::OWNED_BY_US; 602915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // keeping read fence as write fence to avoid clobbering 603015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->mIsReadFence = false; 6031cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber } 6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 60336fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar if (mCodec->mNativeWindow != NULL && 60347e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim (buffer == NULL || buffer->size() != 0)) { 603515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // move read fence into write fence to avoid clobbering 603615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->mIsReadFence = false; 60376fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar ATRACE_NAME("frame-drop"); 60386fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar } 6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = BufferInfo::OWNED_BY_US; 6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber PortMode mode = getPortMode(kPortIndexOutput); 6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (mode) { 6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case KEEP_BUFFERS: 6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // We cannot resubmit the buffer we just rendered, dequeue 6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // the spare instead. 6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info = mCodec->dequeueBufferFromNativeWindow(); 6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case RESUBMIT_BUFFERS: 6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mCodec->mPortEOS[kPortIndexOutput]) { 6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // We cannot resubmit the buffer we just rendered, dequeue 6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // the spare instead. 6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info = mCodec->dequeueBufferFromNativeWindow(); 6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6068c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber if (info != NULL) { 6069609b815a3131d22da38b2f452faa9f89daad4039Andy Hung ALOGV("[%s] calling fillBuffer %u", 6070c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber mCodec->mComponentName.c_str(), info->mBufferID); 607115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS"); 60723fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang status_t err = mCodec->fillBuffer(info); 60733fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang if (err != OK) { 60740806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 60750806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6076c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } 6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6081777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim case FREE_BUFFERS: 6082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 60830806340688c937e7b78c2d89db3809274130df4eLajos Molnar status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 60840806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 60850806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 60860806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6089777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim 6090777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim default: 6091777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGE("Invalid port mode: %d", mode); 6092777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return; 6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 6097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6098f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec) 6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : BaseState(codec) { 6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6102c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() { 6103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber ALOGV("Now uninitialized"); 6104ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber 6105ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber if (mDeathNotifier != NULL) { 61061d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang if (mCodec->mOMXNode != NULL) { 61071d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode); 61081d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang binder->unlinkToDeath(mDeathNotifier); 61091d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang } 6110ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber mDeathNotifier.clear(); 6111ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber } 6112ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber 6113b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mCodec->mUsingNativeWindow = false; 6114ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber mCodec->mNativeWindow.clear(); 6115e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar mCodec->mNativeWindowUsageBits = 0; 6116ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber mCodec->mOMX.clear(); 6117d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang mCodec->mOMXNode.clear(); 6118ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber mCodec->mFlags = 0; 6119d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 6120d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 61215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mCodec->mConverter[0].clear(); 61225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar mCodec->mConverter[1].clear(); 6123ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber mCodec->mComponentName.clear(); 6124c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 6125c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool handled = false; 6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case ACodec::kWhatSetup: 6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onSetup(msg); 6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 61385778822d86b0337407514b9372562b86edfa91cdAndreas Huber case ACodec::kWhatAllocateComponent: 61395778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 61405778822d86b0337407514b9372562b86edfa91cdAndreas Huber onAllocateComponent(msg); 61415778822d86b0337407514b9372562b86edfa91cdAndreas Huber handled = true; 61425778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 61435778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 61445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case ACodec::kWhatShutdown: 6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber int32_t keepComponentAllocated; 6148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK(msg->findInt32( 6149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber "keepComponentAllocated", &keepComponentAllocated)); 615054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar ALOGW_IF(keepComponentAllocated, 615154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar "cannot keep component allocated on shutdown in Uninitialized state"); 6152c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 6154349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang notify->setInt32("what", keepComponentAllocated ? 6155349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang CodecBase::kWhatStopCompleted : CodecBase::kWhatReleaseCompleted); 6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 6159c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber break; 6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case ACodec::kWhatFlush: 6163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 6165d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 6169c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber break; 6170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 617230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar case ACodec::kWhatReleaseCodecInstance: 617330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar { 617430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar // nothing to do, as we have already signaled shutdown 617530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar handled = true; 617630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar break; 617730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar } 617830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar 6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onMessageReceived(msg); 6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return handled; 6184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6186f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup( 6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> &msg) { 6188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (onAllocateComponent(msg) 6189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber && mCodec->mLoadedState->onConfigureComponent(msg)) { 6190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCodec->mLoadedState->onStart(); 6191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 61925778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 61935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 61955778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("onAllocateComponent"); 61965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6197d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang CHECK(mCodec->mOMXNode == NULL); 61985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMXClient client; 620048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung if (client.connect() != OK) { 620148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 620248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung return false; 620348a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung } 6204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<IOMX> omx = client.interface(); 6206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 62071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 6208ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber 6209b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar Vector<AString> matchingCodecs; 62105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber AString mime; 6212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 62135778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString componentName; 6214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t quirks = 0; 62157791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen int32_t encoder = false; 62165778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (msg->findString("componentName", &componentName)) { 6217b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar sp<IMediaCodecList> list = MediaCodecList::getInstance(); 6218b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) { 6219b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar matchingCodecs.add(componentName); 6220afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber } 62215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 62225778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("mime", &mime)); 62235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 62245778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("encoder", &encoder)) { 62255778822d86b0337407514b9372562b86edfa91cdAndreas Huber encoder = false; 62265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 62275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6228b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar MediaCodecList::findMatchingCodecs( 62295778822d86b0337407514b9372562b86edfa91cdAndreas Huber mime.c_str(), 62305778822d86b0337407514b9372562b86edfa91cdAndreas Huber encoder, // createEncoder 6231b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar 0, // flags 6232e671207115fac3914134c61b336d5fa0242c68caAndreas Huber &matchingCodecs); 62335778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 62341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 62351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber sp<CodecObserver> observer = new CodecObserver; 6236d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang sp<IOMXNode> omxNode; 62371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 6238201d8d400eb037547f4f476a838475b13a446007Wei Jia status_t err = NAME_NOT_FOUND; 62391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 62401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber ++matchIndex) { 6241b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar componentName = matchingCodecs[matchIndex]; 6242b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar quirks = MediaCodecList::getQuirksFor(componentName.c_str()); 6243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6244da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes pid_t tid = gettid(); 6245078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber int prevPriority = androidGetThreadPriority(tid); 6246078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 62471d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang err = omx->allocateNode(componentName.c_str(), observer, &omxNode); 6248078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber androidSetThreadPriority(tid, prevPriority); 6249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 62501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber if (err == OK) { 62511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber break; 62527a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He } else { 62537a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 62541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 62551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 6256d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang omxNode = NULL; 62571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 62581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 6259d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (omxNode == NULL) { 62605778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!mime.empty()) { 62619f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 62629f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu encoder ? "en" : "de", mime.c_str(), err); 62635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 62649f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 62655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 6266c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 626752e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 6268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return false; 6269c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } 6270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 627123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen mDeathNotifier = new DeathNotifier(notify); 62721d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) { 627323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen // This was a local binder, if it dies so do we, we won't care 627423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen // about any notifications in the afterlife. 627523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen mDeathNotifier.clear(); 627623858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen } 627723858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen 627826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar notify = new AMessage(kWhatOMXMessageList, mCodec); 6279d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang notify->setInt32("generation", ++mCodec->mNodeGeneration); 6280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber observer->setNotificationMessage(notify); 6281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mComponentName = componentName; 628390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mCodec->mRenderTracker.setComponentName(componentName); 6284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber mCodec->mFlags = 0; 6285ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 6286ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (componentName.endsWith(".secure")) { 6287ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber mCodec->mFlags |= kFlagIsSecure; 62881713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang mCodec->mFlags |= kFlagIsGrallocUsageProtected; 62890167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 6290ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 6291ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 629221b46588d022d0c22d7c7c08e919d7a9c5cd76e3Chong Zhang omxNode->setQuirks(quirks); 6293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mOMX = omx; 6294d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang mCodec->mOMXNode = omxNode; 6295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 62965778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 62975778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 6298d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatComponentAllocated); 62995778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->setString("componentName", mCodec->mComponentName.c_str()); 63005778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->post(); 63015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 6302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCodec->changeState(mCodec->mLoadedState); 6304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return true; 63065778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 63075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber//////////////////////////////////////////////////////////////////////////////// 6309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec) 6311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber : BaseState(codec) { 6312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 6313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() { 6315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 6316c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6317f6f38287b97ec69b169387add6458f859b770e65Andreas Huber mCodec->mPortEOS[kPortIndexInput] = 6318f6f38287b97ec69b169387add6458f859b770e65Andreas Huber mCodec->mPortEOS[kPortIndexOutput] = false; 6319f6f38287b97ec69b169387add6458f859b770e65Andreas Huber 6320f6f38287b97ec69b169387add6458f859b770e65Andreas Huber mCodec->mInputEOSResult = OK; 6321f6f38287b97ec69b169387add6458f859b770e65Andreas Huber 6322054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mCodec->mDequeueCounter = 0; 6323054219874873b41f1c815552987c10465c34ba2bLajos Molnar mCodec->mMetadataBuffersToSubmit = 0; 6324a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mCodec->mRepeatFrameDelayUs = -1ll; 6325e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar mCodec->mInputFormat.clear(); 6326e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar mCodec->mOutputFormat.clear(); 63274e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar mCodec->mBaseOutputFormat.clear(); 63286d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mGraphicBufferSource.clear(); 6329054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 6330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mCodec->mShutdownInProgress) { 6331c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 6332c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCodec->mShutdownInProgress = false; 6334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCodec->mKeepComponentAllocated = false; 6335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6336c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber onShutdown(keepComponentAllocated); 6337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 633854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar mCodec->mExplicitShutdown = false; 6339f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia 6340f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia mCodec->processDeferredMessages(); 6341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 6342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6343c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 6344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (!keepComponentAllocated) { 6345d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (void)mCodec->mOMXNode->freeNode(); 6346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6347c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCodec->changeState(mCodec->mUninitializedState); 6348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 6349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 635054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar if (mCodec->mExplicitShutdown) { 635154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar sp<AMessage> notify = mCodec->mNotify->dup(); 6352349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang notify->setInt32("what", keepComponentAllocated ? 6353349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang CodecBase::kWhatStopCompleted : CodecBase::kWhatReleaseCompleted); 635454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar notify->post(); 635554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar mCodec->mExplicitShutdown = false; 635654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar } 6357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 6358c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6359c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 6360c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber bool handled = false; 6361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber switch (msg->what()) { 6363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case ACodec::kWhatConfigureComponent: 6364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 6365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber onConfigureComponent(msg); 6366c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber handled = true; 6367c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 6368c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 6369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 63707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case ACodec::kWhatCreateInputSurface: 63717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 63727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden onCreateInputSurface(msg); 63737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden handled = true; 63747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 63757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 63767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 63778f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang case ACodec::kWhatSetInputSurface: 6378d291c222357303b9611cab89d0c3b047584ef377Chong Zhang { 63798f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang onSetInputSurface(msg); 6380d291c222357303b9611cab89d0c3b047584ef377Chong Zhang handled = true; 6381d291c222357303b9611cab89d0c3b047584ef377Chong Zhang break; 6382d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 6383d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6384c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case ACodec::kWhatStart: 6385c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 6386c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber onStart(); 6387c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber handled = true; 6388c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 6389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 6390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6391c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case ACodec::kWhatShutdown: 6392c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 6393c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber int32_t keepComponentAllocated; 6394c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK(msg->findInt32( 6395c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber "keepComponentAllocated", &keepComponentAllocated)); 6396c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 639754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar mCodec->mExplicitShutdown = true; 6398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber onShutdown(keepComponentAllocated); 6399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber handled = true; 6401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 6402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 6403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6404c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case ACodec::kWhatFlush: 6405c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 6406c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 6407d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber notify->post(); 6409c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber handled = true; 6411c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 6412c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 6413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6414c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber default: 6415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return BaseState::onMessageReceived(msg); 6416c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 6417c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6418c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return handled; 6419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 6420c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6421c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent( 64225778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &msg) { 64235778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("onConfigureComponent"); 64245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6425d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang CHECK(mCodec->mOMXNode != NULL); 64265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 64270806340688c937e7b78c2d89db3809274130df4eLajos Molnar status_t err = OK; 64285778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString mime; 64290806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (!msg->findString("mime", &mime)) { 64300806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = BAD_VALUE; 64310806340688c937e7b78c2d89db3809274130df4eLajos Molnar } else { 64320806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = mCodec->configureCodec(mime.c_str(), msg); 64330806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 64345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 6435c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber ALOGE("[%s] configureCodec returning error %d", 6436c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber mCodec->mComponentName.c_str(), err); 6437c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber 6438251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return false; 64405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 6441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 64425778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 64435778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 6444d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatComponentConfigured); 6445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setMessage("input-format", mCodec->mInputFormat); 6446e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar notify->setMessage("output-format", mCodec->mOutputFormat); 64475778822d86b0337407514b9372562b86edfa91cdAndreas Huber notify->post(); 64485778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 6449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return true; 64515778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 64525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6453d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() { 6454addf2cbb120346ae42e78fa739245a353db5edadChong Zhang if (mCodec->mGraphicBufferSource == NULL) { 6455addf2cbb120346ae42e78fa739245a353db5edadChong Zhang return BAD_VALUE; 6456addf2cbb120346ae42e78fa739245a353db5edadChong Zhang } 6457addf2cbb120346ae42e78fa739245a353db5edadChong Zhang 6458addf2cbb120346ae42e78fa739245a353db5edadChong Zhang android_dataspace dataSpace; 6459addf2cbb120346ae42e78fa739245a353db5edadChong Zhang status_t err = 6460addf2cbb120346ae42e78fa739245a353db5edadChong Zhang mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace); 6461addf2cbb120346ae42e78fa739245a353db5edadChong Zhang if (err != OK) { 6462addf2cbb120346ae42e78fa739245a353db5edadChong Zhang ALOGE("Failed to get default data space"); 6463addf2cbb120346ae42e78fa739245a353db5edadChong Zhang return err; 6464addf2cbb120346ae42e78fa739245a353db5edadChong Zhang } 6465addf2cbb120346ae42e78fa739245a353db5edadChong Zhang 6466addf2cbb120346ae42e78fa739245a353db5edadChong Zhang err = statusFromBinderStatus( 6467addf2cbb120346ae42e78fa739245a353db5edadChong Zhang mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace)); 6468addf2cbb120346ae42e78fa739245a353db5edadChong Zhang if (err != OK) { 6469addf2cbb120346ae42e78fa739245a353db5edadChong Zhang ALOGE("[%s] Unable to configure for node (err %d)", 6470addf2cbb120346ae42e78fa739245a353db5edadChong Zhang mCodec->mComponentName.c_str(), err); 6471addf2cbb120346ae42e78fa739245a353db5edadChong Zhang return err; 6472addf2cbb120346ae42e78fa739245a353db5edadChong Zhang } 6473a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 6474d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mCodec->mRepeatFrameDelayUs > 0ll) { 64756d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang err = statusFromBinderStatus( 64766d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs( 64776d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mRepeatFrameDelayUs)); 6478a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 6479a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (err != OK) { 6480a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGE("[%s] Unable to configure option to repeat previous " 6481a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber "frames (err %d)", 64826d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mComponentName.c_str(), err); 6483d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return err; 6484a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 6485a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 6486a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 6487d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mCodec->mMaxPtsGapUs > 0ll) { 64883604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang OMX_PARAM_U32TYPE maxPtsGapParams; 64893604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang InitOMXParams(&maxPtsGapParams); 64903604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang maxPtsGapParams.nPortIndex = kPortIndexInput; 64913604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs; 64923604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang 64933604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang err = mCodec->mOMXNode->setParameter( 64943604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl, 64953604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang &maxPtsGapParams, sizeof(maxPtsGapParams)); 649694ee4b708acfa941581160b267afb79192b1d816Chong Zhang 649794ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (err != OK) { 649894ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 64996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mComponentName.c_str(), err); 6500d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return err; 65012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 65022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 65032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 6504d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mCodec->mMaxFps > 0) { 65056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang err = statusFromBinderStatus( 65066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps)); 650737b2b389139ed638831e49708c947863eef631efRonghua Wu 650837b2b389139ed638831e49708c947863eef631efRonghua Wu if (err != OK) { 650937b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGE("[%s] Unable to configure max fps (err %d)", 65106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mComponentName.c_str(), err); 6511d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return err; 651237b2b389139ed638831e49708c947863eef631efRonghua Wu } 651337b2b389139ed638831e49708c947863eef631efRonghua Wu } 651437b2b389139ed638831e49708c947863eef631efRonghua Wu 6515d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mCodec->mTimePerCaptureUs > 0ll 65162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang && mCodec->mTimePerFrameUs > 0ll) { 65176d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang err = statusFromBinderStatus( 65186d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mGraphicBufferSource->setTimeLapseConfig( 65196d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mTimePerFrameUs, mCodec->mTimePerCaptureUs)); 65202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 65212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (err != OK) { 65222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGE("[%s] Unable to configure time lapse (err %d)", 65236d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mComponentName.c_str(), err); 6524d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return err; 65252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 65262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 652772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6528d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mCodec->mCreateInputBuffersSuspended) { 65296d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang err = statusFromBinderStatus( 65306d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mGraphicBufferSource->setSuspend(true)); 653172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 653272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 653372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("[%s] Unable to configure option to suspend (err %d)", 65346d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mComponentName.c_str(), err); 6535d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return err; 653694ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 653794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 653894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 6539c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar uint32_t usageBits; 6540d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (mCodec->mOMXNode->getParameter( 6541d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 6542c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar &usageBits, sizeof(usageBits)) == OK) { 6543c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mCodec->mInputFormat->setInt32( 6544c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 6545c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 6546c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 6547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar sp<ABuffer> colorAspectsBuffer; 6548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) { 65496d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang if (colorAspectsBuffer->size() != sizeof(ColorAspects)) { 65506d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang return INVALID_OPERATION; 65516d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang } 65526d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang 65536d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang err = statusFromBinderStatus( 65546d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32( 65556d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang *(ColorAspects *)colorAspectsBuffer->base()))); 65566d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang 6557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err != OK) { 6558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGE("[%s] Unable to configure color aspects (err %d)", 6559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mCodec->mComponentName.c_str(), err); 6560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar return err; 6561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 6562b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 6563d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return OK; 6564d291c222357303b9611cab89d0c3b047584ef377Chong Zhang} 6565d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6566d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface( 6567d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<AMessage> & /* msg */) { 6568d291c222357303b9611cab89d0c3b047584ef377Chong Zhang ALOGV("onCreateInputSurface"); 6569d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6570d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<AMessage> notify = mCodec->mNotify->dup(); 6571d291c222357303b9611cab89d0c3b047584ef377Chong Zhang notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated); 6572d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6573d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<IGraphicBufferProducer> bufferProducer; 6574addf2cbb120346ae42e78fa739245a353db5edadChong Zhang status_t err = mCodec->mOMX->createInputSurface( 6575addf2cbb120346ae42e78fa739245a353db5edadChong Zhang &bufferProducer, &mCodec->mGraphicBufferSource); 6576d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6577d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (err == OK) { 6578d291c222357303b9611cab89d0c3b047584ef377Chong Zhang err = setupInputSurface(); 6579d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 6580d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 65817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (err == OK) { 6582addf2cbb120346ae42e78fa739245a353db5edadChong Zhang notify->setMessage("input-format", mCodec->mInputFormat); 6583addf2cbb120346ae42e78fa739245a353db5edadChong Zhang notify->setMessage("output-format", mCodec->mOutputFormat); 6584addf2cbb120346ae42e78fa739245a353db5edadChong Zhang 65857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden notify->setObject("input-surface", 65867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden new BufferProducerWrapper(bufferProducer)); 65877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 65887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // Can't use mCodec->signalError() here -- MediaCodec won't forward 65897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // the error through because it's in the "configured" state. We 65907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // send a kWhatInputSurfaceCreated with an error value instead. 65917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGE("[%s] onCreateInputSurface returning error %d", 65927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->mComponentName.c_str(), err); 65937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden notify->setInt32("err", err); 65947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 65957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden notify->post(); 65967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 65977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 65988f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface( 6599d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<AMessage> &msg) { 66008f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang ALOGV("onSetInputSurface"); 6601d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6602d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<AMessage> notify = mCodec->mNotify->dup(); 6603d291c222357303b9611cab89d0c3b047584ef377Chong Zhang notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted); 6604d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6605d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<RefBase> obj; 6606d291c222357303b9611cab89d0c3b047584ef377Chong Zhang CHECK(msg->findObject("input-surface", &obj)); 6607d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 6608addf2cbb120346ae42e78fa739245a353db5edadChong Zhang mCodec->mGraphicBufferSource = surface->getBufferSource(); 6609d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6610addf2cbb120346ae42e78fa739245a353db5edadChong Zhang status_t err = setupInputSurface(); 6611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 6612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 6613addf2cbb120346ae42e78fa739245a353db5edadChong Zhang notify->setMessage("input-format", mCodec->mInputFormat); 6614addf2cbb120346ae42e78fa739245a353db5edadChong Zhang notify->setMessage("output-format", mCodec->mOutputFormat); 6615addf2cbb120346ae42e78fa739245a353db5edadChong Zhang } else { 6616d291c222357303b9611cab89d0c3b047584ef377Chong Zhang // Can't use mCodec->signalError() here -- MediaCodec won't forward 6617d291c222357303b9611cab89d0c3b047584ef377Chong Zhang // the error through because it's in the "configured" state. We 6618d291c222357303b9611cab89d0c3b047584ef377Chong Zhang // send a kWhatInputSurfaceAccepted with an error value instead. 66198f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang ALOGE("[%s] onSetInputSurface returning error %d", 6620d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mCodec->mComponentName.c_str(), err); 6621d291c222357303b9611cab89d0c3b047584ef377Chong Zhang notify->setInt32("err", err); 6622d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 6623d291c222357303b9611cab89d0c3b047584ef377Chong Zhang notify->post(); 6624d291c222357303b9611cab89d0c3b047584ef377Chong Zhang} 6625d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 6626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() { 66275778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("onStart"); 66285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6629d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); 66300806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 66310806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 66320806340688c937e7b78c2d89db3809274130df4eLajos Molnar } else { 66330806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->changeState(mCodec->mLoadedToIdleState); 66340806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 6638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6639f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 6640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : BaseState(codec) { 6641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6643f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() { 66443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 6645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6646cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber status_t err; 6647cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if ((err = allocateBuffers()) != OK) { 664829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to allocate buffers after transitioning to IDLE state " 6649cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber "(error 0x%08x)", 6650cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber err); 6651cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 6652251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 665391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber 6654d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang mCodec->mOMXNode->sendCommand( 6655d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_CommandStateSet, OMX_StateLoaded); 6656c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) { 6657c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia mCodec->freeBuffersOnPort(kPortIndexInput); 6658c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia } 6659c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) { 6660c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia mCodec->freeBuffersOnPort(kPortIndexOutput); 6661c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia } 6662c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia 666391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber mCodec->changeState(mCodec->mLoadedState); 6664cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 6665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6667f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() { 6668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 6669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 6671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 6672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return mCodec->allocateBuffersOnPort(kPortIndexOutput); 6675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6677f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 667972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatSetParameters: 6680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatShutdown: 6681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->deferMessage(msg); 6683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 6684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 66866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden case kWhatSignalEndOfInputStream: 66876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden { 66886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mCodec->onSignalEndOfInputStream(); 66896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden return true; 66906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden } 66916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 66926463e76d41430f9b03a79b221de84255f2475658Marco Nelissen case kWhatResume: 66936463e76d41430f9b03a79b221de84255f2475658Marco Nelissen { 66946463e76d41430f9b03a79b221de84255f2475658Marco Nelissen // We'll be active soon enough. 66956463e76d41430f9b03a79b221de84255f2475658Marco Nelissen return true; 66966463e76d41430f9b03a79b221de84255f2475658Marco Nelissen } 66976463e76d41430f9b03a79b221de84255f2475658Marco Nelissen 66986463e76d41430f9b03a79b221de84255f2475658Marco Nelissen case kWhatFlush: 66996463e76d41430f9b03a79b221de84255f2475658Marco Nelissen { 67006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen // We haven't even started yet, so we're flushed alright... 67016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen sp<AMessage> notify = mCodec->mNotify->dup(); 6702d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatFlushCompleted); 67036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen notify->post(); 67046463e76d41430f9b03a79b221de84255f2475658Marco Nelissen return true; 67056463e76d41430f9b03a79b221de84255f2475658Marco Nelissen } 67066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen 6707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 6708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onMessageReceived(msg); 6709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6712f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent( 6713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (event) { 6715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventCmdComplete: 6716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 67170806340688c937e7b78c2d89db3809274130df4eLajos Molnar status_t err = OK; 67180806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (data1 != (OMX_U32)OMX_CommandStateSet 67190806340688c937e7b78c2d89db3809274130df4eLajos Molnar || data2 != (OMX_U32)OMX_StateIdle) { 67200806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 67210806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_COMMANDTYPE)data1), data1, 67220806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_STATETYPE)data2), data2); 67230806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = FAILED_TRANSACTION; 67240806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 67260806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err == OK) { 6727d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mCodec->mOMXNode->sendCommand( 6728d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_CommandStateSet, OMX_StateExecuting); 67290806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 67310806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 67320806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 67330806340688c937e7b78c2d89db3809274130df4eLajos Molnar } else { 67340806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->changeState(mCodec->mIdleToExecutingState); 67350806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 6738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 6741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onOMXEvent(event, data1, data2); 6742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 6746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6747f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 6748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : BaseState(codec) { 6749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6751f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() { 67523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 6753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6755f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 675772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatSetParameters: 6758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatShutdown: 6759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->deferMessage(msg); 6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 6762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6764d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber case kWhatResume: 6765d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber { 6766d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber // We'll be active soon enough. 6767d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber return true; 6768d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber } 6769d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber 6770d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber case kWhatFlush: 6771d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber { 6772d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber // We haven't even started yet, so we're flushed alright... 6773d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 6774d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6775d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber notify->post(); 6776d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber 6777d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber return true; 6778d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber } 6779d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber 67806507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden case kWhatSignalEndOfInputStream: 67816507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden { 67826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mCodec->onSignalEndOfInputStream(); 67836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden return true; 67846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden } 67856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 6786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 6787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onMessageReceived(msg); 6788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6791f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent( 6792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (event) { 6794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventCmdComplete: 6795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 67960806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (data1 != (OMX_U32)OMX_CommandStateSet 67970806340688c937e7b78c2d89db3809274130df4eLajos Molnar || data2 != (OMX_U32)OMX_StateExecuting) { 67980806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 67990806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_COMMANDTYPE)data1), data1, 68000806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_STATETYPE)data2), data2); 68010806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 68020806340688c937e7b78c2d89db3809274130df4eLajos Molnar return true; 68030806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mExecutingState->resume(); 6806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->changeState(mCodec->mExecutingState); 6807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 6809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 6812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onOMXEvent(event, data1, data2); 6813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 6817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6818f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec) 6819349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber : BaseState(codec), 6820349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mActive(false) { 6821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6823f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 6824ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber OMX_U32 /* portIndex */) { 6825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return RESUBMIT_BUFFERS; 6826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() { 6829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // submit as many buffers as there are input buffers with the codec 6830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // in case we are in port reconfiguring 6831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 6832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 6834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 6835054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (mCodec->submitOutputMetadataBuffer() != OK) 6836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar break; 6837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 6838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 68394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar 68404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6841054219874873b41f1c815552987c10465c34ba2bLajos Molnar mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 6843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 6844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() { 68450806340688c937e7b78c2d89db3809274130df4eLajos Molnar bool failed = false; 6846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 6847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 6848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCodec->mNativeWindow != NULL) { 68500806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (info->mStatus != BufferInfo::OWNED_BY_US 68510806340688c937e7b78c2d89db3809274130df4eLajos Molnar && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 68520806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("buffers should be owned by us or the surface"); 68530806340688c937e7b78c2d89db3809274130df4eLajos Molnar failed = true; 68540806340688c937e7b78c2d89db3809274130df4eLajos Molnar break; 68550806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber continue; 6859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 68610806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (info->mStatus != BufferInfo::OWNED_BY_US) { 68620806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("buffers should be owned by us"); 68630806340688c937e7b78c2d89db3809274130df4eLajos Molnar failed = true; 68640806340688c937e7b78c2d89db3809274130df4eLajos Molnar break; 68650806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 68680806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 6869349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 687015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar info->checkWriteFence("submitRegularOutputBuffers"); 68713fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang status_t err = mCodec->fillBuffer(info); 68720806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 68730806340688c937e7b78c2d89db3809274130df4eLajos Molnar failed = true; 68740806340688c937e7b78c2d89db3809274130df4eLajos Molnar break; 68750806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 68770806340688c937e7b78c2d89db3809274130df4eLajos Molnar 68780806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (failed) { 68790806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 68800806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() { 6884c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar submitRegularOutputBuffers(); 6885054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (mCodec->storingMetadataInDecodedBuffers()) { 6886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar submitOutputMetaBuffers(); 6887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 6888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 6889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 6890f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() { 6891349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber if (mActive) { 68920806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 6893349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber return; 6894349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } 6895349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 6896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber submitOutputBuffers(); 6897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 68983cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar // Post all available input buffers 6899777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 6900777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 6901777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 6902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim 69033cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 69043cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 69053cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar if (info->mStatus == BufferInfo::OWNED_BY_US) { 69063cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar postFillThisBuffer(info); 69073cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar } 69083cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar } 6909349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 6910349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mActive = true; 6911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6913f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() { 69143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 6915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 691690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 6917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->processDeferredMessages(); 6918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 6919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6920f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool handled = false; 6922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 6924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatShutdown: 6925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6926c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber int32_t keepComponentAllocated; 6927c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK(msg->findInt32( 6928c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber "keepComponentAllocated", &keepComponentAllocated)); 6929c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6930c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCodec->mShutdownInProgress = true; 693154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar mCodec->mExplicitShutdown = true; 6932c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCodec->mKeepComponentAllocated = keepComponentAllocated; 6933c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 6934349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mActive = false; 6935349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 6936d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mCodec->mOMXNode->sendCommand( 6937d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_CommandStateSet, OMX_StateIdle); 69380806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 69390806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (keepComponentAllocated) { 69400806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 69410806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 69420806340688c937e7b78c2d89db3809274130df4eLajos Molnar // TODO: do some recovery here. 69430806340688c937e7b78c2d89db3809274130df4eLajos Molnar } else { 69440806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->changeState(mCodec->mExecutingToIdleState); 69450806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 6948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 6949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 6952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 69537a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong ALOGV("[%s] ExecutingState flushing now " 6954ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar "(codec owns %zu/%zu input, %zu/%zu output).", 6955d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber mCodec->mComponentName.c_str(), 6956d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber mCodec->countBuffersOwnedByComponent(kPortIndexInput), 6957d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber mCodec->mBuffers[kPortIndexInput].size(), 6958d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 6959d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber mCodec->mBuffers[kPortIndexOutput].size()); 6960d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 6961349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mActive = false; 6962349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 6963d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL); 69640806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 69650806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 69660806340688c937e7b78c2d89db3809274130df4eLajos Molnar } else { 69670806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->changeState(mCodec->mFlushingState); 69680806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 6969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 6971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 6972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatResume: 6975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 6976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber resume(); 6977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 6979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 6980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6982496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 6983496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 6984496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber status_t err = mCodec->requestIDRFrame(); 6985496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (err != OK) { 6986496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber ALOGW("Requesting an IDR frame failed."); 6987496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 6988496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 6989496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber handled = true; 6990496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 6991496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 6992496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 6993a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber case kWhatSetParameters: 6994a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber { 6995a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> params; 6996a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->findMessage("params", ¶ms)); 6997a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 6998a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber status_t err = mCodec->setParameters(params); 6999a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 7000a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> reply; 7001a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber if (msg->findMessage("reply", &reply)) { 7002a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber reply->setInt32("err", err); 7003a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber reply->post(); 7004a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 7005a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 7006a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber handled = true; 7007a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber break; 7008a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 7009a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 70107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case ACodec::kWhatSignalEndOfInputStream: 70117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 70126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mCodec->onSignalEndOfInputStream(); 70137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden handled = true; 70147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 70157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 70167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 70174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 7018054219874873b41f1c815552987c10465c34ba2bLajos Molnar case kWhatSubmitOutputMetadataBufferIfEOS: 70194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar { 70204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar if (mCodec->mPortEOS[kPortIndexInput] && 70214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar !mCodec->mPortEOS[kPortIndexOutput]) { 7022054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mCodec->submitOutputMetadataBuffer(); 70234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar if (err == OK) { 7024054219874873b41f1c815552987c10465c34ba2bLajos Molnar mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 70254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar } 70264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar } 70274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar return true; 70284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar } 70294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar 7030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = BaseState::onMessageReceived(msg); 7032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return handled; 7036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7038a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> ¶ms) { 7039a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber int32_t videoBitrate; 7040530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar if (params->findInt32("video-bitrate", &videoBitrate)) { 7041a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber OMX_VIDEO_CONFIG_BITRATETYPE configParams; 7042a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber InitOMXParams(&configParams); 7043a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber configParams.nPortIndex = kPortIndexOutput; 7044a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber configParams.nEncodeBitrate = videoBitrate; 7045a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 7046d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mOMXNode->setConfig( 7047a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber OMX_IndexConfigVideoBitrate, 7048a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber &configParams, 7049a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sizeof(configParams)); 7050a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 7051a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber if (err != OK) { 7052a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 7053a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber videoBitrate, err); 7054a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 7055a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return err; 7056a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 7057a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 7058a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 705961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang int64_t timeOffsetUs; 706061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (params->findInt64("time-offset-us", &timeOffsetUs)) { 70616d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang if (mGraphicBufferSource == NULL) { 70626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang ALOGE("[%s] Invalid to set input buffer time offset without surface", 70636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mComponentName.c_str()); 70646d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang return INVALID_OPERATION; 70656d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang } 70666d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang 70676d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang status_t err = statusFromBinderStatus( 70686d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs)); 706961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 707061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (err != OK) { 707161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang ALOGE("[%s] Unable to set input buffer time offset (err %d)", 707261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang mComponentName.c_str(), 707361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang err); 707461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang return err; 707561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 707661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 707761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 707872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t skipFramesBeforeUs; 707972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 70806d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang if (mGraphicBufferSource == NULL) { 70816d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang ALOGE("[%s] Invalid to set start time without surface", 70826d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mComponentName.c_str()); 70836d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang return INVALID_OPERATION; 70846d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang } 70856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang 70866d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang status_t err = statusFromBinderStatus( 70876d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs)); 708872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 708972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 709072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 709172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 709272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 709372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 709472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7095e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber int32_t dropInputFrames; 7096e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (params->findInt32("drop-input-frames", &dropInputFrames)) { 70976d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang if (mGraphicBufferSource == NULL) { 70986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang ALOGE("[%s] Invalid to set suspend without surface", 70996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mComponentName.c_str()); 71006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang return INVALID_OPERATION; 71016d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang } 7102e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 71036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang status_t err = statusFromBinderStatus( 71046d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang mGraphicBufferSource->setSuspend(dropInputFrames != 0)); 7105b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber 7106b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber if (err != OK) { 7107b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 7108b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber return err; 7109b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber } 7110b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber } 7111b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber 7112b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber int32_t dummy; 7113b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber if (params->findInt32("request-sync", &dummy)) { 7114b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber status_t err = requestIDRFrame(); 7115b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber 7116b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber if (err != OK) { 7117b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber ALOGE("Requesting a sync frame failed w/ err %d", err); 7118b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber return err; 7119b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber } 7120e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 7121e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 71228db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu float rate; 71238db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu if (params->findFloat("operating-rate", &rate) && rate > 0) { 71248db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu status_t err = setOperatingRate(rate, mIsVideo); 71258db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu if (err != OK) { 71268db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 71278db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu return err; 71288db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu } 71298db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu } 71308db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu 7131870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang int32_t intraRefreshPeriod = 0; 7132870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (params->findInt32("intra-refresh-period", &intraRefreshPeriod) 7133870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang && intraRefreshPeriod > 0) { 7134870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false); 7135870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang if (err != OK) { 7136870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional", 7137870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang mComponentName.c_str()); 7138870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang err = OK; 7139870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 7140870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang } 7141870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang 71420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat); 71430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar if (err != OK) { 71440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar err = OK; // ignore failure 71450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar } 71460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar 71470f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar return err; 7148a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 7149a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 71506507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() { 71516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden sp<AMessage> notify = mNotify->dup(); 7152d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatSignaledInputEOS); 71536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 71546d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang status_t err = INVALID_OPERATION; 71556d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang if (mGraphicBufferSource != NULL) { 71566d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream()); 71576d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang } 71586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden if (err != OK) { 71596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden notify->setInt32("err", err); 71606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden } 71616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden notify->post(); 71626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden} 71636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 716490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 716590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mCodec->onFrameRendered(mediaTimeUs, systemNano); 716690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar return true; 716790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar} 716890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 7169f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent( 7170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (event) { 7172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventPortSettingsChanged: 7173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 7175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7176b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar mCodec->onOutputFormatChanged(); 7177b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar 717831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 7179054219874873b41f1c815552987c10465c34ba2bLajos Molnar mCodec->mMetadataBuffersToSubmit = 0; 7180d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang CHECK_EQ(mCodec->mOMXNode->sendCommand( 7181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_CommandPortDisable, kPortIndexOutput), 7182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (status_t)OK); 7183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7184349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mCodec->freeOutputBuffersNotOwnedByComponent(); 7185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 7187b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar } else if (data2 != OMX_IndexConfigCommonOutputCrop 7188b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar && data2 != OMX_IndexConfigAndroidIntraRefresh) { 7189ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 7190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mComponentName.c_str(), data2); 7191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 7194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventBufferFlag: 7197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 7199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onOMXEvent(event, data1, data2); 7203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 7207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7208f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 7209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ACodec *codec) 7210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : BaseState(codec) { 7211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7213f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 7214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 portIndex) { 7215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexOutput) { 7216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return FREE_BUFFERS; 7217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 7220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return RESUBMIT_BUFFERS; 7222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7224f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived( 7225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> &msg) { 7226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool handled = false; 7227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 7229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 7230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatShutdown: 7231349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber case kWhatResume: 7232e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson case kWhatSetParameters: 7233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7234349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber if (msg->what() == kWhatResume) { 72353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 7236349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } 7237349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 7238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->deferMessage(msg); 7239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 7240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = BaseState::onMessageReceived(msg); 7245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return handled; 7249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7251f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() { 72523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Now handling output port settings change", 7253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mComponentName.c_str()); 7254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 725690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered( 725790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar int64_t mediaTimeUs, nsecs_t systemNano) { 725890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mCodec->onFrameRendered(mediaTimeUs, systemNano); 725990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar return true; 726090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar} 726190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 7262f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent( 7263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (event) { 7265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventCmdComplete: 7266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (data1 == (OMX_U32)OMX_CommandPortDisable) { 72680806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (data2 != (OMX_U32)kPortIndexOutput) { 72690806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 72700806340688c937e7b78c2d89db3809274130df4eLajos Molnar return false; 72710806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 7272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 72730806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 7274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 72750806340688c937e7b78c2d89db3809274130df4eLajos Molnar status_t err = OK; 72760806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 72770806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("disabled port should be empty, but has %zu buffers", 72780806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->mBuffers[kPortIndexOutput].size()); 72790806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = FAILED_TRANSACTION; 72800806340688c937e7b78c2d89db3809274130df4eLajos Molnar } else { 72810806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->mDealer[kPortIndexOutput].clear(); 72820806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 7283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 72840806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err == OK) { 7285d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = mCodec->mOMXNode->sendCommand( 7286d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_CommandPortEnable, kPortIndexOutput); 72870806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 7288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 72890806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err == OK) { 72900806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 72910806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 72920806340688c937e7b78c2d89db3809274130df4eLajos Molnar "reconfiguration: (%d)", err); 72930806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 7294cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 72950806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 7296251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 7297d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 7298755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber // This is technically not correct, but appears to be 7299755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber // the only way to free the component instance. 7300755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber // Controlled transitioning from excecuting->idle 7301755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber // and idle->loaded seem impossible probably because 7302755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber // the output port never finishes re-enabling. 7303755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber mCodec->mShutdownInProgress = true; 7304755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber mCodec->mKeepComponentAllocated = false; 7305755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber mCodec->changeState(mCodec->mLoadedState); 7306cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 7307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 7309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 7310777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (data2 != (OMX_U32)kPortIndexOutput) { 7311777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 7312777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return false; 7313777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 7314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 73150806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 7316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber if (mCodec->mExecutingState->active()) { 7318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mCodec->mExecutingState->submitOutputBuffers(); 7319349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } 7320349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 7321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->changeState(mCodec->mExecutingState); 7322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 7324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 7327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 7331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 7335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7336f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 73375778822d86b0337407514b9372562b86edfa91cdAndreas Huber : BaseState(codec), 73385778822d86b0337407514b9372562b86edfa91cdAndreas Huber mComponentNowIdle(false) { 7339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7341f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 7342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool handled = false; 7343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 7345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 7346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Don't send me a flush request if you previously wanted me 7348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // to shutdown. 73490806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGW("Ignoring flush request in ExecutingToIdleState"); 7350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatShutdown: 7354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7355349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang mCodec->deferMessage(msg); 7356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 7357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = BaseState::onMessageReceived(msg); 7362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return handled; 7366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7368f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() { 73693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 737031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 73715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mComponentNowIdle = false; 7372b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar mCodec->mLastOutputFormat.clear(); 7373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7375f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent( 7376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (event) { 7378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventCmdComplete: 7379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 73800806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (data1 != (OMX_U32)OMX_CommandStateSet 73810806340688c937e7b78c2d89db3809274130df4eLajos Molnar || data2 != (OMX_U32)OMX_StateIdle) { 73820806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 73830806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_COMMANDTYPE)data1), data1, 73840806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_STATETYPE)data2), data2); 73850806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 73860806340688c937e7b78c2d89db3809274130df4eLajos Molnar return true; 73870806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 7388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 73895778822d86b0337407514b9372562b86edfa91cdAndreas Huber mComponentNowIdle = true; 73905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber changeStateIfWeOwnAllBuffers(); 7392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7396349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber case OMX_EventPortSettingsChanged: 7397349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber case OMX_EventBufferFlag: 7398349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { 7399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber // We're shutting down and don't care about this anymore. 7400349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber return true; 7401349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } 7402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 7403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onOMXEvent(event, data1, data2); 7405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 74070af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber 7408f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 74095778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 7410d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = mCodec->mOMXNode->sendCommand( 7411d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_CommandStateSet, OMX_StateLoaded); 74120806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err == OK) { 74130806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = mCodec->freeBuffersOnPort(kPortIndexInput); 74140806340688c937e7b78c2d89db3809274130df4eLajos Molnar status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 74150806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err == OK) { 74160806340688c937e7b78c2d89db3809274130df4eLajos Molnar err = err2; 74170806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 74180806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 7419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 74200167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 74210167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber && mCodec->mNativeWindow != NULL) { 7422bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber // We push enough 1x1 blank buffers to ensure that one of 7423bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber // them has made it to the display. This allows the OMX 7424bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber // component teardown to zero out any protected buffers 7425bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber // without the risk of scanning out one of those buffers. 7426b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 7427bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } 7428bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber 74290806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (err != OK) { 74300806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 74310806340688c937e7b78c2d89db3809274130df4eLajos Molnar return; 74320806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 74330806340688c937e7b78c2d89db3809274130df4eLajos Molnar 7434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->changeState(mCodec->mIdleToLoadedState); 7435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7438f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled( 7439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> &msg) { 7440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BaseState::onInputBufferFilled(msg); 7441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber changeStateIfWeOwnAllBuffers(); 7443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7445f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained( 7446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> &msg) { 7447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BaseState::onOutputBufferDrained(msg); 7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber changeStateIfWeOwnAllBuffers(); 7450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 7453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7454f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 7455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : BaseState(codec) { 7456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7458f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 7459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool handled = false; 7460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 7462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatShutdown: 7463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7464349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang mCodec->deferMessage(msg); 7465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 7466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 7470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Don't send me a flush request if you previously wanted me 7472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // to shutdown. 74730806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Got flush request in IdleToLoadedState"); 7474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = BaseState::onMessageReceived(msg); 7479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return handled; 7483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7485f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() { 74863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 7487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7489f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent( 7490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (event) { 7492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventCmdComplete: 7493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 74940806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (data1 != (OMX_U32)OMX_CommandStateSet 74950806340688c937e7b78c2d89db3809274130df4eLajos Molnar || data2 != (OMX_U32)OMX_StateLoaded) { 74960806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 74970806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_COMMANDTYPE)data1), data1, 74980806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_STATETYPE)data2), data2); 74990806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 75000806340688c937e7b78c2d89db3809274130df4eLajos Molnar return true; 75010806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 7502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCodec->changeState(mCodec->mLoadedState); 7504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 7506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onOMXEvent(event, data1, data2); 7510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 7514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7515f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec) 7516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : BaseState(codec) { 7517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7519f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() { 75203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 7521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 7523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7525f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 7526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool handled = false; 7527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 7529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatShutdown: 7530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->deferMessage(msg); 7532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 7536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 7537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // We're already doing this right now. 7538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = true; 7539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber handled = BaseState::onMessageReceived(msg); 7544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 7545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return handled; 7548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7550f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent( 7551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7552ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 7553ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 7554d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 7555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (event) { 7556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventCmdComplete: 7557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 75580806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (data1 != (OMX_U32)OMX_CommandFlush) { 75590806340688c937e7b78c2d89db3809274130df4eLajos Molnar ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 75600806340688c937e7b78c2d89db3809274130df4eLajos Molnar asString((OMX_COMMANDTYPE)data1), data1, data2); 75610806340688c937e7b78c2d89db3809274130df4eLajos Molnar mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 75620806340688c937e7b78c2d89db3809274130df4eLajos Molnar return true; 75630806340688c937e7b78c2d89db3809274130df4eLajos Molnar } 7564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 7566777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (mFlushComplete[data2]) { 7567777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGW("Flush already completed for %s port", 7568777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim data2 == kPortIndexInput ? "input" : "output"); 7569777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return true; 7570777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 7571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushComplete[data2] = true; 7572e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber 75730806340688c937e7b78c2d89db3809274130df4eLajos Molnar if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 7574e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber changeStateIfWeOwnAllBuffers(); 7575e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber } 7576777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } else if (data2 == OMX_ALL) { 7577777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 7578777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGW("received flush complete event for OMX_ALL before ports have been" 7579777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim "flushed (%d/%d)", 7580777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 7581777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim return false; 7582777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } 7583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber changeStateIfWeOwnAllBuffers(); 7585777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim } else { 7586777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 7587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 7590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7592349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber case OMX_EventPortSettingsChanged: 7593349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { 75941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 7595349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber msg->setInt32("type", omx_message::EVENT); 7596d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang msg->setInt32("generation", mCodec->mNodeGeneration); 7597349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber msg->setInt32("event", event); 7598349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber msg->setInt32("data1", data1); 7599349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber msg->setInt32("data2", data2); 7600349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 76013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 7602349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mCodec->mComponentName.c_str()); 7603349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 7604349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mCodec->deferMessage(msg); 7605349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 7606349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber return true; 7607349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } 7608349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 7609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 7610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BaseState::onOMXEvent(event, data1, data2); 7611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 7614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7616f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 7617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BaseState::onOutputBufferDrained(msg); 7618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber changeStateIfWeOwnAllBuffers(); 7620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7622f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 7623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BaseState::onInputBufferFilled(msg); 7624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber changeStateIfWeOwnAllBuffers(); 7626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7628f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 7629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mFlushComplete[kPortIndexInput] 7630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && mFlushComplete[kPortIndexOutput] 7631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && mCodec->allYourBuffersAreBelongToUs()) { 76327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber // We now own all buffers except possibly those still queued with 76337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber // the native window for rendering. Let's get those back as well. 76347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 76357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber 763690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 763790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 7638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mCodec->mNotify->dup(); 7639d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar notify->setInt32("what", CodecBase::kWhatFlushCompleted); 7640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 7641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mPortEOS[kPortIndexInput] = 7643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->mPortEOS[kPortIndexOutput] = false; 7644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7645dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mCodec->mInputEOSResult = OK; 7646dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber 7647f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen if (mCodec->mSkipCutBuffer != NULL) { 7648f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen mCodec->mSkipCutBuffer->clear(); 7649f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen } 7650f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen 7651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->changeState(mCodec->mExecutingState); 7652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 7654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 76555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities( 76565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar const AString &name, const AString &mime, bool isEncoder, 76575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar sp<MediaCodecInfo::Capabilities> *caps) { 76585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar (*caps).clear(); 76591ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim const char *role = GetComponentRole(isEncoder, mime.c_str()); 76605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (role == NULL) { 76615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return BAD_VALUE; 76625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 76635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 76645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar OMXClient client; 76655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar status_t err = client.connect(); 76665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (err != OK) { 76675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return err; 76685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 76695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 76705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar sp<IOMX> omx = client.interface(); 76715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar sp<CodecObserver> observer = new CodecObserver; 7672d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang sp<IOMXNode> omxNode; 76735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 76741d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang err = omx->allocateNode(name.c_str(), observer, &omxNode); 76755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (err != OK) { 76765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar client.disconnect(); 76775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return err; 76785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 76795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 7680d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang err = SetComponentRole(omxNode, role); 76815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (err != OK) { 7682d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang omxNode->freeNode(); 76835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar client.disconnect(); 76845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return err; 76855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 76865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 76875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder(); 76885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar bool isVideo = mime.startsWithIgnoreCase("video/"); 76895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 76905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (isVideo) { 76915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 76925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar InitOMXParams(¶m); 76935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 76945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 76956e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 76966e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar param.nProfileIndex = index; 7697d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = omxNode->getParameter( 7698d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoProfileLevelQuerySupported, 76995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar ¶m, sizeof(param)); 77005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (err != OK) { 77015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar break; 77025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar builder->addProfileLevel(param.eProfile, param.eLevel); 77046e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar 77056e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar if (index == kMaxIndicesToCheck) { 77066e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar ALOGW("[%s] stopping checking profiles after %u: %x/%x", 77076e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar name.c_str(), index, 77086e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar param.eProfile, param.eLevel); 77096e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar } 77105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 77125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // Color format query 77135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // return colors in the order reported by the OMX component 77145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // prefix "flexible" standard ones with the flexible equivalent 77155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 77165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar InitOMXParams(&portFormat); 771736e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput; 77185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar Vector<uint32_t> supportedColors; // shadow copy to check for duplicates 77196e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 77206e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar portFormat.nIndex = index; 7721d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = omxNode->getParameter( 7722d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang OMX_IndexParamVideoPortFormat, 77235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar &portFormat, sizeof(portFormat)); 77245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (err != OK) { 77255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar break; 77265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 77285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar OMX_U32 flexibleEquivalent; 77291ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim if (IsFlexibleColorFormat( 7730d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang omxNode, portFormat.eColorFormat, false /* usingNativeWindow */, 77315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar &flexibleEquivalent)) { 77325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar bool marked = false; 77335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar for (size_t i = 0; i < supportedColors.size(); ++i) { 77345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (supportedColors[i] == flexibleEquivalent) { 77355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar marked = true; 77365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar break; 77375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (!marked) { 77405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar supportedColors.push(flexibleEquivalent); 77415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar builder->addColorFormat(flexibleEquivalent); 77425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar supportedColors.push(portFormat.eColorFormat); 77455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar builder->addColorFormat(portFormat.eColorFormat); 77466e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar 77476e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar if (index == kMaxIndicesToCheck) { 77486e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar ALOGW("[%s] stopping checking formats after %u: %s(%x)", 77496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar name.c_str(), index, 77506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar asString(portFormat.eColorFormat), portFormat.eColorFormat); 77516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar } 77525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) { 77545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // More audio codecs if they have profiles. 77555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param; 77565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar InitOMXParams(¶m); 77575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 77586e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 77596e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar param.nProfileIndex = index; 7760d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang status_t err = omxNode->getParameter( 7761d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported, 77625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar ¶m, sizeof(param)); 77635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (err != OK) { 77645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar break; 77655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // For audio, level is ignored. 77675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar builder->addProfileLevel(param.eProfile, 0 /* level */); 77686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar 77696e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar if (index == kMaxIndicesToCheck) { 77706e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar ALOGW("[%s] stopping checking profiles after %u: %x", 77716e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar name.c_str(), index, 77726e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar param.eProfile); 77736e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar } 77745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 77765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // NOTE: Without Android extensions, OMX does not provide a way to query 77775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // AAC profile support 77785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (param.nProfileIndex == 0) { 77795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar ALOGW("component %s doesn't support profile query.", name.c_str()); 77805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 77835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (isVideo && !isEncoder) { 77845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar native_handle_t *sidebandHandle = NULL; 7785d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (omxNode->configureVideoTunnelMode( 7786d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) { 77875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // tunneled playback includes adaptive playback 77885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback 77895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback); 7790d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang } else if (omxNode->setPortMode( 7791d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK || 7792d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang omxNode->prepareForAdaptivePlayback( 7793d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang kPortIndexOutput, OMX_TRUE, 77945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 1280 /* width */, 720 /* height */) == OK) { 77955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback); 77965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 77985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 77995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (isVideo && isEncoder) { 78005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 78015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar InitOMXParams(¶ms); 78025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar params.nPortIndex = kPortIndexOutput; 78035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // TODO: should we verify if fallback is supported? 7804d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang if (omxNode->getConfig( 7805d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, 78065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar ¶ms, sizeof(params)) == OK) { 78075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh); 78085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 78095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 78105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 78115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar *caps = builder; 7812d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang omxNode->freeNode(); 78135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar client.disconnect(); 78145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return OK; 78155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar} 78165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 7817a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in 7818a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count". 7819a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static 7820a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) { 7821a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar switch (numChannels) { 7822a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar case 1: 7823a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[0] = OMX_AUDIO_ChannelCF; 7824a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar break; 7825a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar case 2: 7826a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[0] = OMX_AUDIO_ChannelLF; 7827a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[1] = OMX_AUDIO_ChannelRF; 7828a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar break; 7829a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar case 3: 7830a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[0] = OMX_AUDIO_ChannelLF; 7831a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[1] = OMX_AUDIO_ChannelRF; 7832a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[2] = OMX_AUDIO_ChannelCF; 7833a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar break; 7834a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar case 4: 7835a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[0] = OMX_AUDIO_ChannelLF; 7836a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[1] = OMX_AUDIO_ChannelRF; 7837a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[2] = OMX_AUDIO_ChannelLR; 7838a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[3] = OMX_AUDIO_ChannelRR; 7839a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar break; 7840a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar case 5: 7841a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[0] = OMX_AUDIO_ChannelLF; 7842a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[1] = OMX_AUDIO_ChannelRF; 7843a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[2] = OMX_AUDIO_ChannelCF; 7844a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[3] = OMX_AUDIO_ChannelLR; 7845a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[4] = OMX_AUDIO_ChannelRR; 7846a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar break; 7847a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar case 6: 7848a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[0] = OMX_AUDIO_ChannelLF; 7849a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[1] = OMX_AUDIO_ChannelRF; 7850a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[2] = OMX_AUDIO_ChannelCF; 7851a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[3] = OMX_AUDIO_ChannelLFE; 7852a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[4] = OMX_AUDIO_ChannelLR; 7853a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[5] = OMX_AUDIO_ChannelRR; 7854a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar break; 7855a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar case 7: 7856a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[0] = OMX_AUDIO_ChannelLF; 7857a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[1] = OMX_AUDIO_ChannelRF; 7858a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[2] = OMX_AUDIO_ChannelCF; 7859a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[3] = OMX_AUDIO_ChannelLFE; 7860a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[4] = OMX_AUDIO_ChannelLR; 7861a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[5] = OMX_AUDIO_ChannelRR; 7862a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[6] = OMX_AUDIO_ChannelCS; 7863a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar break; 7864a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar case 8: 7865a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[0] = OMX_AUDIO_ChannelLF; 7866a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[1] = OMX_AUDIO_ChannelRF; 7867a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[2] = OMX_AUDIO_ChannelCF; 7868a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[3] = OMX_AUDIO_ChannelLFE; 7869a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[4] = OMX_AUDIO_ChannelLR; 7870a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[5] = OMX_AUDIO_ChannelRR; 7871a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[6] = OMX_AUDIO_ChannelLS; 7872a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar map[7] = OMX_AUDIO_ChannelRS; 7873a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar break; 7874a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar default: 7875a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar return -EINVAL; 7876a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar } 7877a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar 7878a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar return OK; 7879a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar} 7880a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar 7881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 7882