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