ACodec.cpp revision 98a421bfffe6b3a1b762d11740e90787bdfeac08
1d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright/* 2d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Copyright (C) 2010 The Android Open Source Project 3d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * 4d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Licensed under the Apache License, Version 2.0 (the "License"); 5d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * you may not use this file except in compliance with the License. 6d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * You may obtain a copy of the License at 7d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * 8d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * http://www.apache.org/licenses/LICENSE-2.0 9d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * 10d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Unless required by applicable law or agreed to in writing, software 11d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * distributed under the License is distributed on an "AS IS" BASIS, 12d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * See the License for the specific language governing permissions and 14d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * limitations under the License. 15d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright */ 16d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 17d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//#define LOG_NDEBUG 0 18d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define LOG_TAG "ACodec" 19d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 20d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#ifdef __LP64__ 21d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 22d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif 23d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 24d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <inttypes.h> 25d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <utils/Trace.h> 26d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 27d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <gui/Surface.h> 28d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 29d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/ACodec.h> 30d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 31d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <binder/MemoryDealer.h> 32d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 33d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/foundation/hexdump.h> 34d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/foundation/ABuffer.h> 35d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/foundation/ADebug.h> 36d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/foundation/AMessage.h> 37d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/foundation/AUtils.h> 38d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 39d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/BufferProducerWrapper.h> 40d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/MediaCodec.h> 41d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/MediaCodecList.h> 42d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/MediaDefs.h> 43d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/OMXClient.h> 44d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/OMXCodec.h> 45d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/PersistentSurface.h> 46d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/stagefright/SurfaceUtils.h> 47d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <media/hardware/HardwareAPI.h> 48d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 49d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <OMX_AudioExt.h> 50d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <OMX_VideoExt.h> 51d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <OMX_Component.h> 52d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <OMX_IndexExt.h> 53d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <OMX_AsString.h> 54d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 55d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include "include/avc_utils.h" 56d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 57d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightnamespace android { 58d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 59d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// OMX errors are directly mapped into status_t range if 60d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// there is no corresponding MediaError status code. 61d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Use the statusFromOMXError(int32_t omxError) function. 62d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// 63d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Currently this is a direct map. 64d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// See frameworks/native/include/media/openmax/OMX_Core.h 65d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// 66d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Vendor OMX errors from 0x90000000 - 0x9000FFFF 67d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Extension OMX errors from 0x8F000000 - 0x90000000 68d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Standard OMX errors from 0x80001000 - 0x80001024 (0x80001024 current) 69d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// 70d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 71d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// returns true if err is a recognized OMX error code. 72d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// as OMX error is OMX_S32, this is an int32_t type 73d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline bool isOMXError(int32_t err) { 74d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX); 75d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 76d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 77d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// converts an OMX error to a status_t 78d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline status_t statusFromOMXError(int32_t omxError) { 79d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (omxError) { 80d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_ErrorInvalidComponentName: 81d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_ErrorComponentNotFound: 82d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return NAME_NOT_FOUND; // can trigger illegal argument error for provided names. 83d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 84d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return isOMXError(omxError) ? omxError : 0; // no translation required 85d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 86d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 87d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 88d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// checks and converts status_t to a non-side-effect status_t 89d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline status_t makeNoSideEffectStatus(status_t err) { 90d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (err) { 91d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // the following errors have side effects and may come 92d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // from other code modules. Remap for safety reasons. 93d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case INVALID_OPERATION: 94d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case DEAD_OBJECT: 95d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return UNKNOWN_ERROR; 96d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 97d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 98d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 99d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrighttemplate<class T> 102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic void InitOMXParams(T *params) { 103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params->nSize = sizeof(T); 104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params->nVersion.s.nVersionMajor = 1; 105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params->nVersion.s.nVersionMinor = 0; 106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params->nVersion.s.nRevision = 0; 10739efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath params->nVersion.s.nStep = 0; 108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 11039efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamathstruct MessageList : public RefBase { 111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright MessageList() { 112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 11339efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath virtual ~MessageList() { 114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright std::list<sp<AMessage> > &getList() { return mList; } 11639efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamathprivate: 117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright std::list<sp<AMessage> > mList; 118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(MessageList); 120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct CodecObserver : public BnOMXObserver { 123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CodecObserver() {} 124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void setNotificationMessage(const sp<AMessage> &msg) { 126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNotify = msg; 127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // from IOMXObserver 130489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke virtual void onMessages(const std::list<omx_message> &messages) { 131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (messages.empty()) { 132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mNotify->dup(); 136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool first = true; 137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<MessageList> msgList = new MessageList(); 138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (std::list<omx_message>::const_iterator it = messages.cbegin(); 139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright it != messages.cend(); ++it) { 140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const omx_message &omx_msg = *it; 141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (first) { 142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("node", omx_msg.node); 143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright first = false; 144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> msg = new AMessage; 147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32("type", omx_msg.type); 148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (omx_msg.type) { 149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case omx_message::EVENT: 150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32("event", omx_msg.u.event_data.event); 152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32("data1", omx_msg.u.event_data.data1); 153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32("data2", omx_msg.u.event_data.data2); 154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case omx_message::EMPTY_BUFFER_DONE: 158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32("buffer", omx_msg.u.buffer_data.buffer); 160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32("fence_fd", omx_msg.fenceFd); 161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case omx_message::FILL_BUFFER_DONE: 165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32( 167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "buffer", omx_msg.u.extended_buffer_data.buffer); 168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32( 169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "range_offset", 170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright omx_msg.u.extended_buffer_data.range_offset); 171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32( 172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "range_length", 173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright omx_msg.u.extended_buffer_data.range_length); 174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32( 175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "flags", 17671b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke omx_msg.u.extended_buffer_data.flags); 17771b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke msg->setInt64( 178489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke "timestamp", 179489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke omx_msg.u.extended_buffer_data.timestamp); 180489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke msg->setInt32( 181489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke "fence_fd", omx_msg.fenceFd); 182489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke break; 18312d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke } 18412d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke 185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case omx_message::FRAME_RENDERED: 186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt64( 188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "media_time_us", omx_msg.u.render_data.timestamp); 189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt64( 190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "system_nano", omx_msg.u.render_data.nanoTime); 191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Unrecognized message type: %d", omx_msg.type); 196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 19839efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath msgList->getList().push_back(msg); 199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setObject("messages", msgList); 201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 20239efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath } 203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual ~CodecObserver() {} 206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> mNotify; 209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::BaseState : public AState { 216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright enum PortMode { 220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright KEEP_BUFFERS, 221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright RESUBMIT_BUFFERS, 222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright FREE_BUFFERS, 223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright }; 224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ACodec *mCodec; 226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual PortMode getPortMode(OMX_U32 portIndex); 228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void onOutputBufferDrained(const sp<AMessage> &msg); 234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void onInputBufferFilled(const sp<AMessage> &msg); 235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void postFillThisBuffer(BufferInfo *info); 237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Handles an OMX message. Returns true iff message was handled. 240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool onOMXMessage(const sp<AMessage> &msg); 241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Handles a list of messages. Returns true iff messages were handled. 243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool onOMXMessageList(const sp<AMessage> &msg); 244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // returns true iff this message is for this component and the component is alive 246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool checkOMXMessage(const sp<AMessage> &msg); 247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd); 249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool onOMXFillBufferDone( 251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::buffer_id bufferID, 252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t rangeOffset, size_t rangeLength, 253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 flags, 254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int64_t timeUs, 255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int fenceFd); 256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void getMoreInputDataIfPossible(); 260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(BaseState); 262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::DeathNotifier : public IBinder::DeathRecipient { 267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DeathNotifier(const sp<AMessage> ¬ify) 268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright : mNotify(notify) { 269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void binderDied(const wp<IBinder> &) { 272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNotify->post(); 273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual ~DeathNotifier() {} 277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> mNotify; 280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier); 282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::UninitializedState : public ACodec::BaseState { 285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright UninitializedState(ACodec *codec); 286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void onSetup(const sp<AMessage> &msg); 293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool onAllocateComponent(const sp<AMessage> &msg); 294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<DeathNotifier> mDeathNotifier; 296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); 298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::LoadedState : public ACodec::BaseState { 303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright LoadedState(ACodec *codec); 304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright friend struct ACodec::UninitializedState; 311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool onConfigureComponent(const sp<AMessage> &msg); 313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void onCreateInputSurface(const sp<AMessage> &msg); 314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void onSetInputSurface(const sp<AMessage> &msg); 315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void onStart(); 316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void onShutdown(bool keepComponentAllocated); 317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t setupInputSurface(); 319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(LoadedState); 321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::LoadedToIdleState : public ACodec::BaseState { 326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright LoadedToIdleState(ACodec *codec); 327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3286ca70efdaef8c07e91692101c7a3ae35dc1e0cbbChih-Hung Hsiehprotected: 329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t allocateBuffers(); 335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::IdleToExecutingState : public ACodec::BaseState { 342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IdleToExecutingState(ACodec *codec); 343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::ExecutingState : public ACodec::BaseState { 356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ExecutingState(ACodec *codec); 357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void submitRegularOutputBuffers(); 359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void submitOutputMetaBuffers(); 360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void submitOutputBuffers(); 361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Submit output buffers to the decoder, submit input buffers to client 363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // to fill with data. 364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void resume(); 365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Returns true iff input and output buffers are in play. 367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool active() const { return mActive; } 368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual PortMode getPortMode(OMX_U32 portIndex); 371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool mActive; 379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OutputPortSettingsChangedState(ACodec *codec); 387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual PortMode getPortMode(OMX_U32 portIndex); 390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::ExecutingToIdleState : public ACodec::BaseState { 403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ExecutingToIdleState(ACodec *codec); 404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void onOutputBufferDrained(const sp<AMessage> &msg); 412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void onInputBufferFilled(const sp<AMessage> &msg); 413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void changeStateIfWeOwnAllBuffers(); 416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool mComponentNowIdle; 418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::IdleToLoadedState : public ACodec::BaseState { 425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IdleToLoadedState(ACodec *codec); 426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstruct ACodec::FlushingState : public ACodec::BaseState { 440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright FlushingState(ACodec *codec); 441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected: 443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onMessageReceived(const sp<AMessage> &msg); 444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void stateEntered(); 445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void onOutputBufferDrained(const sp<AMessage> &msg); 449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright virtual void onInputBufferFilled(const sp<AMessage> &msg); 450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate: 452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool mFlushComplete[2]; 453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void changeStateIfWeOwnAllBuffers(); 455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) { 462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mFenceFd >= 0) { 463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s", 464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg); 465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mFenceFd = fenceFd; 467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIsReadFence = false; 468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) { 471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mFenceFd >= 0) { 472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s", 473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg); 474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mFenceFd = fenceFd; 476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIsReadFence = true; 477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) { 480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mFenceFd >= 0 && mIsReadFence) { 481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg); 482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 48439efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath 485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::BufferInfo::checkReadFence(const char *dbg) { 486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mFenceFd >= 0 && !mIsReadFence) { 487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg); 488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightACodec::ACodec() 494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright : mQuirks(0), 495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode(0), 496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindowUsageBits(0), 497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mSentFormat(false), 498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIsVideo(false), 499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIsEncoder(false), 500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mShutdownInProgress(false), 501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mExplicitShutdown(false), 502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mEncoderDelay(0), 503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mEncoderPadding(0), 504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRotationDegrees(0), 505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mChannelMaskPresent(false), 506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mChannelMask(0), 507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDequeueCounter(0), 508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mInputMetadataType(kMetadataBufferTypeInvalid), 509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOutputMetadataType(kMetadataBufferTypeInvalid), 510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mLegacyAdaptiveExperiment(false), 511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mMetadataBuffersToSubmit(0), 512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRepeatFrameDelayUs(-1ll), 513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mMaxPtsGapUs(-1ll), 514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mMaxFps(-1), 515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mTimePerFrameUs(-1ll), 516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mTimePerCaptureUs(-1ll), 51739efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath mCreateInputBuffersSuspended(false), 518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mTunneled(false) { 519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mUninitializedState = new UninitializedState(this); 520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mLoadedState = new LoadedState(this); 5210faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov mLoadedToIdleState = new LoadedToIdleState(this); 5220faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov mIdleToExecutingState = new IdleToExecutingState(this); 5230faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov mExecutingState = new ExecutingState(this); 524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOutputPortSettingsChangedState = 526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright new OutputPortSettingsChangedState(this); 527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mExecutingToIdleState = new ExecutingToIdleState(this); 529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIdleToLoadedState = new IdleToLoadedState(this); 530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mFlushingState = new FlushingState(this); 531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mInputEOSResult = OK; 5340faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov 5350faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov changeState(mUninitializedState); 5360faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov} 537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightACodec::~ACodec() { 539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::setNotificationMessage(const sp<AMessage> &msg) { 542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNotify = msg; 543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::initiateSetup(const sp<AMessage> &msg) { 546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setWhat(kWhatSetup); 547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setTarget(this); 548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->post(); 549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::signalSetParameters(const sp<AMessage> ¶ms) { 552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setMessage("params", params); 554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->post(); 555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) { 558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setWhat(kWhatAllocateComponent); 55939efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath msg->setTarget(this); 560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->post(); 561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) { 564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setWhat(kWhatConfigureComponent); 565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setTarget(this); 566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->post(); 56739efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath} 568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setSurface(const sp<Surface> &surface) { 570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> msg = new AMessage(kWhatSetSurface, this); 571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setObject("surface", surface); 572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> response; 574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = msg->postAndAwaitResponse(&response); 575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (void)response->findInt32("err", &err); 578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::initiateCreateInputSurface() { 583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (new AMessage(kWhatCreateInputSurface, this))->post(); 584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::initiateSetInputSurface( 587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const sp<PersistentSurface> &surface) { 588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setObject("input-surface", surface); 590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->post(); 591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::signalEndOfInputStream() { 594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (new AMessage(kWhatSignalEndOfInputStream, this))->post(); 595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::initiateStart() { 598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (new AMessage(kWhatStart, this))->post(); 599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::signalFlush() { 602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] signalFlush", mComponentName.c_str()); 603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (new AMessage(kWhatFlush, this))->post(); 604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::signalResume() { 607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (new AMessage(kWhatResume, this))->post(); 608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::initiateShutdown(bool keepComponentAllocated) { 611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> msg = new AMessage(kWhatShutdown, this); 612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32("keepComponentAllocated", keepComponentAllocated); 613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->post(); 614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!keepComponentAllocated) { 615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // ensure shutdown completes in 3 seconds 616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000); 617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::signalRequestIDRFrame() { 621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (new AMessage(kWhatRequestIDRFrame, this))->post(); 622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Some codecs may return input buffers before having them processed. 626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// This causes a halt if we already signaled an EOS on the input 627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// port. For now keep submitting an output buffer if there was an 628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// EOS on the input port, but not yet on the output port. 629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() { 630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] && 631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mMetadataBuffersToSubmit > 0) { 632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post(); 633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) { 637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // allow keeping unset surface 638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (surface == NULL) { 639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mNativeWindow != NULL) { 640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("cannot unset a surface"); 641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // cannot switch from bytebuffers to surface 647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mNativeWindow == NULL) { 648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("component was not configured with a surface"); 649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ANativeWindow *nativeWindow = surface.get(); 653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // if we have not yet started the codec, we can simply set the native window 654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mBuffers[kPortIndexInput].size() == 0) { 655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindow = surface; 656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // we do not support changing a tunneled surface after start 660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mTunneled) { 661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("cannot change tunneled surface"); 662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int usageBits = 0; 666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits); 667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int ignoredFlags = kVideoGrallocUsage; 672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // New output surface is not allowed to add new usage flag except ignored ones. 673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) { 674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits); 675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // get min undequeued count. We cannot switch to a surface that has a higher 679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // undequeued count than we allocated. 680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int minUndequeuedBuffers = 0; 681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = nativeWindow->query( 682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &minUndequeuedBuffers); 684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 68539efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright strerror(-err), -err); 687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 68939efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) { 690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)", 691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright minUndequeuedBuffers, mNumUndequeuedBuffers); 692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 69339efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath } 694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // we cannot change the number of output buffers while OMX is running 69639efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath // set up surface to the same count 697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput]; 698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("setting up surface for %zu buffers", buffers.size()); 69939efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath 700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = native_window_set_buffer_count(nativeWindow, buffers.size()); 701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 70339efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath -err); 704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // need to enable allocation when attaching 708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright surface->getIGraphicBufferProducer()->allowAllocation(true); 709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // for meta data mode, we move dequeud buffers to the new surface. 711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // for non-meta mode, we must move all registered buffers 712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < buffers.size(); ++i) { 713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const BufferInfo &info = buffers[i]; 714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // skip undequeued buffers for meta data mode 715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (storingMetadataInDecodedBuffers() 716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && !mLegacyAdaptiveExperiment 717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer()); 719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright continue; 720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer()); 722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer()); 724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("failed to attach buffer %p to the new surface: %s (%d)", 726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mGraphicBuffer->getNativeBuffer(), 727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright strerror(-err), -err); 728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // cancel undequeued buffers to new surface 733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) { 734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < buffers.size(); ++i) { 735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo &info = buffers.editItemAt(i); 736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer()); 738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = nativeWindow->cancelBuffer( 739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd); 740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mFenceFd = -1; 741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("failed to cancel buffer %p to the new surface: %s (%d)", 743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mGraphicBuffer->getNativeBuffer(), 744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright strerror(-err), -err); 745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // disallow further allocation 750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (void)surface->getIGraphicBufferProducer()->allowAllocation(false); 751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // push blank buffers to previous window if requested 754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) { 755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pushBlankBuffersToNativeWindow(mNativeWindow.get()); 756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindow = nativeWindow; 759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindowUsageBits = usageBits; 760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(mDealer[portIndex] == NULL); 767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(mBuffers[portIndex].isEmpty()); 76839efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath 769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err; 770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 77139efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath if (storingMetadataInDecodedBuffers()) { 772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = allocateOutputMetadataBuffers(); 773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = allocateOutputBuffersFromNativeWindow(); 775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_PORTDEFINITIONTYPE def; 77839efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath InitOMXParams(&def); 779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = portIndex; 780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 784842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright if (err == OK) { 785842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright MetadataBufferType type = 786842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType; 787842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright int32_t bufSize = def.nBufferSize; 788842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright if (type == kMetadataBufferTypeGrallocSource) { 789842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright bufSize = sizeof(VideoGrallocMetadata); 790842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright } else if (type == kMetadataBufferTypeANWBuffer) { 791842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright bufSize = sizeof(VideoNativeMetadata); 792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // If using gralloc or native source input metadata buffers, allocate largest 795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // metadata size as we prefer to generate native source metadata, but component 796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // may require gralloc source. For camera source, allocate at least enough 797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // size for native metadata buffers. 798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t allottedSize = bufSize; 799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) { 800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata)); 801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) { 802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bufSize = max(bufSize, (int32_t)sizeof(VideoNativeMetadata)); 803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port", 806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), 807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type), 808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright portIndex == kPortIndexInput ? "input" : "output"); 809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t totalSize = def.nBufferCountActual * bufSize; 811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec"); 812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) { 814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize); 815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mem == NULL || mem->pointer() == NULL) { 816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return NO_MEMORY; 817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo info; 820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mStatus = BufferInfo::OWNED_BY_US; 821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mFenceFd = -1; 822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mRenderInfo = NULL; 823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright uint32_t requiresAllocateBufferBit = 825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (portIndex == kPortIndexInput) 826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ? OMXCodec::kRequiresAllocateBufferOnInputPorts 827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright : OMXCodec::kRequiresAllocateBufferOnOutputPorts; 828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) 830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) { 831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mem.clear(); 832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright void *ptr; 834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->allocateBuffer( 835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, portIndex, bufSize, &info.mBufferID, 836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &ptr); 837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mData = new ABuffer(ptr, bufSize); 839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (mQuirks & requiresAllocateBufferBit) { 840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->allocateBufferWithBackup( 841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, portIndex, mem, &info.mBufferID, allottedSize); 842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize); 844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mem != NULL) { 847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mData = new ABuffer(mem->pointer(), bufSize); 848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (type == kMetadataBufferTypeANWBuffer) { 849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1; 850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBuffers[portIndex].push(info); 854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mNotify->dup(); 863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", CodecBase::kWhatBuffersAllocated); 864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("portIndex", portIndex); 866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<PortDescription> desc = new PortDescription; 868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const BufferInfo &info = mBuffers[portIndex][i]; 871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright desc->addBuffer(info.mBufferID, info.mData); 873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setObject("portDesc", desc); 876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 87939efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath} 880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupNativeWindowSizeFormatAndUsage( 882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) { 88339efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath OMX_PARAM_PORTDEFINITIONTYPE def; 884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = kPortIndexOutput; 886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 89239efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath } 893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 usage = 0; 895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 89739efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath ALOGW("querying usage flags from OMX IL component failed: %d", err); 898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // XXX: Currently this error is logged, but not fatal. 899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright usage = 0; 900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int omxUsage = usage; 90239efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath 903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mFlags & kFlagIsGrallocUsageProtected) { 904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright usage |= GRALLOC_USAGE_PROTECTED; 905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 90739efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath usage |= kVideoGrallocUsage; 908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *finalUsage = usage; 909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage); 911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return setNativeWindowSizeFormatAndUsage( 912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright nativeWindow, 913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.format.video.nFrameWidth, 914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.format.video.nFrameHeight, 915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.format.video.eColorFormat, 916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRotationDegrees, 917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright usage); 918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::configureOutputBuffersFromNativeWindow( 921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 *bufferCount, OMX_U32 *bufferSize, 922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 *minUndequeuedBuffers) { 923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_PORTDEFINITIONTYPE def; 924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = kPortIndexOutput; 926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits); 932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindowUsageBits = 0; 935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Exits here for tunneled video playback codecs -- i.e. skips native window 939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // buffer allocation step as this is managed by the tunneled OMX omponent 940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // itself and explicitly sets def.nBufferCountActual to 0. 941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mTunneled) { 942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("Tunneled Playback: skipping native window buffer allocation."); 943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nBufferCountActual = 0; 944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *minUndequeuedBuffers = 0; 948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *bufferCount = 0; 949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *bufferSize = 0; 950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *minUndequeuedBuffers = 0; 954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mNativeWindow->query( 955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (int *)minUndequeuedBuffers); 957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright strerror(-err), -err); 961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // FIXME: assume that surface is controlled by app (native window 965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // returns the number for the case when surface is not controlled by app) 966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported 967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // For now, try to allocate 1 more buffer, but don't fail if unsuccessful 968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Use conservative allocation while also trying to reduce starvation 970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // 971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the 972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // minimum needed for the consumer to be able to work 973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // 2. try to allocate two (2) additional buffers to reduce starvation from 974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // the consumer 975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // plus an extra buffer to account for incorrect minUndequeuedBufs 976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { 977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 newBufferCount = 978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers; 979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nBufferCountActual = newBufferCount; 980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *minUndequeuedBuffers += extraBuffers; 985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("[%s] setting nBufferCountActual to %u failed: %d", 989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), newBufferCount, err); 990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright /* exit condition */ 991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (extraBuffers == 0) { 992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = native_window_set_buffer_count( 997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindow.get(), def.nBufferCountActual); 998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 1000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 1001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright -err); 1002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *bufferCount = def.nBufferCountActual; 1006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *bufferSize = def.nBufferSize; 1007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::allocateOutputBuffersFromNativeWindow() { 1011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 1012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = configureOutputBuffersFromNativeWindow( 1013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &bufferCount, &bufferSize, &minUndequeuedBuffers); 1014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) 1015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNumUndequeuedBuffers = minUndequeuedBuffers; 1017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!storingMetadataInDecodedBuffers()) { 1019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<Surface*>(mNativeWindow.get()) 1020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ->getIGraphicBufferProducer()->allowAllocation(true); 1021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Allocating %u buffers from a native window of size %u on " 1024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "output port", 1025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), bufferCount, bufferSize); 1026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Dequeue buffers and send them to OMX 1028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 i = 0; i < bufferCount; i++) { 1029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ANativeWindowBuffer *buf; 1030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int fenceFd; 1031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 1033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 1035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 1038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo info; 1039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mStatus = BufferInfo::OWNED_BY_US; 1040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mFenceFd = fenceFd; 1041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mIsReadFence = false; 1042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mRenderInfo = NULL; 1043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */); 1044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mGraphicBuffer = graphicBuffer; 1045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBuffers[kPortIndexOutput].push(info); 1046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::buffer_id bufferId; 1048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 1049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &bufferId); 1050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 1051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("registering GraphicBuffer %u with OMX IL component failed: " 1052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "%d", i, err); 1053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 1054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId; 1057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)", 1059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), 1060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bufferId, graphicBuffer.get()); 1061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 cancelStart; 1064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 cancelEnd; 1065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 1067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // If an error occurred while dequeuing we need to cancel any buffers 1068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // that were dequeued. 1069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright cancelStart = 0; 1070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright cancelEnd = mBuffers[kPortIndexOutput].size(); 1071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Return the required minimum undequeued buffers to the native window. 1073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright cancelStart = bufferCount - minUndequeuedBuffers; 1074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright cancelEnd = bufferCount; 1075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 1078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus == BufferInfo::OWNED_BY_US) { 1080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t error = cancelBufferToNativeWindow(info); 1081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == 0) { 1082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = error; 1083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!storingMetadataInDecodedBuffers()) { 1088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<Surface*>(mNativeWindow.get()) 1089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ->getIGraphicBufferProducer()->allowAllocation(false); 1090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::allocateOutputMetadataBuffers() { 1096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 1097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = configureOutputBuffersFromNativeWindow( 1098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &bufferCount, &bufferSize, &minUndequeuedBuffers); 1099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) 1100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNumUndequeuedBuffers = minUndequeuedBuffers; 1102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Allocating %u meta buffers on output port", 1104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), bufferCount); 1105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ? 1107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata); 1108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t totalSize = bufferCount * bufSize; 1109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec"); 1110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Dequeue buffers and send them to OMX 1112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 i = 0; i < bufferCount; i++) { 1113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo info; 1114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mFenceFd = -1; 1116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mRenderInfo = NULL; 1117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mGraphicBuffer = NULL; 1118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mDequeuedAt = mDequeueCounter; 1119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize); 1121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mem == NULL || mem->pointer() == NULL) { 1122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return NO_MEMORY; 1123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) { 1125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1; 1126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mData = new ABuffer(mem->pointer(), mem->size()); 1128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // we use useBuffer for metadata regardless of quirks 1130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->useBuffer( 1131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size()); 1132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBuffers[kPortIndexOutput].push(info); 1134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)", 1136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), info.mBufferID, mem->pointer()); 1137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mLegacyAdaptiveExperiment) { 1140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // preallocate and preregister buffers 1141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<Surface *>(mNativeWindow.get()) 1142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ->getIGraphicBufferProducer()->allowAllocation(true); 1143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Allocating %u buffers from a native window of size %u on " 1145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "output port", 1146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), bufferCount, bufferSize); 1147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Dequeue buffers then cancel them all 1149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 i = 0; i < bufferCount; i++) { 1150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ANativeWindowBuffer *buf; 1153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int fenceFd; 1154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 1156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 1158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 1161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOMX->updateGraphicBufferInMeta( 1162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, kPortIndexOutput, graphicBuffer, info->mBufferID); 1163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_US; 1164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy"); 1165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mGraphicBuffer = graphicBuffer; 1166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) { 1169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus == BufferInfo::OWNED_BY_US) { 1171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t error = cancelBufferToNativeWindow(info); 1172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 1173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = error; 1174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<Surface*>(mNativeWindow.get()) 1179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ->getIGraphicBufferProducer()->allowAllocation(false); 1180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers; 1183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::submitOutputMetadataBuffer() { 1187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(storingMetadataInDecodedBuffers()); 1188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mMetadataBuffersToSubmit == 0) 1189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 1190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = dequeueBufferFromNativeWindow(); 1192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info == NULL) { 1193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return ERROR_IO; 1194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p", 1197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get()); 1198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright --mMetadataBuffersToSubmit; 1200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->checkWriteFence("submitOutputMetadataBuffer"); 1201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd); 1202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd = -1; 1203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 1204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::waitForFence(int fd, const char *dbg ) { 1211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t res = OK; 1212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (fd >= 0) { 1213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<Fence> fence = new Fence(fd); 1214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright res = fence->wait(IOMX::kFenceTimeoutMs); 1215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg); 1216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return res; 1218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// static 1221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightconst char *ACodec::_asString(BufferInfo::Status s) { 1222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (s) { 1223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case BufferInfo::OWNED_BY_US: return "OUR"; 1224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case BufferInfo::OWNED_BY_COMPONENT: return "COMPONENT"; 1225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case BufferInfo::OWNED_BY_UPSTREAM: return "UPSTREAM"; 1226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case BufferInfo::OWNED_BY_DOWNSTREAM: return "DOWNSTREAM"; 1227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE"; 1228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case BufferInfo::UNRECOGNIZED: return "UNRECOGNIZED"; 1229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: return "?"; 1230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::dumpBuffers(OMX_U32 portIndex) { 1234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(), 1236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size()); 1237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const BufferInfo &info = mBuffers[portIndex][i]; 1239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI(" slot %2zu: #%8u %p/%p %s(%d) dequeued:%u", 1240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright i, info.mBufferID, info.mGraphicBuffer.get(), 1241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(), 1242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright _asString(info.mStatus), info.mStatus, info.mDequeuedAt); 1243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 1247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 1248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Calling cancelBuffer on buffer %u", 1250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), info->mBufferID); 1251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->checkWriteFence("cancelBufferToNativeWindow"); 1253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int err = mNativeWindow->cancelBuffer( 1254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 1255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd = -1; 1256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window", 1258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), info->mBufferID); 1259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // change ownership even if cancelBuffer fails 1260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::updateRenderInfoForDequeuedBuffer( 1266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) { 1267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mRenderInfo = 1269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRenderTracker.updateInfoForDequeuedBuffer( 1270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]); 1271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // check for any fences already signaled 1273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo); 1274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 1277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) { 1278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRenderTracker.dumpRenderQueue(); 1279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) { 1283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> msg = mNotify->dup(); 1284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->setInt32("what", CodecBase::kWhatOutputFramesRendered); 1285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright std::list<FrameRenderTracker::Info> done = 1286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete); 1287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // unlink untracked frames 1289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin(); 1290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright it != done.cend(); ++it) { 1291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ssize_t index = it->getIndex(); 1292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) { 1293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL; 1294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (index >= 0) { 1295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // THIS SHOULD NEVER HAPPEN 1296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size()); 1297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (MediaCodec::CreateFramesRenderedMessage(done, msg)) { 1301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->post(); 1302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 1306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ANativeWindowBuffer *buf; 1307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(mNativeWindow.get() != NULL); 1308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mTunneled) { 1310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel" 1311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright " video playback mode mode!"); 1312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return NULL; 1313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int fenceFd = -1; 1316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright do { 1317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != 0) { 1319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err); 1320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return NULL; 1321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool stale = false; 1324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 1325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mGraphicBuffer != NULL && 1328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mGraphicBuffer->handle == buf->handle) { 1329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Since consumers can attach buffers to BufferQueues, it is possible 1330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // that a known yet stale buffer can return from a surface that we 1331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // once used. We can simply ignore this as we have already dequeued 1332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // this buffer properly. NOTE: this does not eliminate all cases, 1333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // e.g. it is possible that we have queued the valid buffer to the 1334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // NW, and a stale copy of the same buffer gets dequeued - which will 1335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // be treated as the valid buffer by ACodec. 1336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("dequeued stale buffer %p. discarding", buf); 1338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright stale = true; 1339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 1340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer()); 1343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_US; 1344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow"); 1345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright updateRenderInfoForDequeuedBuffer(buf, fenceFd, info); 1346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return info; 1347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // It is also possible to receive a previously unregistered buffer 1351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // in non-meta mode. These should be treated as stale buffers. The 1352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // same is possible in meta mode, in which case, it will be treated 1353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // as a normal buffer, which is not desirable. 1354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // TODO: fix this. 1355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) { 1356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf); 1357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright stale = true; 1358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (stale) { 1360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // TODO: detach stale buffer, but there is no API yet to do it. 1361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright buf = NULL; 1362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } while (buf == NULL); 1364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // get oldest undequeued buffer 1366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *oldest = NULL; 1367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 1368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = 1369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &mBuffers[kPortIndexOutput].editItemAt(i); 1370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW && 1371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (oldest == NULL || 1372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // avoid potential issues from counter rolling over 1373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDequeueCounter - info->mDequeuedAt > 1374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDequeueCounter - oldest->mDequeuedAt)) { 1375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright oldest = info; 1376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // it is impossible dequeue a buffer when there are no buffers with ANW 1380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(oldest != NULL); 1381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // it is impossible to dequeue an unknown buffer in non-meta mode, as the 1382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // while loop above does not complete 1383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(storingMetadataInDecodedBuffers()); 1384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // discard buffer in LRU info and replace with new buffer 1386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright oldest->mGraphicBuffer = new GraphicBuffer(buf, false); 1387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright oldest->mStatus = BufferInfo::OWNED_BY_US; 1388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest"); 1389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRenderTracker.untrackFrame(oldest->mRenderInfo); 1390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright oldest->mRenderInfo = NULL; 1391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOMX->updateGraphicBufferInMeta( 1393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, kPortIndexOutput, oldest->mGraphicBuffer, 1394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright oldest->mBufferID); 1395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) { 1397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright VideoGrallocMetadata *grallocMeta = 1398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base()); 1399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)", 1400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]), 1401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDequeueCounter - oldest->mDequeuedAt, 1402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (void *)(uintptr_t)grallocMeta->pHandle, 1403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright oldest->mGraphicBuffer->handle, oldest->mData->base()); 1404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) { 1405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright VideoNativeMetadata *nativeMeta = 1406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base()); 1407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)", 1408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]), 1409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDequeueCounter - oldest->mDequeuedAt, 1410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (void *)(uintptr_t)nativeMeta->pBuffer, 1411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base()); 1412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest); 1415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return oldest; 1416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 1419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = OK; 1420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = mBuffers[portIndex].size(); i > 0;) { 1421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright i--; 1422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err2 = freeBuffer(portIndex, i); 1423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 1424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = err2; 1425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // clear mDealer even on an error 1429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDealer[portIndex].clear(); 1430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() { 1434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = OK; 1435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright i--; 1437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = 1438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &mBuffers[kPortIndexOutput].editItemAt(i); 1439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // At this time some buffers may still be with the component 1441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // or being drained. 1442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT && 1443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) { 1444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err2 = freeBuffer(kPortIndexOutput, i); 1445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 1446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = err2; 1447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 1455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = OK; 1457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // there should not be any fences in the metadata 1459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright MetadataBufferType type = 1460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType; 1461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL 1462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && info->mData->size() >= sizeof(VideoNativeMetadata)) { 1463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd; 1464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (fenceFd >= 0) { 1465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("unreleased fence (%d) in %s metadata buffer %zu", 1466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fenceFd, portIndex == kPortIndexInput ? "input" : "output", i); 1467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (info->mStatus) { 1471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case BufferInfo::OWNED_BY_US: 1472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (portIndex == kPortIndexOutput && mNativeWindow != NULL) { 1473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (void)cancelBufferToNativeWindow(info); 1474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // fall through 1476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case BufferInfo::OWNED_BY_NATIVE_WINDOW: 1478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID); 1479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 1480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 1482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus); 1483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = FAILED_TRANSACTION; 1484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 1485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mFenceFd >= 0) { 1488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ::close(info->mFenceFd); 1489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (portIndex == kPortIndexOutput) { 1492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRenderTracker.untrackFrame(info->mRenderInfo, i); 1493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mRenderInfo = NULL; 1494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // remove buffer even if mOMX->freeBuffer fails 1497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBuffers[portIndex].removeAt(i); 1498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightACodec::BufferInfo *ACodec::findBufferByID( 1502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) { 1503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mBufferID == bufferID) { 1507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (index != NULL) { 1508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *index = i; 1509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return info; 1511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Could not find buffer with ID %u", bufferID); 1515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return NULL; 1516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setComponentRole( 1519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool isEncoder, const char *mime) { 1520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright struct MimeToRole { 1521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *mime; 1522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *decoderRole; 1523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *encoderRole; 1524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright }; 1525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static const MimeToRole kMimeToRole[] = { 1527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_MPEG, 1528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.mp3", "audio_encoder.mp3" }, 1529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, 1530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.mp1", "audio_encoder.mp1" }, 15311bd2fc059c73c91f64d86b0eee59eda6ba888354Dan Albert { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, 15321bd2fc059c73c91f64d86b0eee59eda6ba888354Dan Albert "audio_decoder.mp2", "audio_encoder.mp2" }, 1533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_AAC, 1538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.aac", "audio_encoder.aac" }, 1539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_VORBIS, 1540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.vorbis", "audio_encoder.vorbis" }, 1541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_OPUS, 1542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.opus", "audio_encoder.opus" }, 1543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_G711_MLAW, 1544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" }, 1545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_G711_ALAW, 1546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, 154739efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath { MEDIA_MIMETYPE_VIDEO_AVC, 1548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "video_decoder.avc", "video_encoder.avc" }, 1549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_HEVC, 1550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "video_decoder.hevc", "video_encoder.hevc" }, 1551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_MPEG4, 1552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_H263, 1554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "video_decoder.h263", "video_encoder.h263" }, 1555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_VP8, 1556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "video_decoder.vp8", "video_encoder.vp8" }, 1557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_VP9, 1558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "video_decoder.vp9", "video_encoder.vp9" }, 1559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_RAW, 1560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.raw", "audio_encoder.raw" }, 1561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_FLAC, 1562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.flac", "audio_encoder.flac" }, 1563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_MSGSM, 1564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.gsm", "audio_encoder.gsm" }, 1565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_MPEG2, 1566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "video_decoder.mpeg2", "video_encoder.mpeg2" }, 1567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_AC3, 1568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.ac3", "audio_encoder.ac3" }, 1569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_AUDIO_EAC3, 1570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "audio_decoder.eac3", "audio_encoder.eac3" }, 1571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright }; 1572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static const size_t kNumMimeToRole = 1574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t i; 1577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (i = 0; i < kNumMimeToRole; ++i) { 1578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 1580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (i == kNumMimeToRole) { 1584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return ERROR_UNSUPPORTED; 1585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *role = 1588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright isEncoder ? kMimeToRole[i].encoderRole 1589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright : kMimeToRole[i].decoderRole; 1590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (role != NULL) { 1592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_COMPONENTROLETYPE roleParams; 1593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&roleParams); 1594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright strncpy((char *)roleParams.cRole, 1596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright role, OMX_MAX_STRINGNAME_SIZE - 1); 1597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->setParameter( 1601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamStandardComponentRole, 1602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &roleParams, sizeof(roleParams)); 1603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("[%s] Failed to set standard component role '%s'.", 1606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), role); 1607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 1613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 1614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::configureCodec( 1616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *mime, const sp<AMessage> &msg) { 1617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t encoder; 1618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("encoder", &encoder)) { 1619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder = false; 1620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> inputFormat = new AMessage(); 1623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged 1624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIsEncoder = encoder; 1626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mInputMetadataType = kMetadataBufferTypeInvalid; 1628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOutputMetadataType = kMetadataBufferTypeInvalid; 1629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = setComponentRole(encoder /* isEncoder */, mime); 1631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t bitRate = 0; 1637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // FLAC encoder doesn't need a bitrate, other encoders do 1638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) 1639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && !msg->findInt32("bitrate", &bitRate)) { 1640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 1641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t storeMeta; 1644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder 1645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && msg->findInt32("store-metadata-in-buffers", &storeMeta) 1646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && storeMeta != 0) { 1647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType); 1648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d", 1650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), err); 1651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // For this specific case we could be using camera source even if storeMetaDataInBuffers 1655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize. 1656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mInputMetadataType == kMetadataBufferTypeGrallocSource) { 1657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mInputMetadataType = kMetadataBufferTypeCameraSource; 1658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright uint32_t usageBits; 1661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mOMX->getParameter( 1662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 1663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &usageBits, sizeof(usageBits)) == OK) { 1664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32( 1665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 1666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t prependSPSPPS = 0; 1670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder 1671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS) 1672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && prependSPSPPS != 0) { 1673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_INDEXTYPE index; 1674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getExtensionIndex( 1675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, 1676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "OMX.google.android.index.prependSPSPPSToIDRFrames", 1677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &index); 1678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 1680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright PrependSPSPPSToIDRFramesParams params; 1681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 1682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.bEnable = OMX_TRUE; 1683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 1685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, index, ¶ms, sizeof(params)); 1686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Encoder could not be configured to emit SPS/PPS before " 1690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "IDR frames. (err %d)", err); 1691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Only enable metadata mode on encoder output if encoder can prepend 1697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // sps/pps to idr frames, since in metadata mode the bitstream is in an 1698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // opaque handle, to which we don't have access. 1699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t video = !strncasecmp(mime, "video/", 6); 1700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mIsVideo = video; 1701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder && video) { 1702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS 1703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && msg->findInt32("store-metadata-in-buffers-output", &storeMeta) 1704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && storeMeta != 0); 1705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType); 1707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d", 1709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), err); 1710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt64( 1713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "repeat-previous-frame-after", 1714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &mRepeatFrameDelayUs)) { 1715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRepeatFrameDelayUs = -1ll; 1716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) { 1719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mMaxPtsGapUs = -1ll; 1720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) { 1723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mMaxFps = -1; 1724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) { 1727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mTimePerCaptureUs = -1ll; 1728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32( 1731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "create-input-buffers-suspended", 1732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (int32_t*)&mCreateInputBuffersSuspended)) { 1733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCreateInputBuffersSuspended = false; 1734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // NOTE: we only use native window for video decoders 1738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<RefBase> obj; 1739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool haveNativeWindow = msg->findObject("native-window", &obj) 1740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && obj != NULL && video && !encoder; 1741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mLegacyAdaptiveExperiment = false; 1742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (video && !encoder) { 1743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("adaptive-playback", false); 1744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t usageProtected; 1746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("protected", &usageProtected) && usageProtected) { 1747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!haveNativeWindow) { 1748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("protected output buffers must be sent to an ANativeWindow"); 1749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return PERMISSION_DENIED; 1750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mFlags |= kFlagIsGrallocUsageProtected; 1752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 1753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (haveNativeWindow) { 1756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<ANativeWindow> nativeWindow = 1757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get())); 1758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // START of temporary support for automatic FRC - THIS WILL BE REMOVED 1760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t autoFrc; 1761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("auto-frc", &autoFrc)) { 1762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool enabled = autoFrc; 1763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_CONFIG_BOOLEANTYPE config; 1764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&config); 1765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright config.bEnabled = (OMX_BOOL)enabled; 1766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t temp = mOMX->setConfig( 1767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion, 1768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &config, sizeof(config)); 1769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (temp == OK) { 1770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright outputFormat->setInt32("auto-frc", enabled); 1771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (enabled) { 1772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("codec does not support requested auto-frc (err %d)", temp); 1773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // END of temporary support for automatic FRC 1776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tunneled; 1778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("feature-tunneled-playback", &tunneled) && 1779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright tunneled != 0) { 1780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("Configuring TUNNELED video playback."); 1781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mTunneled = true; 1782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t audioHwSync = 0; 1784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("audio-hw-sync", &audioHwSync)) { 1785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("No Audio HW Sync provided for video tunnel"); 1786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = configureTunneledVideoPlayback(audioHwSync, nativeWindow); 1788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("configureTunneledVideoPlayback(%d,%p) failed!", 1790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright audioHwSync, nativeWindow.get()); 1791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t maxWidth = 0, maxHeight = 0; 1795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("max-width", &maxWidth) && 1796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->findInt32("max-height", &maxHeight)) { 1797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->prepareForAdaptivePlayback( 1799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); 1800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d", 1802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), err); 1803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // allow failure 1804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = OK; 1805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("max-width", maxWidth); 1807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("max-height", maxHeight); 1808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("adaptive-playback", true); 1809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("Configuring CPU controlled video playback."); 1813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mTunneled = false; 1814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Explicity reset the sideband handle of the window for 1816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // non-tunneled video in case the window was previously used 1817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // for a tunneled video playback. 1818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = native_window_set_sideband_stream(nativeWindow.get(), NULL); 1819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("set_sideband_stream(NULL) failed! (err %d).", err); 1821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Always try to enable dynamic output buffers on native surface 1825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->storeMetaDataInBuffers( 1826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType); 1827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d", 1829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), err); 1830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // if adaptive playback has been requested, try JB fallback 1832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS 1833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // LARGE MEMORY REQUIREMENT 1834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // we will not do adaptive playback on software accessed 1836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // surfaces as they never had to respond to changes in the 1837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // crop window, and we don't trust that they will be able to. 1838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int usageBits = 0; 1839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool canDoAdaptivePlayback; 1840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (nativeWindow->query( 1842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright nativeWindow.get(), 1843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright NATIVE_WINDOW_CONSUMER_USAGE_BITS, 1844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &usageBits) != OK) { 1845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright canDoAdaptivePlayback = false; 1846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright canDoAdaptivePlayback = 1848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (usageBits & 1849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (GRALLOC_USAGE_SW_READ_MASK | 1850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright GRALLOC_USAGE_SW_WRITE_MASK)) == 0; 1851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t maxWidth = 0, maxHeight = 0; 1854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (canDoAdaptivePlayback && 1855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->findInt32("max-width", &maxWidth) && 1856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->findInt32("max-height", &maxHeight)) { 1857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)", 1858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), maxWidth, maxHeight); 1859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->prepareForAdaptivePlayback( 1861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, kPortIndexOutput, OMX_TRUE, maxWidth, 1862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright maxHeight); 1863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW_IF(err != OK, 1864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "[%s] prepareForAdaptivePlayback failed w/ err %d", 1865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), err); 1866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 1868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("max-width", maxWidth); 1869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("max-height", maxHeight); 1870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("adaptive-playback", true); 1871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // allow failure 1874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = OK; 1875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] storeMetaDataInBuffers succeeded", 1877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str()); 1878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(storingMetadataInDecodedBuffers()); 1879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled( 1880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "legacy-adaptive", !msg->contains("no-experiments")); 1881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("adaptive-playback", true); 1883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t push; 1886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("push-blank-buffers-on-shutdown", &push) 1887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && push != 0) { 1888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 1889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t rotationDegrees; 1893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("rotation-degrees", &rotationDegrees)) { 1894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRotationDegrees = rotationDegrees; 1895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mRotationDegrees = 0; 1897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (video) { 1901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // determine need for software renderer 1902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool usingSwRenderer = false; 1903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) { 1904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright usingSwRenderer = true; 1905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright haveNativeWindow = false; 1906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder) { 1909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupVideoEncoder(mime, msg); 1910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupVideoDecoder(mime, msg, haveNativeWindow); 1912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (haveNativeWindow) { 1919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindow = static_cast<Surface *>(obj.get()); 1920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // initialize native window now to get actual output format 1923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // TODO: this is needed for some encoders even though they don't use native window 1924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = initNativeWindow(); 1925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // fallback for devices that do not handle flex-YUV for native buffers 1930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (haveNativeWindow) { 1931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t requestedColorFormat = OMX_COLOR_FormatUnused; 1932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("color-format", &requestedColorFormat) && 1933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) { 1934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = getPortFormat(kPortIndexOutput, outputFormat); 1935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 1936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 1937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t colorFormat = OMX_COLOR_FormatUnused; 1939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused; 1940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!outputFormat->findInt32("color-format", &colorFormat)) { 1941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("ouptut port did not have a color format (wrong domain?)"); 1942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 1943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGD("[%s] Requested output format %#x and got %#x.", 1945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), requestedColorFormat, colorFormat); 1946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!isFlexibleColorFormat( 1947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent) 1948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || flexibleEquivalent != (OMX_U32)requestedColorFormat) { 1949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // device did not handle flex-YUV request for native window, fall back 1950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // to SW renderer 1951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("[%s] Falling back to software renderer", mComponentName.c_str()); 1952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindow.clear(); 1953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindowUsageBits = 0; 1954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright haveNativeWindow = false; 1955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright usingSwRenderer = true; 1956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (storingMetadataInDecodedBuffers()) { 1957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->storeMetaDataInBuffers( 1958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType); 1959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case 1960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // TODO: implement adaptive-playback support for bytebuffer mode. 1961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // This is done by SW codecs, but most HW codecs don't support it. 1962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright inputFormat->setInt32("adaptive-playback", false); 1963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 1965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 1966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mFlags & kFlagIsGrallocUsageProtected) { 1968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // fallback is not supported for protected playback 1969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = PERMISSION_DENIED; 1970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (err == OK) { 1971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupVideoDecoder(mime, msg, false); 1972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (usingSwRenderer) { 1978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright outputFormat->setInt32("using-sw-renderer", 1); 1979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 1981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t numChannels, sampleRate; 1982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("channel-count", &numChannels) 1983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("sample-rate", &sampleRate)) { 1984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Since we did not always check for these, leave them optional 1985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // and have the decoder figure it all out. 1986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = OK; 1987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupRawAudioFormat( 1989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder ? kPortIndexInput : kPortIndexOutput, 1990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sampleRate, 1991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright numChannels); 1992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 1993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t numChannels, sampleRate; 1995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("channel-count", &numChannels) 1996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("sample-rate", &sampleRate)) { 1997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = INVALID_OPERATION; 1998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 1999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t isADTS, aacProfile; 2000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t sbrMode; 2001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t maxOutputChannelCount; 2002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t pcmLimiterEnable; 2003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright drcParams_t drc; 2004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("is-adts", &isADTS)) { 2005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright isADTS = 0; 2006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-profile", &aacProfile)) { 2008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright aacProfile = OMX_AUDIO_AACObjectNull; 2009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-sbr-mode", &sbrMode)) { 2011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sbrMode = -1; 2012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) { 2015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright maxOutputChannelCount = -1; 2016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) { 2018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // value is unknown 2019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pcmLimiterEnable = -1; 2020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) { 2022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // value is unknown 2023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright drc.encodedTargetLevel = -1; 2024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) { 2026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // value is unknown 2027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright drc.drcCut = -1; 2028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) { 2030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // value is unknown 2031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright drc.drcBoost = -1; 2032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) { 2034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // value is unknown 2035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright drc.heavyCompression = -1; 2036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) { 2038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // value is unknown 2039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright drc.targetRefLevel = -1; 2040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupAACCodec( 2043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder, numChannels, sampleRate, bitRate, aacProfile, 2044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright isADTS != 0, sbrMode, maxOutputChannelCount, drc, 2045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pcmLimiterEnable); 2046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 2048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupAMRCodec(encoder, false /* isWAMR */, bitRate); 2049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 2050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupAMRCodec(encoder, true /* isWAMR */, bitRate); 2051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW) 2052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) { 2053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // These are PCM-like formats with a fixed sample rate but 2054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // a variable number of channels. 2055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t numChannels; 2057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("channel-count", &numChannels)) { 2058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = INVALID_OPERATION; 2059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 2060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t sampleRate; 2061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("sample-rate", &sampleRate)) { 2062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sampleRate = 8000; 2063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupG711Codec(encoder, sampleRate, numChannels); 2065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { 2067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1; 2068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder && 2069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (!msg->findInt32("channel-count", &numChannels) 2070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("sample-rate", &sampleRate))) { 2071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("missing channel count or sample rate for FLAC encoder"); 2072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = INVALID_OPERATION; 2073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 2074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder) { 2075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32( 2076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "complexity", &compressionLevel) && 2077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright !msg->findInt32( 2078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "flac-compression-level", &compressionLevel)) { 2079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright compressionLevel = 5; // default FLAC compression level 2080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (compressionLevel < 0) { 2081fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ALOGW("compression level %d outside [0..8] range, " 2082fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev "using 0", 2083fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev compressionLevel); 2084fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev compressionLevel = 0; 2085fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else if (compressionLevel > 8) { 2086fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ALOGW("compression level %d outside [0..8] range, " 2087fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev "using 8", 2088fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev compressionLevel); 2089fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev compressionLevel = 8; 2090fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2091fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2092fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = setupFlacCodec( 2093fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev encoder, numChannels, sampleRate, compressionLevel); 2094fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2095fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { 2096fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev int32_t numChannels, sampleRate; 2097fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (encoder 2098fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev || !msg->findInt32("channel-count", &numChannels) 2099fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev || !msg->findInt32("sample-rate", &sampleRate)) { 2100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = INVALID_OPERATION; 2101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 2102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) { 2105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t numChannels; 2106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t sampleRate; 2107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("channel-count", &numChannels) 2108fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev || !msg->findInt32("sample-rate", &sampleRate)) { 2109fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = INVALID_OPERATION; 2110fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else { 2111fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = setupAC3Codec(encoder, numChannels, sampleRate); 2112fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2113fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) { 2114fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev int32_t numChannels; 2115fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev int32_t sampleRate; 2116fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (!msg->findInt32("channel-count", &numChannels) 2117fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev || !msg->findInt32("sample-rate", &sampleRate)) { 2118fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = INVALID_OPERATION; 2119fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else { 2120fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = setupEAC3Codec(encoder, numChannels, sampleRate); 2121fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2122fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2123fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2124fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 2125fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return err; 2126fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("encoder-delay", &mEncoderDelay)) { 2129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mEncoderDelay = 0; 2130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("encoder-padding", &mEncoderPadding)) { 2133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mEncoderPadding = 0; 2134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("channel-mask", &mChannelMask)) { 2137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mChannelMaskPresent = true; 2138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 2139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mChannelMaskPresent = false; 2140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t maxInputSize; 2143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("max-input-size", &maxInputSize)) { 2144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize); 2145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) { 2146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setMinBufferSize(kPortIndexInput, 8192); // XXX 2147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t priority; 2150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("priority", &priority)) { 2151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setPriority(priority); 2152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t rateInt = -1; 2155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright float rateFloat = -1; 2156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findFloat("operating-rate", &rateFloat)) { 2157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->findInt32("operating-rate", &rateInt); 2158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rateFloat = (float)rateInt; // 16MHz (FLINTMAX) is OK for upper bound. 2159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (rateFloat > 0) { 2161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setOperatingRate(rateFloat, video); 2162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBaseOutputFormat = outputFormat; 2165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = getPortFormat(kPortIndexInput, inputFormat); 2167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 2168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = getPortFormat(kPortIndexOutput, outputFormat); 2169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 2170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mInputFormat = inputFormat; 2171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOutputFormat = outputFormat; 2172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setPriority(int32_t priority) { 2178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (priority < 0) { 2179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 2180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2181fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_PARAM_U32TYPE config; 2182fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(&config); 2183fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev config.nU32 = (OMX_U32)priority; 2184fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev status_t temp = mOMX->setConfig( 2185fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority, 2186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &config, sizeof(config)); 2187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (temp != OK) { 2188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("codec does not support config priority (err %d)", temp); 2189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2190fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OK; 2191fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 2192fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2193fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) { 2194fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (rateFloat < 0) { 2195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 2196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 rate; 2198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (isVideo) { 2199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (rateFloat > 65535) { 2200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 2201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f); 2203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 2204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (rateFloat > UINT_MAX) { 2205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 2206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rate = (OMX_U32)(rateFloat); 2208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_U32TYPE config; 2210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&config); 2211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright config.nU32 = rate; 2212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->setConfig( 2213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate, 2214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &config, sizeof(config)); 2215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("codec does not support config operating rate (err %d)", err); 2217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2218fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OK; 2219fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 2220fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2221fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) { 2222fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_PARAM_PORTDEFINITIONTYPE def; 2223fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(&def); 2224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = portIndex; 2225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 2227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (def.nBufferSize >= size) { 2234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 2235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nBufferSize = size; 2238fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2239fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = mOMX->setParameter( 2240fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2241fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2242fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 2243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 2247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (def.nBufferSize < size) { 2254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize); 2255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return FAILED_TRANSACTION; 2256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 2259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::selectAudioPortFormat( 2262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) { 2263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_PORTFORMATTYPE format; 2264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&format); 2265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright format.nPortIndex = portIndex; 2267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 index = 0;; ++index) { 2268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright format.nIndex = index; 2269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 2271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioPortFormat, 2272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &format, sizeof(format)); 2273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (format.eEncoding == desiredFormat) { 2279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->setParameter( 2284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format)); 2285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupAACCodec( 2288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool encoder, int32_t numChannels, int32_t sampleRate, 2289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode, 2290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t maxOutputChannelCount, const drcParams_t& drc, 2291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t pcmLimiterEnable) { 2292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder && isADTS) { 2293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return -EINVAL; 2294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = setupRawAudioFormat( 2297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder ? kPortIndexInput : kPortIndexOutput, 2298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sampleRate, 2299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright numChannels); 2300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder) { 2306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC); 2307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_PORTDEFINITIONTYPE def; 2313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 2314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = kPortIndexOutput; 2315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 2317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.format.audio.bFlagErrorConcealment = OMX_TRUE; 2324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 2325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 2327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&profile); 2335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nPortIndex = kPortIndexOutput; 2336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 2338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2339fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2340fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 2341fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return err; 2342fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2343fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2344fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev profile.nChannels = numChannels; 2345fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.eChannelMode = 2347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (numChannels == 1) 2348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo; 2349fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nSampleRate = sampleRate; 2351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nBitRate = bitRate; 2352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAudioBandWidth = 0; 2353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nFrameLength = 0; 2354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAACtools = OMX_AUDIO_AACToolAll; 2355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAACERtools = OMX_AUDIO_AACERNone; 2356fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile; 2357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 2358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (sbrMode) { 2359fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev case 0: 2360fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev // disable sbr 2361fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 2362fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 2363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2364fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev case 1: 2365fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev // enable single-rate sbr 2366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 2367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 2368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case 2: 2370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // enable dual-rate sbr 2371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 2372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 2373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case -1: 2375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // enable both modes -> the codec will decide which mode should be used 2376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 2377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 2378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 2380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // unsupported sbr mode 2381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 2382fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2383fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2384fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2385fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = mOMX->setParameter( 2386fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2387fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2388fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 2389fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return err; 2390fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2391fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2392fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return err; 2393fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2394fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2395fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2396fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(&profile); 2397fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev profile.nPortIndex = kPortIndexInput; 2398fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 2400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2402fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 2403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2405fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2406fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev profile.nChannels = numChannels; 2407fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev profile.nSampleRate = sampleRate; 2408fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright profile.eAACStreamFormat = 2410fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev isADTS 2411fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ? OMX_AUDIO_AACStreamFormatMP4ADTS 2412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright : OMX_AUDIO_AACStreamFormatMP4FF; 2413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation; 2415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright presentation.nMaxOutputChannels = maxOutputChannelCount; 2416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright presentation.nDrcCut = drc.drcCut; 2417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright presentation.nDrcBoost = drc.drcBoost; 2418fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev presentation.nHeavyCompression = drc.heavyCompression; 2419fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev presentation.nTargetReferenceLevel = drc.targetRefLevel; 2420fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev presentation.nEncodedTargetLevel = drc.encodedTargetLevel; 2421fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev presentation.nPCMLimiterEnable = pcmLimiterEnable; 2422fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2423fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2424fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (res == OK) { 2425fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev // optional parameters, will not cause configuration failure 2426fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation, 2427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &presentation, sizeof(presentation)); 2428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 2429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res); 2430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return res; 2432fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 2433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupAC3Codec( 2435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool encoder, int32_t numChannels, int32_t sampleRate) { 2436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = setupRawAudioFormat( 2437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 2438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder) { 2444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("AC3 encoding is not supported."); 2445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 2446fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2448fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_AUDIO_PARAM_ANDROID_AC3TYPE def; 2449fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(&def); 2450fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev def.nPortIndex = kPortIndexInput; 2451fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2452fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = mOMX->getParameter( 2453fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mNode, 2454fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 2455fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev &def, 2456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sizeof(def)); 2457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nChannels = numChannels; 2463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nSampleRate = sampleRate; 2464fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->setParameter( 2466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, 2467fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 2468fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev &def, 2469fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev sizeof(def)); 2470fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 2471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2472fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatus_t ACodec::setupEAC3Codec( 2473fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev bool encoder, int32_t numChannels, int32_t sampleRate) { 2474fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev status_t err = setupRawAudioFormat( 2475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 2476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder) { 2482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("EAC3 encoding is not supported."); 2483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 2484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def; 2487fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(&def); 2488fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev def.nPortIndex = kPortIndexInput; 2489fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2490fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = mOMX->getParameter( 2491fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mNode, 2492fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 2493fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev &def, 2494fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev sizeof(def)); 2495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2496fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 2497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nChannels = numChannels; 2501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nSampleRate = sampleRate; 2502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->setParameter( 2504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, 2505fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 2506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &def, 2507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sizeof(def)); 2508fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 2509fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2510fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate( 2511fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev bool isAMRWB, int32_t bps) { 2512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (isAMRWB) { 2513fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (bps <= 6600) { 2514fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OMX_AUDIO_AMRBandModeWB0; 2515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 8850) { 2516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeWB1; 2517fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else if (bps <= 12650) { 2518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeWB2; 2519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 14250) { 2520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeWB3; 2521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 15850) { 2522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeWB4; 2523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 18250) { 2524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeWB5; 2525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 19850) { 2526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeWB6; 2527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 23050) { 2528fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OMX_AUDIO_AMRBandModeWB7; 2529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2530fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2531fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev // 23850 bps 2532fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OMX_AUDIO_AMRBandModeWB8; 2533fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else { // AMRNB 2534fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (bps <= 4750) { 2535fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OMX_AUDIO_AMRBandModeNB0; 2536fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else if (bps <= 5150) { 2537fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OMX_AUDIO_AMRBandModeNB1; 2538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 5900) { 2539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeNB2; 2540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 6700) { 2541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeNB3; 2542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 7400) { 2543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeNB4; 2544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (bps <= 7950) { 2545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeNB5; 2546fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else if (bps <= 10200) { 2547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_AUDIO_AMRBandModeNB6; 2548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2549fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2550fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev // 12200 bps 2551fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OMX_AUDIO_AMRBandModeNB7; 2552fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2554fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2555fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) { 2556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_AMRTYPE def; 2557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 2558fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput; 2559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = 2561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 2568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate); 2569fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 2571fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2572fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2573fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 2574fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return err; 2575fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 2576fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2577fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return setupRawAudioFormat( 2578fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev encoder ? kPortIndexInput : kPortIndexOutput, 2579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright isWAMR ? 16000 : 8000 /* sampleRate */, 2580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 1 /* numChannels */); 2581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) { 2584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (encoder) { 2585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 2586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2587fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return setupRawAudioFormat( 2589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright kPortIndexInput, sampleRate, numChannels); 2590fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 2591fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2592fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatus_t ACodec::setupFlacCodec( 2593fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) { 2594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2595fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (encoder) { 2596fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_AUDIO_PARAM_FLACTYPE def; 2597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 2598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = kPortIndexOutput; 2599fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 2600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // configure compression level 2601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def)); 2602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err); 2604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nCompressionLevel = compressionLevel; 2607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def)); 2608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err); 2610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return setupRawAudioFormat( 2615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder ? kPortIndexInput : kPortIndexOutput, 2616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sampleRate, 2617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright numChannels); 2618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupRawAudioFormat( 2621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 2622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_PORTDEFINITIONTYPE def; 2623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 2624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = portIndex; 2625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 2627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 2634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 2636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 2643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&pcmParams); 2644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pcmParams.nPortIndex = portIndex; 2645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 2647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pcmParams.nChannels = numChannels; 2654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pcmParams.eNumData = OMX_NumericalDataSigned; 2655489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke pcmParams.bInterleaved = OMX_TRUE; 2656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pcmParams.nBitPerSample = 16; 2657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pcmParams.nSamplingRate = sampleRate; 2658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 2659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) { 2661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_ErrorNone; 2662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->setParameter( 2665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::configureTunneledVideoPlayback( 2669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) { 2670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright native_handle_t* sidebandHandle; 2671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->configureVideoTunnelMode( 2673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle); 2674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2675489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke ALOGE("configureVideoTunnelMode failed! (err %d).", err); 2676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2678489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke 2679489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle); 2680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", 2682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sidebandHandle, err); 2683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 2687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setVideoPortFormatType( 2690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 portIndex, 2691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CODINGTYPE compressionFormat, 2692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_COLOR_FORMATTYPE colorFormat, 2693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool usingNativeBuffers) { 2694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_PORTFORMATTYPE format; 2695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&format); 2696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright format.nPortIndex = portIndex; 2697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright format.nIndex = 0; 2698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool found = false; 2699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 index = 0; 2701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (;;) { 2702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright format.nIndex = index; 2703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 2704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoPortFormat, 2705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &format, sizeof(format)); 2706489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke 2707489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke if (err != OK) { 2708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // substitute back flexible color format to codec supported format 2712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 flexibleEquivalent; 2713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (compressionFormat == OMX_VIDEO_CodingUnused 2714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && isFlexibleColorFormat( 2715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent) 2716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && colorFormat == flexibleEquivalent) { 2717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("[%s] using color format %#x in place of %#x", 2718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), format.eColorFormat, colorFormat); 2719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright colorFormat = format.eColorFormat; 2720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // The following assertion is violated by TI's video decoder. 2723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // CHECK_EQ(format.nIndex, index); 2724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) { 2726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (portIndex == kPortIndexInput 2727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && colorFormat == format.eColorFormat) { 2728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // eCompressionFormat does not seem right. 2729489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke found = true; 2730489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke break; 2731489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke } 2732489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke if (portIndex == kPortIndexOutput 2733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && compressionFormat == format.eCompressionFormat) { 2734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // eColorFormat does not seem right. 2735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright found = true; 2736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (format.eCompressionFormat == compressionFormat 2741489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke && format.eColorFormat == colorFormat) { 2742489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke found = true; 2743489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke break; 2744489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke } 2745489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke 2746489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke ++index; 2747489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke } 2748489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke 2749489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke if (!found) { 2750489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke return UNKNOWN_ERROR; 2751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->setParameter( 2754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoPortFormat, 2755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &format, sizeof(format)); 2756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Set optimal output format. OMX component lists output formats in the order 2761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// of preference, but this got more complicated since the introduction of flexible 2762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// YUV formats. We support a legacy behavior for applications that do not use 2763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// surface output, do not specify an output format, but expect a "usable" standard 2764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// OMX format. SW readable and standard formats must be flex-YUV. 2765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// 2766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Suggested preference order: 2767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// - optimal format for texture rendering (mediaplayer behavior) 2768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// - optimal SW readable & texture renderable format (flex-YUV support) 2769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// - optimal SW readable non-renderable format (flex-YUV bytebuffer support) 2770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// - legacy "usable" standard formats 2771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// 2772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// For legacy support, we prefer a standard format, but will settle for a SW readable 2773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// flex-YUV format. 2774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) { 2775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat; 2776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&format); 2777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright format.nPortIndex = kPortIndexOutput; 2778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&legacyFormat); 2780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // this field will change when we find a suitable legacy format 2781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright legacyFormat.eColorFormat = OMX_COLOR_FormatUnused; 2782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (OMX_U32 index = 0; ; ++index) { 2784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright format.nIndex = index; 2785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 2786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoPortFormat, 2787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &format, sizeof(format)); 2788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // no more formats, pick legacy format if found 2790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) { 2791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright memcpy(&format, &legacyFormat, sizeof(format)); 2792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) { 2797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_ErrorBadParameter; 2798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!getLegacyFlexibleFormat) { 2800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // standard formats that were exposed to users before 2803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar 2804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar 2805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 2806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar 2807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 2808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 2809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // find best legacy non-standard format 2811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 flexibleEquivalent; 2812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused 2813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && isFlexibleColorFormat( 2814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */, 2815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &flexibleEquivalent) 2816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) { 2817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright memcpy(&legacyFormat, &format, sizeof(format)); 2818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->setParameter( 2821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoPortFormat, 2822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &format, sizeof(format)); 2823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const struct VideoCodingMapEntry { 2826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *mMime; 2827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CODINGTYPE mVideoCodingType; 2828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} kVideoCodingMapEntry[] = { 2829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC }, 2830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC }, 2831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 }, 2832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 }, 2833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 }, 2834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 }, 2835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 }, 2836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}; 2837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic status_t GetVideoCodingTypeFromMime( 2839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *mime, OMX_VIDEO_CODINGTYPE *codingType) { 2840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; 2841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 2842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ++i) { 2843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) { 2844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *codingType = kVideoCodingMapEntry[i].mVideoCodingType; 2845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 2846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *codingType = OMX_VIDEO_CodingUnused; 2850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return ERROR_UNSUPPORTED; 2852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic status_t GetMimeTypeForVideoCoding( 2855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CODINGTYPE codingType, AString *mime) { 2856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; 2857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 2858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ++i) { 2859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) { 2860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *mime = kVideoCodingMapEntry[i].mMime; 2861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 2862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mime->clear(); 2866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return ERROR_UNSUPPORTED; 2868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupVideoDecoder( 2871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) { 2872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t width, height; 2873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("width", &width) 2874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("height", &height)) { 2875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 2876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CODINGTYPE compressionFormat; 2879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 2880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setVideoPortFormatType( 2886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 2887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 2893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("color-format", &tmp)) { 2894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_COLOR_FORMATTYPE colorFormat = 2895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<OMX_COLOR_FORMATTYPE>(tmp); 2896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setVideoPortFormatType( 2897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow); 2898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("[%s] does not support color format %d", 2900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), colorFormat); 2901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */); 2902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 2904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */); 2905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t frameRateInt; 2912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright float frameRateFloat; 2913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findFloat("frame-rate", &frameRateFloat)) { 2914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("frame-rate", &frameRateInt)) { 2915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright frameRateInt = -1; 2916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright frameRateFloat = (float)frameRateInt; 2918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setVideoFormatOnPort( 2921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright kPortIndexInput, width, height, compressionFormat, frameRateFloat); 2922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setVideoFormatOnPort( 2928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused); 2929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 2935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 2936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) { 2938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 2939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("color-format", &tmp)) { 2940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 2941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_COLOR_FORMATTYPE colorFormat = 2944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<OMX_COLOR_FORMATTYPE>(tmp); 2945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = setVideoPortFormatType( 2947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat); 2948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] does not support color format %d", 2951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), colorFormat); 2952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright /* Input port configuration */ 2957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_PORTDEFINITIONTYPE def; 2959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 2960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = kPortIndexInput; 2964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 2966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 2969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 2970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t width, height, bitrate; 2973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("width", &width) 2974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("height", &height) 2975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("bitrate", &bitrate)) { 2976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 2977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nFrameWidth = width; 2980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nFrameHeight = height; 2981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t stride; 2983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("stride", &stride)) { 2984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright stride = width; 2985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nStride = stride; 2988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t sliceHeight; 2990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("slice-height", &sliceHeight)) { 2991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sliceHeight = height; 2992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 2993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nSliceHeight = sliceHeight; 2995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2; 2997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 2998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright float frameRate; 2999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findFloat("frame-rate", &frameRate)) { 3000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 3001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("frame-rate", &tmp)) { 3002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright frameRate = (float)tmp; 3005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mTimePerFrameUs = (int64_t) (1000000.0f / frameRate); 3006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 3009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 3010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // this is redundant as it was already set up in setVideoPortFormatType 3011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // FIXME for now skip this only for flexible YUV formats 3012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (colorFormat != OMX_COLOR_FormatYUV420Flexible) { 3013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->eColorFormat = colorFormat; 3014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 3017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] failed to set input port definition parameters.", 3021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str()); 3022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright /* Output port configuration */ 3027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CODINGTYPE compressionFormat; 3029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 3030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setVideoPortFormatType( 3036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); 3037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] does not support compression format %d", 3040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), compressionFormat); 3041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = kPortIndexOutput; 3046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 3048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nFrameWidth = width; 3055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nFrameHeight = height; 3056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->xFramerate = 0; 3057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nBitrate = bitrate; 3058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->eCompressionFormat = compressionFormat; 3059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->eColorFormat = OMX_COLOR_FormatUnused; 3060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 3062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] failed to set output port definition parameters.", 3066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str()); 3067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (compressionFormat) { 3072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingMPEG4: 3073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupMPEG4EncoderParameters(msg); 3074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingH263: 3077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupH263EncoderParameters(msg); 3078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingAVC: 3081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupAVCEncoderParameters(msg); 3082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingHEVC: 3085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupHEVCEncoderParameters(msg); 3086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingVP8: 3089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingVP9: 3090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setupVPXEncoderParameters(msg); 3091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 3094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 3098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("setupVideoEncoder succeeded"); 3099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { 3105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; 3106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 3107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = kPortIndexOutput; 3108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode); 3110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || 3112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 3113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t mbs; 3114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { 3115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nCirMBs = mbs; 3118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || 3121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 3122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t mbs; 3123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { 3124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nAirMBs = mbs; 3127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t ref; 3129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { 3130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nAirRef = ref; 3133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->setParameter( 3136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoIntraRefresh, 3137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ¶ms, sizeof(params)); 3138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 3142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (iFramesInterval < 0) { 3143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return 0xFFFFFFFF; 3144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (iFramesInterval == 0) { 3145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return 0; 3146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 ret = frameRate * iFramesInterval; 3148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return ret; 3149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) { 3152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 3153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("bitrate-mode", &tmp)) { 3154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OMX_Video_ControlRateVariable; 3155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp); 3158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) { 3161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t bitrate, iFrameInterval; 3162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("bitrate", &bitrate) 3163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 3164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright float frameRate; 3170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findFloat("frame-rate", &frameRate)) { 3171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 3172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("frame-rate", &tmp)) { 3173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright frameRate = (float)tmp; 3176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 3179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&mpeg4type); 3180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nPortIndex = kPortIndexOutput; 3181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 3183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 3184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nSliceHeaderSpacing = 0; 3190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.bSVH = OMX_FALSE; 3191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.bGov = OMX_FALSE; 3192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nAllowedPictureTypes = 3194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 3195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 3197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mpeg4type.nPFrames == 0) { 3198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 3199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nBFrames = 0; 3201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nIDCVLCThreshold = 0; 3202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.bACPred = OMX_TRUE; 3203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nMaxPacketSize = 256; 3204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nTimeIncRes = 1000; 3205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.nHeaderExtension = 0; 3206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.bReversibleVLC = OMX_FALSE; 3207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t profile; 3209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("profile", &profile)) { 3210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t level; 3211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("level", &level)) { 3212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = verifySupportForProfileAndLevel(profile, level); 3216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile); 3222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level); 3223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 3226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 3227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = configureBitrate(bitrate, bitrateMode); 3233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return setupErrorCorrectionParameters(); 3239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { 3242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t bitrate, iFrameInterval; 3243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("bitrate", &bitrate) 3244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 3245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright float frameRate; 3251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findFloat("frame-rate", &frameRate)) { 3252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 3253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("frame-rate", &tmp)) { 3254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright frameRate = (float)tmp; 3257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_H263TYPE h263type; 3260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&h263type); 3261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.nPortIndex = kPortIndexOutput; 3262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 3264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 3265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.nAllowedPictureTypes = 3271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 3272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 3274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (h263type.nPFrames == 0) { 3275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 3276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.nBFrames = 0; 3278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t profile; 3280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("profile", &profile)) { 3281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t level; 3282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("level", &level)) { 3283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = verifySupportForProfileAndLevel(profile, level); 3287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile); 3293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level); 3294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.bPLUSPTYPEAllowed = OMX_FALSE; 3297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.bForceRoundingTypeToZero = OMX_FALSE; 3298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.nPictureHeaderRepetition = 0; 3299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h263type.nGOBHeaderInterval = 0; 3300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 3302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 3303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = configureBitrate(bitrate, bitrateMode); 3309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return setupErrorCorrectionParameters(); 3315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// static 3318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor( 3319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int width, int height, int rate, int bitrate, 3320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_AVCPROFILETYPE profile) { 3321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // convert bitrate to main/baseline profile kbps equivalent 3322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (profile) { 3323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_AVCProfileHigh10: 3324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bitrate = divUp(bitrate, 3000); break; 3325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_AVCProfileHigh: 3326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bitrate = divUp(bitrate, 1250); break; 3327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 3328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bitrate = divUp(bitrate, 1000); break; 3329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // convert size and rate to MBs 3332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright width = divUp(width, 16); 3333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright height = divUp(height, 16); 3334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int mbs = width * height; 3335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rate *= mbs; 3336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int maxDimension = max(width, height); 3337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static const int limits[][5] = { 3339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright /* MBps MB dim bitrate level */ 3340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 1485, 99, 28, 64, OMX_VIDEO_AVCLevel1 }, 3341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 1485, 99, 28, 128, OMX_VIDEO_AVCLevel1b }, 3342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 3000, 396, 56, 192, OMX_VIDEO_AVCLevel11 }, 3343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 6000, 396, 56, 384, OMX_VIDEO_AVCLevel12 }, 3344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 11880, 396, 56, 768, OMX_VIDEO_AVCLevel13 }, 3345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 11880, 396, 56, 2000, OMX_VIDEO_AVCLevel2 }, 3346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 19800, 792, 79, 4000, OMX_VIDEO_AVCLevel21 }, 3347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 20250, 1620, 113, 4000, OMX_VIDEO_AVCLevel22 }, 3348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 40500, 1620, 113, 10000, OMX_VIDEO_AVCLevel3 }, 3349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 108000, 3600, 169, 14000, OMX_VIDEO_AVCLevel31 }, 3350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 216000, 5120, 202, 20000, OMX_VIDEO_AVCLevel32 }, 3351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 245760, 8192, 256, 20000, OMX_VIDEO_AVCLevel4 }, 3352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 245760, 8192, 256, 50000, OMX_VIDEO_AVCLevel41 }, 3353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 522240, 8704, 263, 50000, OMX_VIDEO_AVCLevel42 }, 3354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5 }, 3355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 }, 3356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 }, 3357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright }; 3358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < ARRAY_SIZE(limits); i++) { 3360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const int (&limit)[5] = limits[i]; 3361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2] 3362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && bitrate <= limit[3]) { 3363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return limit[4]; 3364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return 0; 3367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { 3370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t bitrate, iFrameInterval; 3371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("bitrate", &bitrate) 3372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 3373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright float frameRate; 3379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findFloat("frame-rate", &frameRate)) { 3380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 3381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("frame-rate", &tmp)) { 3382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright frameRate = (float)tmp; 3385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = OK; 3388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t intraRefreshMode = 0; 3389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { 3390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); 3391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", 3393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err, intraRefreshMode); 3394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_AVCTYPE h264type; 3399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&h264type); 3400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.nPortIndex = kPortIndexOutput; 3401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 3403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 3404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.nAllowedPictureTypes = 3410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 3411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t profile; 3413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("profile", &profile)) { 3414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t level; 3415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("level", &level)) { 3416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = verifySupportForProfileAndLevel(profile, level); 3420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile); 3426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level); 3427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // XXX 3430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) { 3431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("Use baseline profile instead of %d for AVC recording", 3432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.eProfile); 3433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 3434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 3437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.nSliceHeaderSpacing = 0; 3438489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bUseHadamard = OMX_TRUE; 3439489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.nRefFrames = 1; 3440489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.nBFrames = 0; 3441489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 3442489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke if (h264type.nPFrames == 0) { 3443489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 3444489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke } 3445489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.nRefIdx10ActiveMinus1 = 0; 3446489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.nRefIdx11ActiveMinus1 = 0; 3447489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bEntropyCodingCABAC = OMX_FALSE; 3448489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bWeightedPPrediction = OMX_FALSE; 3449489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bconstIpred = OMX_FALSE; 3450489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bDirect8x8Inference = OMX_FALSE; 3451489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bDirectSpatialTemporal = OMX_FALSE; 3452489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.nCabacInitIdc = 0; 3453489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke } 3454489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke 3455489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke if (h264type.nBFrames != 0) { 3456489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 3457489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke } 3458489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke 3459489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bEnableUEP = OMX_FALSE; 3460489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bEnableFMO = OMX_FALSE; 3461489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke h264type.bEnableASO = OMX_FALSE; 3462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.bEnableRS = OMX_FALSE; 3463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.bFrameMBsOnly = OMX_TRUE; 3464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.bMBAFF = OMX_FALSE; 3465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 3466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 3468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 3469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return configureBitrate(bitrate, bitrateMode); 3475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) { 3478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t bitrate, iFrameInterval; 3479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("bitrate", &bitrate) 3480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 3481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3486fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev float frameRate; 3487fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (!msg->findFloat("frame-rate", &frameRate)) { 3488fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev int32_t tmp; 3489fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (!msg->findInt32("frame-rate", &tmp)) { 3490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright frameRate = (float)tmp; 3493fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3495fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_VIDEO_PARAM_HEVCTYPE hevcType; 3496fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(&hevcType); 3497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright hevcType.nPortIndex = kPortIndexOutput; 3498fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = OK; 3500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 3501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 3502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t profile; 3507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findInt32("profile", &profile)) { 3508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t level; 3509fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (!msg->findInt32("level", &level)) { 3510fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return INVALID_OPERATION; 3511fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3512fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3513fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = verifySupportForProfileAndLevel(profile, level); 3514fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 3515fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return err; 3516fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3517fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile); 3519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level); 3520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3521fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // TODO: Need OMX structure definition for setting iFrameInterval 3523fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3524fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = mOMX->setParameter( 3525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 3526fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 3527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return configureBitrate(bitrate, bitrateMode); 3531fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 3532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3533fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) { 3534fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev int32_t bitrate; 3535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t iFrameInterval = 0; 3536fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev size_t tsLayers = 0; 3537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern = 3538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_VPXTemporalLayerPatternNone; 3539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static const uint32_t kVp8LayerRateAlloction 3540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] 3541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = { 3542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright {100, 100, 100}, // 1 layer 3543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 60, 100, 100}, // 2 layers {60%, 40%} 3544fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev { 40, 60, 100}, // 3 layers {40%, 20%, 40%} 3545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright }; 3546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("bitrate", &bitrate)) { 3547fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return INVALID_OPERATION; 3548fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3549fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev msg->findInt32("i-frame-interval", &iFrameInterval); 3550fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3551fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright float frameRate; 3554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findFloat("frame-rate", &frameRate)) { 3555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 3556fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (!msg->findInt32("frame-rate", &tmp)) { 3557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return INVALID_OPERATION; 3558fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3559fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev frameRate = (float)tmp; 3560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3561fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3562fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev AString tsSchema; 3563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findString("ts-schema", &tsSchema)) { 3564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (tsSchema == "webrtc.vp8.1-layer") { 3565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright tsLayers = 1; 3567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (tsSchema == "webrtc.vp8.2-layer") { 3568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright tsLayers = 2; 3570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (tsSchema == "webrtc.vp8.3-layer") { 3571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright tsLayers = 3; 3573fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else { 3574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str()); 3575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3576fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3577fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3578fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 3579fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(&vp8type); 3580fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev vp8type.nPortIndex = kPortIndexOutput; 3581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 3582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 3583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &vp8type, sizeof(vp8type)); 3584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3585fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err == OK) { 3586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (iFrameInterval > 0) { 3587fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate); 3588fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright vp8type.eTemporalPattern = pattern; 3590fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev vp8type.nTemporalLayerCount = tsLayers; 3591fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (tsLayers > 0) { 3592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) { 3593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright vp8type.nTemporalLayerBitrateRatio[i] = 3594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright kVp8LayerRateAlloction[tsLayers - 1][i]; 3595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (bitrateMode == OMX_Video_ControlRateConstant) { 3598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright vp8type.nMinQuantizer = 2; 3599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright vp8type.nMaxQuantizer = 63; 3600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3602fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev err = mOMX->setParameter( 3603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 3604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &vp8type, sizeof(vp8type)); 3605fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 3606fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ALOGW("Extended VP8 parameters set failed: %d", err); 3607fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3608fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3609fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return configureBitrate(bitrate, bitrateMode); 3611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::verifySupportForProfileAndLevel( 3614fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev int32_t profile, int32_t level) { 3615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 3616fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(¶ms); 3617fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev params.nPortIndex = kPortIndexOutput; 3618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3619fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev for (params.nProfileIndex = 0;; ++params.nProfileIndex) { 3620fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev status_t err = mOMX->getParameter( 3621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, 3622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_IndexParamVideoProfileLevelQuerySupported, 3623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ¶ms, 3624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sizeof(params)); 3625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t supportedProfile = static_cast<int32_t>(params.eProfile); 3631fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev int32_t supportedLevel = static_cast<int32_t>(params.eLevel); 3632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (profile == supportedProfile && level <= supportedLevel) { 3634fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return OK; 3635fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3636fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3637fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 3638fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::configureBitrate( 3640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) { 3641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 3642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&bitrateType); 3643fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev bitrateType.nPortIndex = kPortIndexOutput; 3644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3645fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev status_t err = mOMX->getParameter( 3646fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mNode, OMX_IndexParamVideoBitrate, 3647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &bitrateType, sizeof(bitrateType)); 3648fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3649fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 3650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bitrateType.eControlRate = bitrateMode; 3654fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev bitrateType.nTargetBitrate = bitrate; 3655fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->setParameter( 3657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoBitrate, 3658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &bitrateType, sizeof(bitrateType)); 3659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3661fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatus_t ACodec::setupErrorCorrectionParameters() { 3662fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 3663fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev InitOMXParams(&errorCorrectionType); 3664fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev errorCorrectionType.nPortIndex = kPortIndexOutput; 3665fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 3667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoErrorCorrection, 3668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &errorCorrectionType, sizeof(errorCorrectionType)); 3669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3670fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (err != OK) { 3671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; // Optional feature. Ignore this failure 3672fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 3673fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright errorCorrectionType.bEnableHEC = OMX_FALSE; 3675fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev errorCorrectionType.bEnableResync = OMX_TRUE; 3676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright errorCorrectionType.nResynchMarkerSpacing = 256; 3677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 3678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright errorCorrectionType.bEnableRVLC = OMX_FALSE; 3679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->setParameter( 3681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamVideoErrorCorrection, 3682fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev &errorCorrectionType, sizeof(errorCorrectionType)); 3683fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 3684fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3685fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevstatus_t ACodec::setVideoFormatOnPort( 3686fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_U32 portIndex, 3687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat, 3688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright float frameRate) { 3689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_PORTDEFINITIONTYPE def; 3690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 3691fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev def.nPortIndex = portIndex; 3692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3693fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 3694fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 3695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 3696fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (portIndex == kPortIndexInput) { 3702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // XXX Need a (much) better heuristic to compute input buffer sizes. 3703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const size_t X = 64 * 1024; 3704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (def.nBufferSize < X) { 3705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nBufferSize = X; 3706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (def.eDomain != OMX_PortDomainVideo) { 3710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain); 3711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return FAILED_TRANSACTION; 3712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nFrameWidth = width; 3715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->nFrameHeight = height; 3716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (portIndex == kPortIndexInput) { 3718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->eCompressionFormat = compressionFormat; 3719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->eColorFormat = OMX_COLOR_FormatUnused; 3720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (frameRate >= 0) { 3721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 3722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->setParameter( 3726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::initNativeWindow() { 3732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mNativeWindow != NULL) { 3733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 3734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 3737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 3738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightsize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const { 3741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t n = 0; 3742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 3744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const BufferInfo &info = mBuffers[portIndex].itemAt(i); 3745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) { 3747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ++n; 3748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return n; 3752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightsize_t ACodec::countBuffersOwnedByNativeWindow() const { 3755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t n = 0; 3756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 3758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i); 3759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ++n; 3762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return n; 3766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { 3769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mNativeWindow == NULL) { 3770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 3771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers 3774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && dequeueBufferFromNativeWindow() != NULL) { 3775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // these buffers will be submitted as regular buffers; account for this 3776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) { 3777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright --mMetadataBuffersToSubmit; 3778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::allYourBuffersAreBelongToUs( 3783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 portIndex) { 3784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 3785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 3786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus != BufferInfo::OWNED_BY_US 3788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Buffer %u on port %u still has status %d", 3790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), 3791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mBufferID, portIndex, info->mStatus); 3792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 3793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 3797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::allYourBuffersAreBelongToUs() { 3800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return allYourBuffersAreBelongToUs(kPortIndexInput) 3801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && allYourBuffersAreBelongToUs(kPortIndexOutput); 3802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::deferMessage(const sp<AMessage> &msg) { 3805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDeferredQueue.push_back(msg); 3806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::processDeferredMessages() { 3809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright List<sp<AMessage> > queue = mDeferredQueue; 3810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDeferredQueue.clear(); 3811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright List<sp<AMessage> >::iterator it = queue.begin(); 3813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright while (it != queue.end()) { 3814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright onMessageReceived(*it++); 3815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// static 3819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams ¶ms) { 3820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright MediaImage &image = params.sMediaImage; 3821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright memset(&image, 0, sizeof(image)); 3822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 3824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mNumPlanes = 0; 3825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat; 3827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mWidth = params.nFrameWidth; 3828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mHeight = params.nFrameHeight; 3829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // only supporting YUV420 3831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (fmt != OMX_COLOR_FormatYUV420Planar && 3832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fmt != OMX_COLOR_FormatYUV420PackedPlanar && 3833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fmt != OMX_COLOR_FormatYUV420SemiPlanar && 3834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar && 3835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fmt != HAL_PIXEL_FORMAT_YV12) { 3836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("do not know color format 0x%x = %d", fmt, fmt); 3837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 3838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // TEMPORARY FIX for some vendors that advertise sliceHeight as 0 3841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (params.nStride != 0 && params.nSliceHeight == 0) { 3842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("using sliceHeight=%u instead of what codec advertised (=0)", 3843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nFrameHeight); 3844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nSliceHeight = params.nFrameHeight; 3845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // we need stride and slice-height to be non-zero 3848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (params.nStride == 0 || params.nSliceHeight == 0) { 3849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u", 3850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fmt, fmt, params.nStride, params.nSliceHeight); 3851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 3852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // set-up YUV format 3855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV; 3856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mNumPlanes = 3; 3857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mBitDepth = 8; 3858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.Y].mOffset = 0; 3859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.Y].mColInc = 1; 3860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.Y].mRowInc = params.nStride; 3861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.Y].mHorizSubsampling = 1; 3862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.Y].mVertSubsampling = 1; 3863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch ((int)fmt) { 3865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case HAL_PIXEL_FORMAT_YV12: 3866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (params.bUsingNativeBuffers) { 3867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t ystride = align(params.nStride, 16); 3868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t cstride = align(params.nStride / 2, 16); 3869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.Y].mRowInc = ystride; 3870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mOffset = ystride * params.nSliceHeight; 3872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mColInc = 1; 3873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mRowInc = cstride; 3874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mHorizSubsampling = 2; 3875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mVertSubsampling = 2; 3876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset 3878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright + (cstride * params.nSliceHeight / 2); 3879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mColInc = 1; 3880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mRowInc = cstride; 3881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mHorizSubsampling = 2; 3882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mVertSubsampling = 2; 3883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 3885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // fall through as YV12 is used for YUV420Planar by some codecs 3886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_COLOR_FormatYUV420Planar: 3889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_COLOR_FormatYUV420PackedPlanar: 3890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight; 3891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mColInc = 1; 3892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mRowInc = params.nStride / 2; 3893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mHorizSubsampling = 2; 3894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mVertSubsampling = 2; 3895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset 3897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright + (params.nStride * params.nSliceHeight / 4); 3898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mColInc = 1; 3899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mRowInc = params.nStride / 2; 3900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mHorizSubsampling = 2; 3901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mVertSubsampling = 2; 3902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_COLOR_FormatYUV420SemiPlanar: 3905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder 3906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_COLOR_FormatYUV420PackedSemiPlanar: 3907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // NV12 3908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight; 3909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mColInc = 2; 3910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mRowInc = params.nStride; 3911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mHorizSubsampling = 2; 3912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.U].mVertSubsampling = 2; 3913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1; 3915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mColInc = 2; 3916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mRowInc = params.nStride; 3917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mHorizSubsampling = 2; 3918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright image.mPlane[image.V].mVertSubsampling = 2; 3919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 3920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 3922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright TRESPASS(); 3923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 3925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// static 3928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::describeColorFormat( 3929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const sp<IOMX> &omx, IOMX::node_id node, 3930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DescribeColorFormatParams &describeParams) 3931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright{ 3932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_INDEXTYPE describeColorFormatIndex; 3933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (omx->getExtensionIndex( 3934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright node, "OMX.google.android.index.describeColorFormat", 3935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &describeColorFormatIndex) != OK || 3936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright omx->getParameter( 3937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright node, describeColorFormatIndex, 3938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &describeParams, sizeof(describeParams)) != OK) { 3939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return describeDefaultColorFormat(describeParams); 3940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return describeParams.sMediaImage.mType != 3942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 3943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// static 3946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::isFlexibleColorFormat( 3947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const sp<IOMX> &omx, IOMX::node_id node, 3948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) { 3949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DescribeColorFormatParams describeParams; 3950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&describeParams); 3951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 3952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // reasonable dummy values 3953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.nFrameWidth = 128; 3954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.nFrameHeight = 128; 3955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.nStride = 128; 3956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.nSliceHeight = 128; 3957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers; 3958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(flexibleEquivalent != NULL); 3960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!describeColorFormat(omx, node, describeParams)) { 3962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 3963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const MediaImage &img = describeParams.sMediaImage; 3966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) { 3967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (img.mNumPlanes != 3 || 3968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright img.mPlane[img.Y].mHorizSubsampling != 1 || 3969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright img.mPlane[img.Y].mVertSubsampling != 1) { 3970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 3971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // YUV 420 3974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (img.mPlane[img.U].mHorizSubsampling == 2 3975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && img.mPlane[img.U].mVertSubsampling == 2 3976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && img.mPlane[img.V].mHorizSubsampling == 2 3977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && img.mPlane[img.V].mVertSubsampling == 2) { 3978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // possible flexible YUV420 format 3979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (img.mBitDepth <= 8) { 3980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible; 3981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 3982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 3986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 3987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) { 3989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output"; 3990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_PARAM_PORTDEFINITIONTYPE def; 3991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&def); 3992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright def.nPortIndex = portIndex; 3993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 3996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 3997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 3998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 3999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) { 4000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex); 4001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 4002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (def.eDomain) { 4005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_PortDomainVideo: 4006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch ((int)videoDef->eCompressionFormat) { 4009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingUnused: 4010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput)); 4012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 4013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("stride", videoDef->nStride); 4015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("slice-height", videoDef->nSliceHeight); 4016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("color-format", videoDef->eColorFormat); 4017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mNativeWindow == NULL) { 4019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright DescribeColorFormatParams describeParams; 4020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&describeParams); 4021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.eColorFormat = videoDef->eColorFormat; 4022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.nFrameWidth = videoDef->nFrameWidth; 4023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.nFrameHeight = videoDef->nFrameHeight; 4024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.nStride = videoDef->nStride; 4025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.nSliceHeight = videoDef->nSliceHeight; 4026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright describeParams.bUsingNativeBuffers = OMX_FALSE; 4027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (describeColorFormat(mOMX, mNode, describeParams)) { 4029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setBuffer( 4030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "image-data", 4031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ABuffer::CreateAsCopy( 4032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &describeParams.sMediaImage, 4033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sizeof(describeParams.sMediaImage))); 4034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright MediaImage *img = &describeParams.sMediaImage; 4036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] MediaImage { F(%ux%u) @%u+%u+%u @%u+%u+%u @%u+%u+%u }", 4037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mComponentName.c_str(), img->mWidth, img->mHeight, 4038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc, 4039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc, 4040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc); 4041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (portIndex != kPortIndexOutput) { 4045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // TODO: also get input crop 4046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_CONFIG_RECTTYPE rect; 4050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&rect); 4051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nPortIndex = portIndex; 4052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mOMX->getConfig( 4054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, 4055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (portIndex == kPortIndexOutput ? 4056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_IndexConfigCommonOutputCrop : 4057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_IndexConfigCommonInputCrop), 4058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &rect, sizeof(rect)) != OK) { 4059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nLeft = 0; 4060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nTop = 0; 4061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nWidth = videoDef->nFrameWidth; 4062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nHeight = videoDef->nFrameHeight; 4063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (rect.nLeft < 0 || 4066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nTop < 0 || 4067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nLeft + rect.nWidth > videoDef->nFrameWidth || 4068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nTop + rect.nHeight > videoDef->nFrameHeight) { 4069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)", 4070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nLeft, rect.nTop, 4071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight, 4072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright videoDef->nFrameWidth, videoDef->nFrameHeight); 4073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 4074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setRect( 4077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "crop", 4078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nLeft, 4079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nTop, 4080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nLeft + rect.nWidth - 1, 4081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright rect.nTop + rect.nHeight - 1); 4082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingVP8: 4087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_VIDEO_CodingVP9: 4088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 4090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(&vp8type); 4091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright vp8type.nPortIndex = kPortIndexOutput; 4092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mOMX->getParameter( 4093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, 4094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 4095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &vp8type, 4096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sizeof(vp8type)); 4097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 4099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright AString tsSchema = "none"; 4100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (vp8type.eTemporalPattern 4101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) { 4102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (vp8type.nTemporalLayerCount) { 4103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case 1: 4104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright tsSchema = "webrtc.vp8.1-layer"; 4106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case 2: 4109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright tsSchema = "webrtc.vp8.2-layer"; 4111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case 3: 4114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright tsSchema = "webrtc.vp8.3-layer"; 4116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 4119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("ts-schema", tsSchema); 4125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Fall through to set up mime. 4127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 4130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mIsEncoder ^ (portIndex == kPortIndexOutput)) { 4132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // should be CodingUnused 4133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Raw port video compression format is %s(%d)", 4134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright asString(videoDef->eCompressionFormat), 4135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright videoDef->eCompressionFormat); 4136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_VALUE; 4137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright AString mime; 4139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (GetMimeTypeForVideoCoding( 4140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright videoDef->eCompressionFormat, &mime) != OK) { 4141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", "application/octet-stream"); 4142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 4143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", mime.c_str()); 4144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("width", videoDef->nFrameWidth); 4149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("height", videoDef->nFrameHeight); 4150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] %s format is %s", mComponentName.c_str(), 4151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright portIndex == kPortIndexInput ? "input" : "output", 4152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->debugString().c_str()); 4153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_PortDomainAudio: 4158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 4160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch ((int)audioDef->eEncoding) { 4162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingPCM: 4163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_PCMMODETYPE params; 4165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (params.nChannels <= 0 4175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || (params.nChannels != 1 && !params.bInterleaved) 4176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || params.nBitPerSample != 16u 4177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || params.eNumData != OMX_NumericalDataSigned 4178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || params.ePCMMode != OMX_AUDIO_PCMModeLinear) { 4179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ", 4180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nChannels, 4181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.bInterleaved ? " interleaved" : "", 4182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nBitPerSample, 4183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright asString(params.eNumData), params.eNumData, 4184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright asString(params.ePCMMode), params.ePCMMode); 4185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return FAILED_TRANSACTION; 4186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 4189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSamplingRate); 4191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mChannelMaskPresent) { 4193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-mask", mChannelMask); 4194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingAAC: 4199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_AACPROFILETYPE params; 4201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioAac, ¶ms, sizeof(params)); 4206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 4211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSampleRate); 4213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingAMR: 4217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_AMRTYPE params; 4219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioAmr, ¶ms, sizeof(params)); 4224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", 1); 4229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) { 4230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 4231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", 16000); 4232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 4233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 4234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", 8000); 4235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingFLAC: 4240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_FLACTYPE params; 4242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioFlac, ¶ms, sizeof(params)); 4247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC); 4252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSampleRate); 4254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingMP3: 4258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_MP3TYPE params; 4260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioMp3, ¶ms, sizeof(params)); 4265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG); 4270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSampleRate); 4272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingVORBIS: 4276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_VORBISTYPE params; 4278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioVorbis, ¶ms, sizeof(params)); 4283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS); 4288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSampleRate); 4290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingAndroidAC3: 4294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_ANDROID_AC3TYPE params; 4296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 4301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ¶ms, sizeof(params)); 4302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3); 4307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSampleRate); 4309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingAndroidEAC3: 4313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params; 4315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 4320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ¶ms, sizeof(params)); 4321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3); 4326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSampleRate); 4328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingAndroidOPUS: 4332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params; 4334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, 4339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ¶ms, sizeof(params)); 4340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS); 4345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSampleRate); 4347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingG711: 4351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_PCMMODETYPE params; 4353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const char *mime = NULL; 4363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) { 4364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW; 4365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) { 4366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW; 4367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear 4368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mime = MEDIA_MIMETYPE_AUDIO_RAW; 4369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", mime); 4371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSamplingRate); 4373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case OMX_AUDIO_CodingGSMFR: 4377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_AUDIO_PARAM_PCMMODETYPE params; 4379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = portIndex; 4381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mOMX->getParameter( 4383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 4385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return err; 4386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM); 4389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("channel-count", params.nChannels); 4390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("sample-rate", params.nSamplingRate); 4391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 4395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Unsupported audio coding: %s(%d)\n", 4396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright asString(audioDef->eEncoding), audioDef->eEncoding); 4397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_TYPE; 4398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 4403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain); 4404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BAD_TYPE; 4405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return OK; 4408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::sendFormatChange(const sp<AMessage> &reply) { 4411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mBaseOutputFormat->dup(); 4412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", kWhatOutputFormatChanged); 4413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (getPortFormat(kPortIndexOutput, notify) != OK) { 4415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str()); 4416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 4417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright AString mime; 4420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(notify->findString("mime", &mime)); 4421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t left, top, right, bottom; 4423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mime == MEDIA_MIMETYPE_VIDEO_RAW && 4424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNativeWindow != NULL && 4425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->findRect("crop", &left, &top, &right, &bottom)) { 4426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // notify renderer of the crop change 4427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // NOTE: native window uses extended right-bottom coordinate 4428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright reply->setRect("crop", left, top, right + 1, bottom + 1); 4429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW && 4430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (mEncoderDelay || mEncoderPadding)) { 4431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t channelCount; 4432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(notify->findInt32("channel-count", &channelCount)); 4433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t frameSize = channelCount * sizeof(int16_t); 4434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mSkipCutBuffer != NULL) { 4435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t prevbufsize = mSkipCutBuffer->size(); 4436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (prevbufsize != 0) { 4437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 4438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mSkipCutBuffer = new SkipCutBuffer( 4441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mEncoderDelay * frameSize, 4442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mEncoderPadding * frameSize); 4443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 4446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mSentFormat = true; 4448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 4451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mNotify->dup(); 4452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", CodecBase::kWhatError); 4453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 4454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (internalError == UNKNOWN_ERROR) { // find better error code 4456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const status_t omxStatus = statusFromOMXError(error); 4457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (omxStatus != 0) { 4458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright internalError = omxStatus; 4459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 4460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("Invalid OMX error %#x", error); 4461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("err", internalError); 4464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error. 4465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 4466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 4469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightACodec::PortDescription::PortDescription() { 4471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t ACodec::requestIDRFrame() { 4474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!mIsEncoder) { 4475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return ERROR_UNSUPPORTED; 4476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_CONFIG_INTRAREFRESHVOPTYPE params; 4479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright InitOMXParams(¶ms); 4480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.nPortIndex = kPortIndexOutput; 4482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright params.IntraRefreshVOP = OMX_TRUE; 4483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mOMX->setConfig( 4485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mNode, 4486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_IndexConfigVideoIntraVOPRefresh, 4487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ¶ms, 4488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sizeof(params)); 4489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::PortDescription::addBuffer( 4492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::buffer_id id, const sp<ABuffer> &buffer) { 4493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBufferIDs.push_back(id); 4494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mBuffers.push_back(buffer); 4495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightsize_t ACodec::PortDescription::countBuffers() { 4498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mBufferIDs.size(); 4499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const { 4502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mBufferIDs.itemAt(index); 4503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightsp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const { 4506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return mBuffers.itemAt(index); 4507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 4510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 4512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright : AState(parentState), 4513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec(codec) { 4514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 4517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 /* portIndex */) { 4518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return KEEP_BUFFERS; 4519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 4522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (msg->what()) { 4523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case kWhatInputBufferFilled: 4524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright onInputBufferFilled(msg); 4526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case kWhatOutputBufferDrained: 4530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright onOutputBufferDrained(msg); 4532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatOMXMessageList: 4536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return checkOMXMessage(msg) ? onOMXMessageList(msg) : true; 4538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatOMXMessageItem: 4541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // no need to check as we already did it for kWhatOMXMessageList 4543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return onOMXMessage(msg); 4544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatOMXMessage: 4547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return checkOMXMessage(msg) ? onOMXMessage(msg) : true; 4549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatSetSurface: 4552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AReplyToken> replyID; 4554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->senderAwaitsResponse(&replyID)); 4555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<RefBase> obj; 4557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findObject("surface", &obj)); 4558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get())); 4560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> response = new AMessage; 4562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright response->setInt32("err", err); 4563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright response->postReply(replyID); 4564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatCreateInputSurface: 4568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatSetInputSurface: 4569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatSignalEndOfInputStream: 4570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // This may result in an app illegal state exception. 4572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Message 0x%x was not handled", msg->what()); 4573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 4574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 4575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatOMXDied: 4578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // This will result in kFlagSawMediaServerDie handling in MediaCodec. 4580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("OMX/mediaserver died, signalling error!"); 4581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 4582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatReleaseCodecInstance: 4586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("[%s] forcing the release of codec", 4588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str()); 4589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mCodec->mOMX->freeNode(mCodec->mNode); 4590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE_IF("[%s] failed to release codec instance: err=%d", 4591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), err); 4592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mCodec->mNotify->dup(); 4593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 4594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 4595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 4599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 4600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 4603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) { 4606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // there is a possibility that this is an outstanding message for a 4607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // codec that we have already destroyed 4608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->mNode == 0) { 4609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("ignoring message as already freed component: %s", 4610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright msg->debugString().c_str()); 4611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 4612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::node_id nodeID; 4615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("node", (int32_t*)&nodeID)); 4616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (nodeID != mCodec->mNode) { 4617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode); 4618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 4619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 4621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) { 4624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<RefBase> obj; 4625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findObject("messages", &obj)); 4626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<MessageList> msgList = static_cast<MessageList *>(obj.get()); 4627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool receivedRenderedEvents = false; 4629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin(); 4630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright it != msgList->getList().cend(); ++it) { 4631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (*it)->setWhat(ACodec::kWhatOMXMessageItem); 4632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->handleMessage(*it); 4633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t type; 4634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK((*it)->findInt32("type", &type)); 4635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (type == omx_message::FRAME_RENDERED) { 4636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright receivedRenderedEvents = true; 4637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (receivedRenderedEvents) { 4641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // NOTE: all buffers are rendered in this case 4642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->notifyOfRenderedFrames(); 4643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 4645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 4648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t type; 4649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("type", &type)); 4650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (type) { 4652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case omx_message::EVENT: 4653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t event, data1, data2; 4655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("event", &event)); 4656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("data1", &data1)); 4657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("data2", &data2)); 4658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (event == OMX_EventCmdComplete 4660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && data1 == OMX_CommandFlush 4661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && data2 == (int32_t)OMX_ALL) { 4662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Use of this notification is not consistent across 4663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // implementations. We'll drop this notification and rely 4664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // on flush-complete notifications on the individual port 4665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // indices instead. 4666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 4668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return onOMXEvent( 4671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<OMX_EVENTTYPE>(event), 4672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<OMX_U32>(data1), 4673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright static_cast<OMX_U32>(data2)); 4674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case omx_message::EMPTY_BUFFER_DONE: 4677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::buffer_id bufferID; 4679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t fenceFd; 4680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("fence_fd", &fenceFd)); 4683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return onOMXEmptyBufferDone(bufferID, fenceFd); 4685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case omx_message::FILL_BUFFER_DONE: 4688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::buffer_id bufferID; 4690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t rangeOffset, rangeLength, flags, fenceFd; 4693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int64_t timeUs; 4694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("range_offset", &rangeOffset)); 4696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("range_length", &rangeLength)); 4697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("flags", &flags)); 4698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt64("timestamp", &timeUs)); 4699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("fence_fd", &fenceFd)); 4700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return onOMXFillBufferDone( 4702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bufferID, 4703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (size_t)rangeOffset, (size_t)rangeLength, 4704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (OMX_U32)flags, 4705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright timeUs, 4706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fenceFd); 4707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case omx_message::FRAME_RENDERED: 4710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int64_t mediaTimeUs, systemNano; 4712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt64("media_time_us", &mediaTimeUs)); 4714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt64("system_nano", &systemNano)); 4715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return onOMXFrameRendered( 4717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mediaTimeUs, systemNano); 4718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 4721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Unexpected message type: %d", type); 4722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 4723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::BaseState::onOMXFrameRendered( 4727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) { 4728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // ignore outside of Executing and PortSettingsChanged states 4729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 4730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::BaseState::onOMXEvent( 4733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (event != OMX_EventError) { 4735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 4736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), event, data1, data2); 4737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 4739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 4742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // verify OMX component sends back an error we expect. 4744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 4745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!isOMXError(omxError)) { 4746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW("Invalid OMX error %#x", omxError); 4747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright omxError = OMX_ErrorUndefined; 4748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(omxError); 4750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 4752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) { 4755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] onOMXEmptyBufferDone %u", 4756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), bufferID); 4757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (status != BufferInfo::OWNED_BY_COMPONENT) { 4761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 4762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->dumpBuffers(kPortIndexInput); 4763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (fenceFd >= 0) { 4764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ::close(fenceFd); 4765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 4767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_US; 4769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // input buffers cannot take fences, so wait for any fence now 4771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone"); 4772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fenceFd = -1; 4773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // still save fence for completeness 4775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->setWriteFence(fenceFd, "onOMXEmptyBufferDone"); 4776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // We're in "store-metadata-in-buffers" mode, the underlying 4778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // OMX component had access to data that's implicitly refcounted 4779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // by this "MediaBuffer" object. Now that the OMX component has 4780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // told us that it's done with the input buffer, we can decrement 4781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // the mediaBuffer's reference count. 4782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mData->setMediaBufferBase(NULL); 4783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright PortMode mode = getPortMode(kPortIndexInput); 4785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (mode) { 4787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case KEEP_BUFFERS: 4788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case RESUBMIT_BUFFERS: 4791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright postFillThisBuffer(info); 4792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case FREE_BUFFERS: 4795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 4796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers"); 4797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 4798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 4801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 4804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->mPortEOS[kPortIndexInput]) { 4805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 4806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 4809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mCodec->mNotify->dup(); 4811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", CodecBase::kWhatFillThisBuffer); 4812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("buffer-id", info->mBufferID); 4813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mData->meta()->clear(); 4815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setBuffer("buffer", info->mData); 4816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec); 4818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright reply->setInt32("buffer-id", info->mBufferID); 4819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setMessage("reply", reply); 4821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 4823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 4825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 4826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 4828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::buffer_id bufferID; 4829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 4830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<ABuffer> buffer; 4831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t err = OK; 4832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool eos = false; 4833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright PortMode mode = getPortMode(kPortIndexInput); 4834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findBuffer("buffer", &buffer)) { 4836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright /* these are unfilled buffers returned by client */ 4837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("err", &err)); 4838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 4840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright /* buffers with no errors are returned on MediaCodec.flush */ 4841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mode = KEEP_BUFFERS; 4842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 4843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] saw error %d instead of an input buffer", 4844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), err); 4845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright eos = true; 4846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright buffer.clear(); 4849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t tmp; 4852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 4853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright eos = true; 4854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = ERROR_END_OF_STREAM; 4855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (status != BufferInfo::OWNED_BY_UPSTREAM) { 4860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID); 4861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->dumpBuffers(kPortIndexInput); 4862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 4864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_US; 4867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (mode) { 4869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case KEEP_BUFFERS: 4870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (eos) { 4872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!mCodec->mPortEOS[kPortIndexInput]) { 4873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mPortEOS[kPortIndexInput] = true; 4874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mInputEOSResult = err; 4875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case RESUBMIT_BUFFERS: 4881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 4882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 4883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // Do not send empty input buffer w/o EOS to the component. 4884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (buffer->size() == 0 && !eos) { 4885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright postFillThisBuffer(info); 4886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 4887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int64_t timeUs; 4890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 4891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 4893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t isCSD; 4895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 4896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright flags |= OMX_BUFFERFLAG_CODECCONFIG; 4897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (eos) { 4900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright flags |= OMX_BUFFERFLAG_EOS; 4901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (buffer != info->mData) { 4904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 4905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), 4906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bufferID, 4907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright buffer.get(), info->mData.get()); 4908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (buffer->size() > info->mData->capacity()) { 4910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("data size (%zu) is greated than buffer capacity (%zu)", 4911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright buffer->size(), // this is the data received 4912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mData->capacity()); // this is out buffer size 4913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 4915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright memcpy(info->mData->data(), buffer->data(), buffer->size()); 4917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 4920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 4921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), bufferID); 4922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (flags & OMX_BUFFERFLAG_EOS) { 4923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] calling emptyBuffer %u w/ EOS", 4924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), bufferID); 4925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 4926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if TRACK_BUFFER_TIMING 4927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 4928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#else 4930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 4931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif 4933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if TRACK_BUFFER_TIMING 4936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ACodec::BufferStats stats; 4937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 4938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright stats.mFillBufferDoneTimeUs = -1ll; 4939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mBufferStats.add(timeUs, stats); 4940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif 4941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->storingMetadataInDecodedBuffers()) { 4943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // try to submit an output buffer for each input buffer 4944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright PortMode outputMode = getPortMode(kPortIndexOutput); 4945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("MetadataBuffersToSubmit=%u portMode=%s", 4947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mMetadataBuffersToSubmit, 4948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (outputMode == FREE_BUFFERS ? "FREE" : 4949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 4950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (outputMode == RESUBMIT_BUFFERS) { 4951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->submitOutputMetadataBuffer(); 4952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->checkReadFence("onInputBufferFilled"); 4955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err2 = mCodec->mOMX->emptyBuffer( 4956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mNode, 4957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bufferID, 4958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 0, 4959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright buffer->size(), 4960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright flags, 4961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright timeUs, 4962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd); 4963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd = -1; 4964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err2 != OK) { 4965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 4966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 4967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!eos && err == OK) { 4971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright getMoreInputDataIfPossible(); 4972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 4973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Signalled EOS (%d) on the input port", 4974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), err); 4975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mPortEOS[kPortIndexInput] = true; 4977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mInputEOSResult = err; 4978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (!mCodec->mPortEOS[kPortIndexInput]) { 4980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK && err != ERROR_END_OF_STREAM) { 4981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] Signalling EOS on the input port due to error %d", 4982fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->mComponentName.c_str(), err); 4983fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else { 4984fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ALOGV("[%s] Signalling EOS on the input port", 4985fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->mComponentName.c_str()); 4986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 4987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] calling emptyBuffer %u signalling EOS", 4989fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->mComponentName.c_str(), bufferID); 4990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 4991fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev info->checkReadFence("onInputBufferFilled"); 4992fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev status_t err2 = mCodec->mOMX->emptyBuffer( 4993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mNode, 4994fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev bufferID, 4995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 0, 4996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 0, 4997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMX_BUFFERFLAG_EOS, 4998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 0, 4999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd); 5000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd = -1; 5001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err2 != OK) { 5002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 5004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5005fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5006fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5007fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->mPortEOS[kPortIndexInput] = true; 5008fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->mInputEOSResult = err; 5009fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5010fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev break; 5011fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5012fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5013fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev case FREE_BUFFERS: 5014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 5017fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ALOGE("invalid port mode: %d", mode); 5018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5019fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5020fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev} 5021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5022fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheevvoid ACodec::BaseState::getMoreInputDataIfPossible() { 5023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->mPortEOS[kPortIndexInput]) { 5024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 5025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5027fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev BufferInfo *eligible = NULL; 5028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5029fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5030fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5032fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev#if 0 5033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 5034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // There's already a "read" pending. 5035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 5036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif 5038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus == BufferInfo::OWNED_BY_US) { 5040fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev eligible = info; 5041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5043fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5044fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (eligible == NULL) { 5045fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return; 5046fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5047fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright postFillThisBuffer(eligible); 5049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 5050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::BaseState::onOMXFillBufferDone( 5052fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev IOMX::buffer_id bufferID, 5053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright size_t rangeOffset, size_t rangeLength, 5054fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev OMX_U32 flags, 5055fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev int64_t timeUs, 5056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int fenceFd) { 5057fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 5058fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 5059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ssize_t index; 5061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err= OK; 5062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if TRACK_BUFFER_TIMING 5064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright index = mCodec->mBufferStats.indexOfKey(timeUs); 5065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (index >= 0) { 5066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 5067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 5068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5069fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ALOGI("frame PTS %lld: %lld", 5070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright timeUs, 5071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 5072fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5073fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->mBufferStats.removeItemsAt(index); 5074fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev stats = NULL; 5075fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5076fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev#endif 5077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = 5079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5081fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (status != BufferInfo::OWNED_BY_COMPONENT) { 5082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5083fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->dumpBuffers(kPortIndexOutput); 5084fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (fenceFd >= 0) { 5086fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ::close(fenceFd); 5087fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 5089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mDequeuedAt = ++mCodec->mDequeueCounter; 5092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_US; 5093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mRenderInfo != NULL) { 5095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // The fence for an emptied buffer must have signaled, but there still could be queued 5096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these, 5097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // as we will soon requeue this buffer to the surface. While in theory we could still keep 5098fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev // track of buffers that are requeued to the surface, it is better to add support to the 5099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // buffer-queue to notify us of released buffers and their fences (in the future). 5100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->notifyOfRenderedFrames(true /* dropIncomplete */); 5101fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5102fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5103fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev // byte buffers cannot take fences, so wait for any fence now 5104fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (mCodec->mNativeWindow == NULL) { 5105fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone"); 5106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright fenceFd = -1; 5107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->setReadFence(fenceFd, "onOMXFillBufferDone"); 5109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5110fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev PortMode mode = getPortMode(kPortIndexOutput); 5111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5112fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev switch (mode) { 5113fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev case KEEP_BUFFERS: 5114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5115fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5116fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev case RESUBMIT_BUFFERS: 5117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 5119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright || mCodec->mPortEOS[kPortIndexOutput])) { 5120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] calling fillBuffer %u", 5121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), info->mBufferID); 5122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd); 5124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd = -1; 5125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 5126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5127fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev return true; 5128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5130fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5131fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev break; 5132fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5133fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5134fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev sp<AMessage> reply = 5135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright new AMessage(kWhatOutputBufferDrained, mCodec); 5136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!mCodec->mSentFormat && rangeLength > 0) { 5138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->sendFormatChange(reply); 5139fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->usingMetadataOnEncoderOutput()) { 5141fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev native_handle_t *handle = NULL; 5142fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data(); 5143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data(); 5144fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (info->mData->size() >= sizeof(grallocMeta) 5145fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev && grallocMeta.eType == kMetadataBufferTypeGrallocSource) { 5146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle; 5147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else if (info->mData->size() >= sizeof(nativeMeta) 5148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && nativeMeta.eType == kMetadataBufferTypeANWBuffer) { 5149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5150fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev // ANativeWindowBuffer is only valid on 32-bit/mediaserver process 5151fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev handle = NULL; 5152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#else 5153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright handle = (native_handle_t *)nativeMeta.pBuffer->handle; 5154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif 5155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mData->meta()->setPointer("handle", handle); 5157fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev info->mData->meta()->setInt32("rangeOffset", rangeOffset); 5158fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev info->mData->meta()->setInt32("rangeLength", rangeLength); 5159fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } else { 5160fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev info->mData->setRange(rangeOffset, rangeLength); 5161fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if 0 5163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->mNativeWindow == NULL) { 5164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (IsIDR(info->mData)) { 5165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGI("IDR frame"); 5166fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev } 5167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5168fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev#endif 5169fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->mSkipCutBuffer != NULL) { 5171fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev mCodec->mSkipCutBuffer->submit(info->mData); 5172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mData->meta()->setInt64("timeUs", timeUs); 5174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mCodec->mNotify->dup(); 5176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", CodecBase::kWhatDrainThisBuffer); 5177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("buffer-id", info->mBufferID); 5178fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev notify->setBuffer("buffer", info->mData); 5179fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev notify->setInt32("flags", flags); 5180fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5181fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev reply->setInt32("buffer-id", info->mBufferID); 5182fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev 5183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setMessage("reply", reply); 5184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 5186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5187fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 5188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5189fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev if (flags & OMX_BUFFERFLAG_EOS) { 5190fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 5191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5192fb7525847700ef8c328616727c747dc5e0ca8c4eVladislav Kaznacheev sp<AMessage> notify = mCodec->mNotify->dup(); 5193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", CodecBase::kWhatEOS); 5194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("err", mCodec->mInputEOSResult); 5195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 5196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mPortEOS[kPortIndexOutput] = true; 5198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case FREE_BUFFERS: 5203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mCodec->freeBuffer(kPortIndexOutput, index); 5204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 5205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 5207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 5211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Invalid port mode: %d", mode); 5212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 5213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return true; 5216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 5217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 5219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::buffer_id bufferID; 5220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 5221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ssize_t index; 5222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 5225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->dumpBuffers(kPortIndexOutput); 5227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 5229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright android_native_rect_t crop; 5232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) { 5233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 5234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 5235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t render; 5238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->mNativeWindow != NULL 5239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && msg->findInt32("render", &render) && render != 0 5240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && info->mData != NULL && info->mData->size() != 0) { 5241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ATRACE_NAME("render"); 5242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // The client wants this buffer to be rendered. 5243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // save buffers sent to the surface so we can get render time when they return 5245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int64_t mediaTimeUs = -1; 5246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mData->meta()->findInt64("timeUs", &mediaTimeUs); 5247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mediaTimeUs >= 0) { 5248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mRenderTracker.onFrameQueued( 5249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd))); 5250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int64_t timestampNs = 0; 5253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt64("timestampNs", ×tampNs)) { 5254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // use media timestamp if client did not request a specific render timestamp 5255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 5256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("using buffer PTS of %lld", (long long)timestampNs); 5257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright timestampNs *= 1000; 5258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err; 5262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 5263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 5264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->checkReadFence("onOutputBufferDrained before queueBuffer"); 5266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright err = mCodec->mNativeWindow->queueBuffer( 5267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 5268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd = -1; 5269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 5270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 5271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 5272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err); 5273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_US; 5275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // keeping read fence as write fence to avoid clobbering 5276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mIsReadFence = false; 5277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 5279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mCodec->mNativeWindow != NULL && 5280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright (info->mData == NULL || info->mData->size() != 0)) { 5281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // move read fence into write fence to avoid clobbering 5282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mIsReadFence = false; 5283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ATRACE_NAME("frame-drop"); 5284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_US; 5286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright PortMode mode = getPortMode(kPortIndexOutput); 5289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (mode) { 5291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case KEEP_BUFFERS: 5292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 5294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // We cannot resubmit the buffer we just rendered, dequeue 5297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // the spare instead. 5298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info = mCodec->dequeueBufferFromNativeWindow(); 5300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case RESUBMIT_BUFFERS: 5305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!mCodec->mPortEOS[kPortIndexOutput]) { 5307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // We cannot resubmit the buffer we just rendered, dequeue 5309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // the spare instead. 5310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info = mCodec->dequeueBufferFromNativeWindow(); 5312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (info != NULL) { 5315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("[%s] calling fillBuffer %u", 5316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.c_str(), info->mBufferID); 5317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS"); 5318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mCodec->mOMX->fillBuffer( 5319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mNode, info->mBufferID, info->mFenceFd); 5320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mFenceFd = -1; 5321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err == OK) { 5322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 5324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case FREE_BUFFERS: 5332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 5334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (err != OK) { 5335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 5341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGE("Invalid port mode: %d", mode); 5342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return; 5343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 5345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//////////////////////////////////////////////////////////////////////////////// 5347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightACodec::UninitializedState::UninitializedState(ACodec *codec) 5349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright : BaseState(codec) { 5350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 5351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::UninitializedState::stateEntered() { 5353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("Now uninitialized"); 5354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (mDeathNotifier != NULL) { 5356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier); 5357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDeathNotifier.clear(); 5358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mNativeWindow.clear(); 5361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mNativeWindowUsageBits = 0; 5362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mNode = 0; 5363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mOMX.clear(); 5364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mQuirks = 0; 5365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mFlags = 0; 5366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mInputMetadataType = kMetadataBufferTypeInvalid; 5367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid; 5368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mComponentName.clear(); 5369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 5370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 5372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright bool handled = false; 5373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright switch (msg->what()) { 5375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatSetup: 5376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright onSetup(msg); 5378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright handled = true; 5380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatAllocateComponent: 5384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright onAllocateComponent(msg); 5386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright handled = true; 5387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatShutdown: 5391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t keepComponentAllocated; 5393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findInt32( 5394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "keepComponentAllocated", &keepComponentAllocated)); 5395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGW_IF(keepComponentAllocated, 5396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright "cannot keep component allocated on shutdown in Uninitialized state"); 5397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mCodec->mNotify->dup(); 5399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 5401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright handled = true; 5403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatFlush: 5407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = mCodec->mNotify->dup(); 5409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright notify->post(); 5411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright handled = true; 5413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright case ACodec::kWhatReleaseCodecInstance: 5417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright { 5418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // nothing to do, as we have already signaled shutdown 5419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright handled = true; 5420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright break; 5421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright default: 5424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return BaseState::onMessageReceived(msg); 5425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return handled; 5428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 5429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid ACodec::UninitializedState::onSetup( 5431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright const sp<AMessage> &msg) { 5432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (onAllocateComponent(msg) 5433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright && mCodec->mLoadedState->onConfigureComponent(msg)) { 5434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->mLoadedState->onStart(); 5435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} 5437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 5439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ALOGV("onAllocateComponent"); 5440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(mCodec->mNode == 0); 5442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMXClient client; 5444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (client.connect() != OK) { 5445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 5446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright return false; 5447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<IOMX> omx = client.interface(); 5450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 5452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDeathNotifier = new DeathNotifier(notify); 5454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) { 5455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // This was a local binder, if it dies so do we, we won't care 5456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright // about any notifications in the afterlife. 5457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mDeathNotifier.clear(); 5458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 5461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright AString mime; 5463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright AString componentName; 5465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright uint32_t quirks = 0; 5466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright int32_t encoder = false; 5467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (msg->findString("componentName", &componentName)) { 5468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ssize_t index = matchingCodecs.add(); 5469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index); 5470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright entry->mName = String8(componentName.c_str()); 5471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!OMXCodec::findCodecQuirks( 5473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright componentName.c_str(), &entry->mQuirks)) { 5474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright entry->mQuirks = 0; 5475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } else { 5477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright CHECK(msg->findString("mime", &mime)); 5478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright if (!msg->findInt32("encoder", &encoder)) { 5480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder = false; 5481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright OMXCodec::findMatchingCodecs( 5484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright mime.c_str(), 5485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright encoder, // createEncoder 5486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright NULL, // matchComponentName 5487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 0, // flags 5488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright &matchingCodecs); 5489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright } 5490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright sp<CodecObserver> observer = new CodecObserver; 5492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright IOMX::node_id node = 0; 5493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright 5494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright status_t err = NAME_NOT_FOUND; 5495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 5496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright ++matchIndex) { 5497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright componentName = matchingCodecs.itemAt(matchIndex).mName.string(); 5498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright quirks = matchingCodecs.itemAt(matchIndex).mQuirks; 5499 5500 pid_t tid = gettid(); 5501 int prevPriority = androidGetThreadPriority(tid); 5502 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 5503 err = omx->allocateNode(componentName.c_str(), observer, &node); 5504 androidSetThreadPriority(tid, prevPriority); 5505 5506 if (err == OK) { 5507 break; 5508 } else { 5509 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 5510 } 5511 5512 node = 0; 5513 } 5514 5515 if (node == 0) { 5516 if (!mime.empty()) { 5517 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 5518 encoder ? "en" : "de", mime.c_str(), err); 5519 } else { 5520 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 5521 } 5522 5523 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 5524 return false; 5525 } 5526 5527 notify = new AMessage(kWhatOMXMessageList, mCodec); 5528 observer->setNotificationMessage(notify); 5529 5530 mCodec->mComponentName = componentName; 5531 mCodec->mRenderTracker.setComponentName(componentName); 5532 mCodec->mFlags = 0; 5533 5534 if (componentName.endsWith(".secure")) { 5535 mCodec->mFlags |= kFlagIsSecure; 5536 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 5537 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 5538 } 5539 5540 mCodec->mQuirks = quirks; 5541 mCodec->mOMX = omx; 5542 mCodec->mNode = node; 5543 5544 { 5545 sp<AMessage> notify = mCodec->mNotify->dup(); 5546 notify->setInt32("what", CodecBase::kWhatComponentAllocated); 5547 notify->setString("componentName", mCodec->mComponentName.c_str()); 5548 notify->post(); 5549 } 5550 5551 mCodec->changeState(mCodec->mLoadedState); 5552 5553 return true; 5554} 5555 5556//////////////////////////////////////////////////////////////////////////////// 5557 5558ACodec::LoadedState::LoadedState(ACodec *codec) 5559 : BaseState(codec) { 5560} 5561 5562void ACodec::LoadedState::stateEntered() { 5563 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 5564 5565 mCodec->mPortEOS[kPortIndexInput] = 5566 mCodec->mPortEOS[kPortIndexOutput] = false; 5567 5568 mCodec->mInputEOSResult = OK; 5569 5570 mCodec->mDequeueCounter = 0; 5571 mCodec->mMetadataBuffersToSubmit = 0; 5572 mCodec->mRepeatFrameDelayUs = -1ll; 5573 mCodec->mInputFormat.clear(); 5574 mCodec->mOutputFormat.clear(); 5575 mCodec->mBaseOutputFormat.clear(); 5576 5577 if (mCodec->mShutdownInProgress) { 5578 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 5579 5580 mCodec->mShutdownInProgress = false; 5581 mCodec->mKeepComponentAllocated = false; 5582 5583 onShutdown(keepComponentAllocated); 5584 } 5585 mCodec->mExplicitShutdown = false; 5586 5587 mCodec->processDeferredMessages(); 5588} 5589 5590void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 5591 if (!keepComponentAllocated) { 5592 (void)mCodec->mOMX->freeNode(mCodec->mNode); 5593 5594 mCodec->changeState(mCodec->mUninitializedState); 5595 } 5596 5597 if (mCodec->mExplicitShutdown) { 5598 sp<AMessage> notify = mCodec->mNotify->dup(); 5599 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5600 notify->post(); 5601 mCodec->mExplicitShutdown = false; 5602 } 5603} 5604 5605bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 5606 bool handled = false; 5607 5608 switch (msg->what()) { 5609 case ACodec::kWhatConfigureComponent: 5610 { 5611 onConfigureComponent(msg); 5612 handled = true; 5613 break; 5614 } 5615 5616 case ACodec::kWhatCreateInputSurface: 5617 { 5618 onCreateInputSurface(msg); 5619 handled = true; 5620 break; 5621 } 5622 5623 case ACodec::kWhatSetInputSurface: 5624 { 5625 onSetInputSurface(msg); 5626 handled = true; 5627 break; 5628 } 5629 5630 case ACodec::kWhatStart: 5631 { 5632 onStart(); 5633 handled = true; 5634 break; 5635 } 5636 5637 case ACodec::kWhatShutdown: 5638 { 5639 int32_t keepComponentAllocated; 5640 CHECK(msg->findInt32( 5641 "keepComponentAllocated", &keepComponentAllocated)); 5642 5643 mCodec->mExplicitShutdown = true; 5644 onShutdown(keepComponentAllocated); 5645 5646 handled = true; 5647 break; 5648 } 5649 5650 case ACodec::kWhatFlush: 5651 { 5652 sp<AMessage> notify = mCodec->mNotify->dup(); 5653 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5654 notify->post(); 5655 5656 handled = true; 5657 break; 5658 } 5659 5660 default: 5661 return BaseState::onMessageReceived(msg); 5662 } 5663 5664 return handled; 5665} 5666 5667bool ACodec::LoadedState::onConfigureComponent( 5668 const sp<AMessage> &msg) { 5669 ALOGV("onConfigureComponent"); 5670 5671 CHECK(mCodec->mNode != 0); 5672 5673 status_t err = OK; 5674 AString mime; 5675 if (!msg->findString("mime", &mime)) { 5676 err = BAD_VALUE; 5677 } else { 5678 err = mCodec->configureCodec(mime.c_str(), msg); 5679 } 5680 if (err != OK) { 5681 ALOGE("[%s] configureCodec returning error %d", 5682 mCodec->mComponentName.c_str(), err); 5683 5684 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5685 return false; 5686 } 5687 5688 { 5689 sp<AMessage> notify = mCodec->mNotify->dup(); 5690 notify->setInt32("what", CodecBase::kWhatComponentConfigured); 5691 notify->setMessage("input-format", mCodec->mInputFormat); 5692 notify->setMessage("output-format", mCodec->mOutputFormat); 5693 notify->post(); 5694 } 5695 5696 return true; 5697} 5698 5699status_t ACodec::LoadedState::setupInputSurface() { 5700 status_t err = OK; 5701 5702 if (mCodec->mRepeatFrameDelayUs > 0ll) { 5703 err = mCodec->mOMX->setInternalOption( 5704 mCodec->mNode, 5705 kPortIndexInput, 5706 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, 5707 &mCodec->mRepeatFrameDelayUs, 5708 sizeof(mCodec->mRepeatFrameDelayUs)); 5709 5710 if (err != OK) { 5711 ALOGE("[%s] Unable to configure option to repeat previous " 5712 "frames (err %d)", 5713 mCodec->mComponentName.c_str(), 5714 err); 5715 return err; 5716 } 5717 } 5718 5719 if (mCodec->mMaxPtsGapUs > 0ll) { 5720 err = mCodec->mOMX->setInternalOption( 5721 mCodec->mNode, 5722 kPortIndexInput, 5723 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP, 5724 &mCodec->mMaxPtsGapUs, 5725 sizeof(mCodec->mMaxPtsGapUs)); 5726 5727 if (err != OK) { 5728 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 5729 mCodec->mComponentName.c_str(), 5730 err); 5731 return err; 5732 } 5733 } 5734 5735 if (mCodec->mMaxFps > 0) { 5736 err = mCodec->mOMX->setInternalOption( 5737 mCodec->mNode, 5738 kPortIndexInput, 5739 IOMX::INTERNAL_OPTION_MAX_FPS, 5740 &mCodec->mMaxFps, 5741 sizeof(mCodec->mMaxFps)); 5742 5743 if (err != OK) { 5744 ALOGE("[%s] Unable to configure max fps (err %d)", 5745 mCodec->mComponentName.c_str(), 5746 err); 5747 return err; 5748 } 5749 } 5750 5751 if (mCodec->mTimePerCaptureUs > 0ll 5752 && mCodec->mTimePerFrameUs > 0ll) { 5753 int64_t timeLapse[2]; 5754 timeLapse[0] = mCodec->mTimePerFrameUs; 5755 timeLapse[1] = mCodec->mTimePerCaptureUs; 5756 err = mCodec->mOMX->setInternalOption( 5757 mCodec->mNode, 5758 kPortIndexInput, 5759 IOMX::INTERNAL_OPTION_TIME_LAPSE, 5760 &timeLapse[0], 5761 sizeof(timeLapse)); 5762 5763 if (err != OK) { 5764 ALOGE("[%s] Unable to configure time lapse (err %d)", 5765 mCodec->mComponentName.c_str(), 5766 err); 5767 return err; 5768 } 5769 } 5770 5771 if (mCodec->mCreateInputBuffersSuspended) { 5772 bool suspend = true; 5773 err = mCodec->mOMX->setInternalOption( 5774 mCodec->mNode, 5775 kPortIndexInput, 5776 IOMX::INTERNAL_OPTION_SUSPEND, 5777 &suspend, 5778 sizeof(suspend)); 5779 5780 if (err != OK) { 5781 ALOGE("[%s] Unable to configure option to suspend (err %d)", 5782 mCodec->mComponentName.c_str(), 5783 err); 5784 return err; 5785 } 5786 } 5787 5788 uint32_t usageBits; 5789 if (mCodec->mOMX->getParameter( 5790 mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 5791 &usageBits, sizeof(usageBits)) == OK) { 5792 mCodec->mInputFormat->setInt32( 5793 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 5794 } 5795 5796 return OK; 5797} 5798 5799void ACodec::LoadedState::onCreateInputSurface( 5800 const sp<AMessage> & /* msg */) { 5801 ALOGV("onCreateInputSurface"); 5802 5803 sp<AMessage> notify = mCodec->mNotify->dup(); 5804 notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated); 5805 5806 sp<IGraphicBufferProducer> bufferProducer; 5807 status_t err = mCodec->mOMX->createInputSurface( 5808 mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType); 5809 5810 if (err == OK) { 5811 err = setupInputSurface(); 5812 } 5813 5814 if (err == OK) { 5815 notify->setObject("input-surface", 5816 new BufferProducerWrapper(bufferProducer)); 5817 } else { 5818 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5819 // the error through because it's in the "configured" state. We 5820 // send a kWhatInputSurfaceCreated with an error value instead. 5821 ALOGE("[%s] onCreateInputSurface returning error %d", 5822 mCodec->mComponentName.c_str(), err); 5823 notify->setInt32("err", err); 5824 } 5825 notify->post(); 5826} 5827 5828void ACodec::LoadedState::onSetInputSurface( 5829 const sp<AMessage> &msg) { 5830 ALOGV("onSetInputSurface"); 5831 5832 sp<AMessage> notify = mCodec->mNotify->dup(); 5833 notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted); 5834 5835 sp<RefBase> obj; 5836 CHECK(msg->findObject("input-surface", &obj)); 5837 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 5838 5839 status_t err = mCodec->mOMX->setInputSurface( 5840 mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(), 5841 &mCodec->mInputMetadataType); 5842 5843 if (err == OK) { 5844 err = setupInputSurface(); 5845 } 5846 5847 if (err != OK) { 5848 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5849 // the error through because it's in the "configured" state. We 5850 // send a kWhatInputSurfaceAccepted with an error value instead. 5851 ALOGE("[%s] onSetInputSurface returning error %d", 5852 mCodec->mComponentName.c_str(), err); 5853 notify->setInt32("err", err); 5854 } 5855 notify->post(); 5856} 5857 5858void ACodec::LoadedState::onStart() { 5859 ALOGV("onStart"); 5860 5861 status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); 5862 if (err != OK) { 5863 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5864 } else { 5865 mCodec->changeState(mCodec->mLoadedToIdleState); 5866 } 5867} 5868 5869//////////////////////////////////////////////////////////////////////////////// 5870 5871ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 5872 : BaseState(codec) { 5873} 5874 5875void ACodec::LoadedToIdleState::stateEntered() { 5876 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 5877 5878 status_t err; 5879 if ((err = allocateBuffers()) != OK) { 5880 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 5881 "(error 0x%08x)", 5882 err); 5883 5884 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5885 5886 mCodec->changeState(mCodec->mLoadedState); 5887 } 5888} 5889 5890status_t ACodec::LoadedToIdleState::allocateBuffers() { 5891 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 5892 5893 if (err != OK) { 5894 return err; 5895 } 5896 5897 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 5898} 5899 5900bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 5901 switch (msg->what()) { 5902 case kWhatSetParameters: 5903 case kWhatShutdown: 5904 { 5905 mCodec->deferMessage(msg); 5906 return true; 5907 } 5908 5909 case kWhatSignalEndOfInputStream: 5910 { 5911 mCodec->onSignalEndOfInputStream(); 5912 return true; 5913 } 5914 5915 case kWhatResume: 5916 { 5917 // We'll be active soon enough. 5918 return true; 5919 } 5920 5921 case kWhatFlush: 5922 { 5923 // We haven't even started yet, so we're flushed alright... 5924 sp<AMessage> notify = mCodec->mNotify->dup(); 5925 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5926 notify->post(); 5927 return true; 5928 } 5929 5930 default: 5931 return BaseState::onMessageReceived(msg); 5932 } 5933} 5934 5935bool ACodec::LoadedToIdleState::onOMXEvent( 5936 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5937 switch (event) { 5938 case OMX_EventCmdComplete: 5939 { 5940 status_t err = OK; 5941 if (data1 != (OMX_U32)OMX_CommandStateSet 5942 || data2 != (OMX_U32)OMX_StateIdle) { 5943 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 5944 asString((OMX_COMMANDTYPE)data1), data1, 5945 asString((OMX_STATETYPE)data2), data2); 5946 err = FAILED_TRANSACTION; 5947 } 5948 5949 if (err == OK) { 5950 err = mCodec->mOMX->sendCommand( 5951 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting); 5952 } 5953 5954 if (err != OK) { 5955 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5956 } else { 5957 mCodec->changeState(mCodec->mIdleToExecutingState); 5958 } 5959 5960 return true; 5961 } 5962 5963 default: 5964 return BaseState::onOMXEvent(event, data1, data2); 5965 } 5966} 5967 5968//////////////////////////////////////////////////////////////////////////////// 5969 5970ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 5971 : BaseState(codec) { 5972} 5973 5974void ACodec::IdleToExecutingState::stateEntered() { 5975 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 5976} 5977 5978bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 5979 switch (msg->what()) { 5980 case kWhatSetParameters: 5981 case kWhatShutdown: 5982 { 5983 mCodec->deferMessage(msg); 5984 return true; 5985 } 5986 5987 case kWhatResume: 5988 { 5989 // We'll be active soon enough. 5990 return true; 5991 } 5992 5993 case kWhatFlush: 5994 { 5995 // We haven't even started yet, so we're flushed alright... 5996 sp<AMessage> notify = mCodec->mNotify->dup(); 5997 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5998 notify->post(); 5999 6000 return true; 6001 } 6002 6003 case kWhatSignalEndOfInputStream: 6004 { 6005 mCodec->onSignalEndOfInputStream(); 6006 return true; 6007 } 6008 6009 default: 6010 return BaseState::onMessageReceived(msg); 6011 } 6012} 6013 6014bool ACodec::IdleToExecutingState::onOMXEvent( 6015 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6016 switch (event) { 6017 case OMX_EventCmdComplete: 6018 { 6019 if (data1 != (OMX_U32)OMX_CommandStateSet 6020 || data2 != (OMX_U32)OMX_StateExecuting) { 6021 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 6022 asString((OMX_COMMANDTYPE)data1), data1, 6023 asString((OMX_STATETYPE)data2), data2); 6024 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6025 return true; 6026 } 6027 6028 mCodec->mExecutingState->resume(); 6029 mCodec->changeState(mCodec->mExecutingState); 6030 6031 return true; 6032 } 6033 6034 default: 6035 return BaseState::onOMXEvent(event, data1, data2); 6036 } 6037} 6038 6039//////////////////////////////////////////////////////////////////////////////// 6040 6041ACodec::ExecutingState::ExecutingState(ACodec *codec) 6042 : BaseState(codec), 6043 mActive(false) { 6044} 6045 6046ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 6047 OMX_U32 /* portIndex */) { 6048 return RESUBMIT_BUFFERS; 6049} 6050 6051void ACodec::ExecutingState::submitOutputMetaBuffers() { 6052 // submit as many buffers as there are input buffers with the codec 6053 // in case we are in port reconfiguring 6054 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 6055 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6056 6057 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 6058 if (mCodec->submitOutputMetadataBuffer() != OK) 6059 break; 6060 } 6061 } 6062 6063 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6064 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6065} 6066 6067void ACodec::ExecutingState::submitRegularOutputBuffers() { 6068 bool failed = false; 6069 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 6070 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 6071 6072 if (mCodec->mNativeWindow != NULL) { 6073 if (info->mStatus != BufferInfo::OWNED_BY_US 6074 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6075 ALOGE("buffers should be owned by us or the surface"); 6076 failed = true; 6077 break; 6078 } 6079 6080 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6081 continue; 6082 } 6083 } else { 6084 if (info->mStatus != BufferInfo::OWNED_BY_US) { 6085 ALOGE("buffers should be owned by us"); 6086 failed = true; 6087 break; 6088 } 6089 } 6090 6091 ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 6092 6093 info->checkWriteFence("submitRegularOutputBuffers"); 6094 status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd); 6095 info->mFenceFd = -1; 6096 if (err != OK) { 6097 failed = true; 6098 break; 6099 } 6100 6101 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 6102 } 6103 6104 if (failed) { 6105 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6106 } 6107} 6108 6109void ACodec::ExecutingState::submitOutputBuffers() { 6110 submitRegularOutputBuffers(); 6111 if (mCodec->storingMetadataInDecodedBuffers()) { 6112 submitOutputMetaBuffers(); 6113 } 6114} 6115 6116void ACodec::ExecutingState::resume() { 6117 if (mActive) { 6118 ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 6119 return; 6120 } 6121 6122 submitOutputBuffers(); 6123 6124 // Post all available input buffers 6125 if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 6126 ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 6127 } 6128 6129 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 6130 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6131 if (info->mStatus == BufferInfo::OWNED_BY_US) { 6132 postFillThisBuffer(info); 6133 } 6134 } 6135 6136 mActive = true; 6137} 6138 6139void ACodec::ExecutingState::stateEntered() { 6140 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 6141 6142 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 6143 mCodec->processDeferredMessages(); 6144} 6145 6146bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6147 bool handled = false; 6148 6149 switch (msg->what()) { 6150 case kWhatShutdown: 6151 { 6152 int32_t keepComponentAllocated; 6153 CHECK(msg->findInt32( 6154 "keepComponentAllocated", &keepComponentAllocated)); 6155 6156 mCodec->mShutdownInProgress = true; 6157 mCodec->mExplicitShutdown = true; 6158 mCodec->mKeepComponentAllocated = keepComponentAllocated; 6159 6160 mActive = false; 6161 6162 status_t err = mCodec->mOMX->sendCommand( 6163 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); 6164 if (err != OK) { 6165 if (keepComponentAllocated) { 6166 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6167 } 6168 // TODO: do some recovery here. 6169 } else { 6170 mCodec->changeState(mCodec->mExecutingToIdleState); 6171 } 6172 6173 handled = true; 6174 break; 6175 } 6176 6177 case kWhatFlush: 6178 { 6179 ALOGV("[%s] ExecutingState flushing now " 6180 "(codec owns %zu/%zu input, %zu/%zu output).", 6181 mCodec->mComponentName.c_str(), 6182 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 6183 mCodec->mBuffers[kPortIndexInput].size(), 6184 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 6185 mCodec->mBuffers[kPortIndexOutput].size()); 6186 6187 mActive = false; 6188 6189 status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL); 6190 if (err != OK) { 6191 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6192 } else { 6193 mCodec->changeState(mCodec->mFlushingState); 6194 } 6195 6196 handled = true; 6197 break; 6198 } 6199 6200 case kWhatResume: 6201 { 6202 resume(); 6203 6204 handled = true; 6205 break; 6206 } 6207 6208 case kWhatRequestIDRFrame: 6209 { 6210 status_t err = mCodec->requestIDRFrame(); 6211 if (err != OK) { 6212 ALOGW("Requesting an IDR frame failed."); 6213 } 6214 6215 handled = true; 6216 break; 6217 } 6218 6219 case kWhatSetParameters: 6220 { 6221 sp<AMessage> params; 6222 CHECK(msg->findMessage("params", ¶ms)); 6223 6224 status_t err = mCodec->setParameters(params); 6225 6226 sp<AMessage> reply; 6227 if (msg->findMessage("reply", &reply)) { 6228 reply->setInt32("err", err); 6229 reply->post(); 6230 } 6231 6232 handled = true; 6233 break; 6234 } 6235 6236 case ACodec::kWhatSignalEndOfInputStream: 6237 { 6238 mCodec->onSignalEndOfInputStream(); 6239 handled = true; 6240 break; 6241 } 6242 6243 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6244 case kWhatSubmitOutputMetadataBufferIfEOS: 6245 { 6246 if (mCodec->mPortEOS[kPortIndexInput] && 6247 !mCodec->mPortEOS[kPortIndexOutput]) { 6248 status_t err = mCodec->submitOutputMetadataBuffer(); 6249 if (err == OK) { 6250 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6251 } 6252 } 6253 return true; 6254 } 6255 6256 default: 6257 handled = BaseState::onMessageReceived(msg); 6258 break; 6259 } 6260 6261 return handled; 6262} 6263 6264status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 6265 int32_t videoBitrate; 6266 if (params->findInt32("video-bitrate", &videoBitrate)) { 6267 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 6268 InitOMXParams(&configParams); 6269 configParams.nPortIndex = kPortIndexOutput; 6270 configParams.nEncodeBitrate = videoBitrate; 6271 6272 status_t err = mOMX->setConfig( 6273 mNode, 6274 OMX_IndexConfigVideoBitrate, 6275 &configParams, 6276 sizeof(configParams)); 6277 6278 if (err != OK) { 6279 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 6280 videoBitrate, err); 6281 6282 return err; 6283 } 6284 } 6285 6286 int64_t skipFramesBeforeUs; 6287 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 6288 status_t err = 6289 mOMX->setInternalOption( 6290 mNode, 6291 kPortIndexInput, 6292 IOMX::INTERNAL_OPTION_START_TIME, 6293 &skipFramesBeforeUs, 6294 sizeof(skipFramesBeforeUs)); 6295 6296 if (err != OK) { 6297 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 6298 return err; 6299 } 6300 } 6301 6302 int32_t dropInputFrames; 6303 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 6304 bool suspend = dropInputFrames != 0; 6305 6306 status_t err = 6307 mOMX->setInternalOption( 6308 mNode, 6309 kPortIndexInput, 6310 IOMX::INTERNAL_OPTION_SUSPEND, 6311 &suspend, 6312 sizeof(suspend)); 6313 6314 if (err != OK) { 6315 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 6316 return err; 6317 } 6318 } 6319 6320 int32_t dummy; 6321 if (params->findInt32("request-sync", &dummy)) { 6322 status_t err = requestIDRFrame(); 6323 6324 if (err != OK) { 6325 ALOGE("Requesting a sync frame failed w/ err %d", err); 6326 return err; 6327 } 6328 } 6329 6330 float rate; 6331 if (params->findFloat("operating-rate", &rate) && rate > 0) { 6332 status_t err = setOperatingRate(rate, mIsVideo); 6333 if (err != OK) { 6334 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 6335 return err; 6336 } 6337 } 6338 6339 return OK; 6340} 6341 6342void ACodec::onSignalEndOfInputStream() { 6343 sp<AMessage> notify = mNotify->dup(); 6344 notify->setInt32("what", CodecBase::kWhatSignaledInputEOS); 6345 6346 status_t err = mOMX->signalEndOfInputStream(mNode); 6347 if (err != OK) { 6348 notify->setInt32("err", err); 6349 } 6350 notify->post(); 6351} 6352 6353bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 6354 mCodec->onFrameRendered(mediaTimeUs, systemNano); 6355 return true; 6356} 6357 6358bool ACodec::ExecutingState::onOMXEvent( 6359 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6360 switch (event) { 6361 case OMX_EventPortSettingsChanged: 6362 { 6363 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 6364 6365 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 6366 mCodec->mMetadataBuffersToSubmit = 0; 6367 CHECK_EQ(mCodec->mOMX->sendCommand( 6368 mCodec->mNode, 6369 OMX_CommandPortDisable, kPortIndexOutput), 6370 (status_t)OK); 6371 6372 mCodec->freeOutputBuffersNotOwnedByComponent(); 6373 6374 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 6375 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 6376 mCodec->mSentFormat = false; 6377 6378 if (mCodec->mTunneled) { 6379 sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec); 6380 mCodec->sendFormatChange(dummy); 6381 } 6382 } else { 6383 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 6384 mCodec->mComponentName.c_str(), data2); 6385 } 6386 6387 return true; 6388 } 6389 6390 case OMX_EventBufferFlag: 6391 { 6392 return true; 6393 } 6394 6395 default: 6396 return BaseState::onOMXEvent(event, data1, data2); 6397 } 6398} 6399 6400//////////////////////////////////////////////////////////////////////////////// 6401 6402ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 6403 ACodec *codec) 6404 : BaseState(codec) { 6405} 6406 6407ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 6408 OMX_U32 portIndex) { 6409 if (portIndex == kPortIndexOutput) { 6410 return FREE_BUFFERS; 6411 } 6412 6413 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 6414 6415 return RESUBMIT_BUFFERS; 6416} 6417 6418bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 6419 const sp<AMessage> &msg) { 6420 bool handled = false; 6421 6422 switch (msg->what()) { 6423 case kWhatFlush: 6424 case kWhatShutdown: 6425 case kWhatResume: 6426 case kWhatSetParameters: 6427 { 6428 if (msg->what() == kWhatResume) { 6429 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 6430 } 6431 6432 mCodec->deferMessage(msg); 6433 handled = true; 6434 break; 6435 } 6436 6437 default: 6438 handled = BaseState::onMessageReceived(msg); 6439 break; 6440 } 6441 6442 return handled; 6443} 6444 6445void ACodec::OutputPortSettingsChangedState::stateEntered() { 6446 ALOGV("[%s] Now handling output port settings change", 6447 mCodec->mComponentName.c_str()); 6448} 6449 6450bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered( 6451 int64_t mediaTimeUs, nsecs_t systemNano) { 6452 mCodec->onFrameRendered(mediaTimeUs, systemNano); 6453 return true; 6454} 6455 6456bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 6457 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6458 switch (event) { 6459 case OMX_EventCmdComplete: 6460 { 6461 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 6462 if (data2 != (OMX_U32)kPortIndexOutput) { 6463 ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 6464 return false; 6465 } 6466 6467 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 6468 6469 status_t err = OK; 6470 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 6471 ALOGE("disabled port should be empty, but has %zu buffers", 6472 mCodec->mBuffers[kPortIndexOutput].size()); 6473 err = FAILED_TRANSACTION; 6474 } else { 6475 mCodec->mDealer[kPortIndexOutput].clear(); 6476 } 6477 6478 if (err == OK) { 6479 err = mCodec->mOMX->sendCommand( 6480 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput); 6481 } 6482 6483 if (err == OK) { 6484 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 6485 ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 6486 "reconfiguration: (%d)", err); 6487 } 6488 6489 if (err != OK) { 6490 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6491 6492 // This is technically not correct, but appears to be 6493 // the only way to free the component instance. 6494 // Controlled transitioning from excecuting->idle 6495 // and idle->loaded seem impossible probably because 6496 // the output port never finishes re-enabling. 6497 mCodec->mShutdownInProgress = true; 6498 mCodec->mKeepComponentAllocated = false; 6499 mCodec->changeState(mCodec->mLoadedState); 6500 } 6501 6502 return true; 6503 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 6504 if (data2 != (OMX_U32)kPortIndexOutput) { 6505 ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 6506 return false; 6507 } 6508 6509 mCodec->mSentFormat = false; 6510 6511 if (mCodec->mTunneled) { 6512 sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec); 6513 mCodec->sendFormatChange(dummy); 6514 } 6515 6516 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 6517 6518 if (mCodec->mExecutingState->active()) { 6519 mCodec->mExecutingState->submitOutputBuffers(); 6520 } 6521 6522 mCodec->changeState(mCodec->mExecutingState); 6523 6524 return true; 6525 } 6526 6527 return false; 6528 } 6529 6530 default: 6531 return false; 6532 } 6533} 6534 6535//////////////////////////////////////////////////////////////////////////////// 6536 6537ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 6538 : BaseState(codec), 6539 mComponentNowIdle(false) { 6540} 6541 6542bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6543 bool handled = false; 6544 6545 switch (msg->what()) { 6546 case kWhatFlush: 6547 { 6548 // Don't send me a flush request if you previously wanted me 6549 // to shutdown. 6550 ALOGW("Ignoring flush request in ExecutingToIdleState"); 6551 break; 6552 } 6553 6554 case kWhatShutdown: 6555 { 6556 // We're already doing that... 6557 6558 handled = true; 6559 break; 6560 } 6561 6562 default: 6563 handled = BaseState::onMessageReceived(msg); 6564 break; 6565 } 6566 6567 return handled; 6568} 6569 6570void ACodec::ExecutingToIdleState::stateEntered() { 6571 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 6572 6573 mComponentNowIdle = false; 6574 mCodec->mSentFormat = false; 6575} 6576 6577bool ACodec::ExecutingToIdleState::onOMXEvent( 6578 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6579 switch (event) { 6580 case OMX_EventCmdComplete: 6581 { 6582 if (data1 != (OMX_U32)OMX_CommandStateSet 6583 || data2 != (OMX_U32)OMX_StateIdle) { 6584 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 6585 asString((OMX_COMMANDTYPE)data1), data1, 6586 asString((OMX_STATETYPE)data2), data2); 6587 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6588 return true; 6589 } 6590 6591 mComponentNowIdle = true; 6592 6593 changeStateIfWeOwnAllBuffers(); 6594 6595 return true; 6596 } 6597 6598 case OMX_EventPortSettingsChanged: 6599 case OMX_EventBufferFlag: 6600 { 6601 // We're shutting down and don't care about this anymore. 6602 return true; 6603 } 6604 6605 default: 6606 return BaseState::onOMXEvent(event, data1, data2); 6607 } 6608} 6609 6610void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 6611 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 6612 status_t err = mCodec->mOMX->sendCommand( 6613 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded); 6614 if (err == OK) { 6615 err = mCodec->freeBuffersOnPort(kPortIndexInput); 6616 status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 6617 if (err == OK) { 6618 err = err2; 6619 } 6620 } 6621 6622 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 6623 && mCodec->mNativeWindow != NULL) { 6624 // We push enough 1x1 blank buffers to ensure that one of 6625 // them has made it to the display. This allows the OMX 6626 // component teardown to zero out any protected buffers 6627 // without the risk of scanning out one of those buffers. 6628 pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 6629 } 6630 6631 if (err != OK) { 6632 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6633 return; 6634 } 6635 6636 mCodec->changeState(mCodec->mIdleToLoadedState); 6637 } 6638} 6639 6640void ACodec::ExecutingToIdleState::onInputBufferFilled( 6641 const sp<AMessage> &msg) { 6642 BaseState::onInputBufferFilled(msg); 6643 6644 changeStateIfWeOwnAllBuffers(); 6645} 6646 6647void ACodec::ExecutingToIdleState::onOutputBufferDrained( 6648 const sp<AMessage> &msg) { 6649 BaseState::onOutputBufferDrained(msg); 6650 6651 changeStateIfWeOwnAllBuffers(); 6652} 6653 6654//////////////////////////////////////////////////////////////////////////////// 6655 6656ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 6657 : BaseState(codec) { 6658} 6659 6660bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 6661 bool handled = false; 6662 6663 switch (msg->what()) { 6664 case kWhatShutdown: 6665 { 6666 // We're already doing that... 6667 6668 handled = true; 6669 break; 6670 } 6671 6672 case kWhatFlush: 6673 { 6674 // Don't send me a flush request if you previously wanted me 6675 // to shutdown. 6676 ALOGE("Got flush request in IdleToLoadedState"); 6677 break; 6678 } 6679 6680 default: 6681 handled = BaseState::onMessageReceived(msg); 6682 break; 6683 } 6684 6685 return handled; 6686} 6687 6688void ACodec::IdleToLoadedState::stateEntered() { 6689 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 6690} 6691 6692bool ACodec::IdleToLoadedState::onOMXEvent( 6693 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6694 switch (event) { 6695 case OMX_EventCmdComplete: 6696 { 6697 if (data1 != (OMX_U32)OMX_CommandStateSet 6698 || data2 != (OMX_U32)OMX_StateLoaded) { 6699 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 6700 asString((OMX_COMMANDTYPE)data1), data1, 6701 asString((OMX_STATETYPE)data2), data2); 6702 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6703 return true; 6704 } 6705 6706 mCodec->changeState(mCodec->mLoadedState); 6707 6708 return true; 6709 } 6710 6711 default: 6712 return BaseState::onOMXEvent(event, data1, data2); 6713 } 6714} 6715 6716//////////////////////////////////////////////////////////////////////////////// 6717 6718ACodec::FlushingState::FlushingState(ACodec *codec) 6719 : BaseState(codec) { 6720} 6721 6722void ACodec::FlushingState::stateEntered() { 6723 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 6724 6725 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 6726} 6727 6728bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 6729 bool handled = false; 6730 6731 switch (msg->what()) { 6732 case kWhatShutdown: 6733 { 6734 mCodec->deferMessage(msg); 6735 break; 6736 } 6737 6738 case kWhatFlush: 6739 { 6740 // We're already doing this right now. 6741 handled = true; 6742 break; 6743 } 6744 6745 default: 6746 handled = BaseState::onMessageReceived(msg); 6747 break; 6748 } 6749 6750 return handled; 6751} 6752 6753bool ACodec::FlushingState::onOMXEvent( 6754 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6755 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 6756 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 6757 6758 switch (event) { 6759 case OMX_EventCmdComplete: 6760 { 6761 if (data1 != (OMX_U32)OMX_CommandFlush) { 6762 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 6763 asString((OMX_COMMANDTYPE)data1), data1, data2); 6764 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6765 return true; 6766 } 6767 6768 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 6769 if (mFlushComplete[data2]) { 6770 ALOGW("Flush already completed for %s port", 6771 data2 == kPortIndexInput ? "input" : "output"); 6772 return true; 6773 } 6774 mFlushComplete[data2] = true; 6775 6776 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 6777 changeStateIfWeOwnAllBuffers(); 6778 } 6779 } else if (data2 == OMX_ALL) { 6780 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 6781 ALOGW("received flush complete event for OMX_ALL before ports have been" 6782 "flushed (%d/%d)", 6783 mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 6784 return false; 6785 } 6786 6787 changeStateIfWeOwnAllBuffers(); 6788 } else { 6789 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 6790 } 6791 6792 return true; 6793 } 6794 6795 case OMX_EventPortSettingsChanged: 6796 { 6797 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 6798 msg->setInt32("type", omx_message::EVENT); 6799 msg->setInt32("node", mCodec->mNode); 6800 msg->setInt32("event", event); 6801 msg->setInt32("data1", data1); 6802 msg->setInt32("data2", data2); 6803 6804 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 6805 mCodec->mComponentName.c_str()); 6806 6807 mCodec->deferMessage(msg); 6808 6809 return true; 6810 } 6811 6812 default: 6813 return BaseState::onOMXEvent(event, data1, data2); 6814 } 6815 6816 return true; 6817} 6818 6819void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 6820 BaseState::onOutputBufferDrained(msg); 6821 6822 changeStateIfWeOwnAllBuffers(); 6823} 6824 6825void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 6826 BaseState::onInputBufferFilled(msg); 6827 6828 changeStateIfWeOwnAllBuffers(); 6829} 6830 6831void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 6832 if (mFlushComplete[kPortIndexInput] 6833 && mFlushComplete[kPortIndexOutput] 6834 && mCodec->allYourBuffersAreBelongToUs()) { 6835 // We now own all buffers except possibly those still queued with 6836 // the native window for rendering. Let's get those back as well. 6837 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 6838 6839 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 6840 6841 sp<AMessage> notify = mCodec->mNotify->dup(); 6842 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6843 notify->post(); 6844 6845 mCodec->mPortEOS[kPortIndexInput] = 6846 mCodec->mPortEOS[kPortIndexOutput] = false; 6847 6848 mCodec->mInputEOSResult = OK; 6849 6850 if (mCodec->mSkipCutBuffer != NULL) { 6851 mCodec->mSkipCutBuffer->clear(); 6852 } 6853 6854 mCodec->changeState(mCodec->mExecutingState); 6855 } 6856} 6857 6858} // namespace android 6859