ACodec.cpp revision 349d3fcb4afacf754f7b5b5186d2f258f5bf35e7
1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//#define LOG_NDEBUG 0 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define LOG_TAG "ACodec" 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <media/stagefright/ACodec.h> 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <binder/MemoryDealer.h> 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <media/stagefright/foundation/hexdump.h> 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <media/stagefright/foundation/ABuffer.h> 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <media/stagefright/foundation/ADebug.h> 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <media/stagefright/foundation/AMessage.h> 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <media/stagefright/MediaDefs.h> 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <media/stagefright/OMXClient.h> 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <surfaceflinger/Surface.h> 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <OMX_Component.h> 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtnamespace android { 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidttemplate<class T> 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void InitOMXParams(T *params) { 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->nSize = sizeof(T); 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->nVersion.s.nVersionMajor = 1; 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->nVersion.s.nVersionMinor = 0; 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->nVersion.s.nRevision = 0; 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->nVersion.s.nStep = 0; 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct CodecObserver : public BnOMXObserver { 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CodecObserver() {} 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void setNotificationMessage(const sp<AMessage> &msg) { 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNotify = msg; 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // from IOMXObserver 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void onMessage(const omx_message &omx_msg) { 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sp<AMessage> msg = mNotify->dup(); 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setInt32("type", omx_msg.type); 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setPointer("node", omx_msg.node); 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (omx_msg.type) { 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case omx_message::EVENT: 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setInt32("event", omx_msg.u.event_data.event); 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setInt32("data1", omx_msg.u.event_data.data1); 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setInt32("data2", omx_msg.u.event_data.data2); 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case omx_message::EMPTY_BUFFER_DONE: 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setPointer("buffer", omx_msg.u.buffer_data.buffer); 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case omx_message::FILL_BUFFER_DONE: 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setPointer( 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "buffer", omx_msg.u.extended_buffer_data.buffer); 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setInt32( 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "range_offset", 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt omx_msg.u.extended_buffer_data.range_offset); 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setInt32( 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "range_length", 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt omx_msg.u.extended_buffer_data.range_length); 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setInt32( 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "flags", 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt omx_msg.u.extended_buffer_data.flags); 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setInt64( 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "timestamp", 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt omx_msg.u.extended_buffer_data.timestamp); 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setPointer( 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "platform_private", 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt omx_msg.u.extended_buffer_data.platform_private); 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setPointer( 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "data_ptr", 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt omx_msg.u.extended_buffer_data.data_ptr); 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TRESPASS(); 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->post(); 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual ~CodecObserver() {} 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sp<AMessage> mNotify; 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::BaseState : public AState { 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt enum PortMode { 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt KEEP_BUFFERS, 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt RESUBMIT_BUFFERS, 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt FREE_BUFFERS, 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt }; 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ACodec *mCodec; 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual PortMode getPortMode(OMX_U32 portIndex); 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void onOutputBufferDrained(const sp<AMessage> &msg); 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void onInputBufferFilled(const sp<AMessage> &msg); 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void postFillThisBuffer(BufferInfo *info); 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool onOMXMessage(const sp<AMessage> &msg); 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID); 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool onOMXFillBufferDone( 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IOMX::buffer_id bufferID, 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t rangeOffset, size_t rangeLength, 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_U32 flags, 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int64_t timeUs, 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *platformPrivate, 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *dataPtr); 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void getMoreInputDataIfPossible(); 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(BaseState); 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::UninitializedState : public ACodec::BaseState { 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt UninitializedState(ACodec *codec); 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void onSetup(const sp<AMessage> &msg); 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::LoadedToIdleState : public ACodec::BaseState { 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LoadedToIdleState(ACodec *codec); 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void stateEntered(); 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t allocateBuffers(); 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::IdleToExecutingState : public ACodec::BaseState { 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IdleToExecutingState(ACodec *codec); 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void stateEntered(); 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::ExecutingState : public ACodec::BaseState { 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ExecutingState(ACodec *codec); 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void submitOutputBuffers(); 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // Submit output buffers to the decoder, submit input buffers to client 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // to fill with data. 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void resume(); 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // Returns true iff input and output buffers are in play. 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool active() const { return mActive; } 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual PortMode getPortMode(OMX_U32 portIndex); 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void stateEntered(); 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool mActive; 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OutputPortSettingsChangedState(ACodec *codec); 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual PortMode getPortMode(OMX_U32 portIndex); 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void stateEntered(); 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::ExecutingToIdleState : public ACodec::BaseState { 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ExecutingToIdleState(ACodec *codec); 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void stateEntered(); 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void onOutputBufferDrained(const sp<AMessage> &msg); 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void onInputBufferFilled(const sp<AMessage> &msg); 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void changeStateIfWeOwnAllBuffers(); 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::IdleToLoadedState : public ACodec::BaseState { 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IdleToLoadedState(ACodec *codec); 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void stateEntered(); 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::ErrorState : public ACodec::BaseState { 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ErrorState(ACodec *codec); 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void stateEntered(); 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(ErrorState); 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ACodec::FlushingState : public ACodec::BaseState { 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt FlushingState(ACodec *codec); 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprotected: 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onMessageReceived(const sp<AMessage> &msg); 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void stateEntered(); 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void onOutputBufferDrained(const sp<AMessage> &msg); 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt virtual void onInputBufferFilled(const sp<AMessage> &msg); 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtprivate: 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool mFlushComplete[2]; 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void changeStateIfWeOwnAllBuffers(); 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtACodec::ACodec() 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt : mNode(NULL), 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mSentFormat(false) { 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mUninitializedState = new UninitializedState(this); 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mLoadedToIdleState = new LoadedToIdleState(this); 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mIdleToExecutingState = new IdleToExecutingState(this); 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mExecutingState = new ExecutingState(this); 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mOutputPortSettingsChangedState = 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt new OutputPortSettingsChangedState(this); 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mExecutingToIdleState = new ExecutingToIdleState(this); 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mIdleToLoadedState = new IdleToLoadedState(this); 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mErrorState = new ErrorState(this); 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mFlushingState = new FlushingState(this); 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt changeState(mUninitializedState); 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtACodec::~ACodec() { 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::setNotificationMessage(const sp<AMessage> &msg) { 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNotify = msg; 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::initiateSetup(const sp<AMessage> &msg) { 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setWhat(kWhatSetup); 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->setTarget(id()); 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg->post(); 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::signalFlush() { 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (new AMessage(kWhatFlush, id()))->post(); 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::signalResume() { 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (new AMessage(kWhatResume, id()))->post(); 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::initiateShutdown() { 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (new AMessage(kWhatShutdown, id()))->post(); 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(mDealer[portIndex] == NULL); 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(mBuffers[portIndex].isEmpty()); 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return allocateOutputBuffersFromNativeWindow(); 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_PARAM_PORTDEFINITIONTYPE def; 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&def); 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nPortIndex = portIndex; 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->getParameter( 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGV("[%s] Allocating %lu buffers of size %lu on %s port", 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mComponentName.c_str(), 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nBufferCountActual, def.nBufferSize, 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt portIndex == kPortIndexInput ? "input" : "output"); 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t totalSize = def.nBufferCountActual * def.nBufferSize; 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec"); 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(mem.get() != NULL); 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IOMX::buffer_id buffer; 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if 0 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mOMX->allocateBufferWithBackup(mNode, portIndex, mem, &buffer); 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mOMX->useBuffer(mNode, portIndex, mem, &buffer); 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo info; 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info.mBufferID = buffer; 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info.mStatus = BufferInfo::OWNED_BY_US; 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info.mData = new ABuffer(mem->pointer(), def.nBufferSize); 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mBuffers[portIndex].push(info); 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::allocateOutputBuffersFromNativeWindow() { 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_PARAM_PORTDEFINITIONTYPE def; 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&def); 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nPortIndex = kPortIndexOutput; 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->getParameter( 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = native_window_set_buffers_geometry( 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNativeWindow.get(), 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.format.video.nFrameWidth, 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.format.video.nFrameHeight, 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.format.video.eColorFormat); 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != 0) { 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGE("native_window_set_buffers_geometry failed: %s (%d)", 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt strerror(-err), -err); 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // Increase the buffer count by one to allow for the ANativeWindow to hold 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // on to one of the buffers. 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nBufferCountActual++; 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mOMX->setParameter( 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // Set up the native window. 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // XXX TODO: Get the gralloc usage flags from the OMX plugin! 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = native_window_set_usage( 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNativeWindow.get(), 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != 0) { 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = native_window_set_buffer_count( 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNativeWindow.get(), def.nBufferCountActual); 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != 0) { 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt -err); 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // XXX TODO: Do something so the ANativeWindow knows that we'll need to get 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // the same set of buffers. 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGV("[%s] Allocating %lu buffers from a native window of size %lu on " 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "output port", 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize); 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // Dequeue buffers and send them to OMX 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_U32 i; 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < def.nBufferCountActual; i++) { 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt android_native_buffer_t *buf; 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf); 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != 0) { 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IOMX::buffer_id bufferId; 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &bufferId); 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != 0) { 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)", 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mComponentName.c_str(), 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufferId, graphicBuffer.get()); 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo info; 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info.mBufferID = bufferId; 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info.mStatus = BufferInfo::OWNED_BY_US; 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info.mData = new ABuffer(0); 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info.mGraphicBuffer = graphicBuffer; 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mBuffers[kPortIndexOutput].push(info); 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_U32 cancelStart; 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_U32 cancelEnd; 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != 0) { 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // If an error occurred while dequeuing we need to cancel any buffers 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // that were dequeued. 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cancelStart = 0; 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cancelEnd = i; 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // Return the last two buffers to the native window. 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // XXX TODO: The number of buffers the native window owns should 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // probably be queried from it when we put the native window in 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // fixed buffer pool mode (which needs to be implemented). 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // Currently it's hard-coded to 2. 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cancelStart = def.nBufferCountActual - 2; 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cancelEnd = def.nBufferCountActual; 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cancelBufferToNativeWindow(info); 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGV("[%s] Calling cancelBuffer on buffer %p", 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mComponentName.c_str(), info->mBufferID); 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int err = mNativeWindow->cancelBuffer( 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNativeWindow.get(), info->mGraphicBuffer.get()); 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(err, 0); 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt android_native_buffer_t *buf; 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf), 0); 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo *info = 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &mBuffers[kPortIndexOutput].editItemAt(i); 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (info->mGraphicBuffer->handle == buf->handle) { 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)info->mStatus, 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int)BufferInfo::OWNED_BY_NATIVE_WINDOW); 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info->mStatus = BufferInfo::OWNED_BY_US; 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return info; 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TRESPASS(); 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (size_t i = mBuffers[portIndex].size(); i-- > 0;) { 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((status_t)OK, freeBuffer(portIndex, i)); 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mDealer[portIndex].clear(); 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() { 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo *info = 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &mBuffers[kPortIndexOutput].editItemAt(i); 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (info->mStatus != 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo::OWNED_BY_COMPONENT) { 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // We shouldn't have sent out any buffers to the client at this 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // point. 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i)); 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(info->mStatus == BufferInfo::OWNED_BY_US 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (portIndex == kPortIndexOutput && mNativeWindow != NULL 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt && info->mStatus == BufferInfo::OWNED_BY_US) { 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info)); 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(mOMX->freeBuffer( 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, portIndex, info->mBufferID), 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (status_t)OK); 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mBuffers[portIndex].removeAt(i); 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 609526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 610526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtACodec::BufferInfo *ACodec::findBufferByID( 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt uint32_t portIndex, IOMX::buffer_id bufferID, 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ssize_t *index) { 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (info->mBufferID == bufferID) { 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (index != NULL) { 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *index = i; 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return info; 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TRESPASS(); 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::setComponentRole( 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool isEncoder, const char *mime) { 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct MimeToRole { 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *mime; 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *decoderRole; 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *encoderRole; 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt }; 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt static const MimeToRole kMimeToRole[] = { 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { MEDIA_MIMETYPE_AUDIO_MPEG, 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "audio_decoder.mp3", "audio_encoder.mp3" }, 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { MEDIA_MIMETYPE_AUDIO_AMR_NB, 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "audio_decoder.amrnb", "audio_encoder.amrnb" }, 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { MEDIA_MIMETYPE_AUDIO_AMR_WB, 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "audio_decoder.amrwb", "audio_encoder.amrwb" }, 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { MEDIA_MIMETYPE_AUDIO_AAC, 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "audio_decoder.aac", "audio_encoder.aac" }, 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { MEDIA_MIMETYPE_VIDEO_AVC, 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "video_decoder.avc", "video_encoder.avc" }, 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { MEDIA_MIMETYPE_VIDEO_MPEG4, 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "video_decoder.mpeg4", "video_encoder.mpeg4" }, 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { MEDIA_MIMETYPE_VIDEO_H263, 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "video_decoder.h263", "video_encoder.h263" }, 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt }; 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt static const size_t kNumMimeToRole = 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t i; 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < kNumMimeToRole; ++i) { 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcasecmp(mime, kMimeToRole[i].mime)) { 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (i == kNumMimeToRole) { 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *role = 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt isEncoder ? kMimeToRole[i].encoderRole 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt : kMimeToRole[i].decoderRole; 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (role != NULL) { 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_PARAM_COMPONENTROLETYPE roleParams; 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&roleParams); 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt strncpy((char *)roleParams.cRole, 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt role, OMX_MAX_STRINGNAME_SIZE - 1); 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->setParameter( 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamStandardComponentRole, 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &roleParams, sizeof(roleParams)); 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGW("[%s] Failed to set standard component role '%s'.", 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mComponentName.c_str(), role); 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::configureCodec( 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *mime, const sp<AMessage> &msg) { 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt setComponentRole(false /* isEncoder */, mime); 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strncasecmp(mime, "video/", 6)) { 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int32_t width, height; 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("width", &width)); 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("height", &height)); 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(setupVideoDecoder(mime, width, height), 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (status_t)OK); 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int32_t numChannels, sampleRate; 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("channel-count", &numChannels)); 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("sample-rate", &sampleRate)); 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(setupAACDecoder(numChannels, sampleRate), (status_t)OK); 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TRESPASS(); 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int32_t maxInputSize; 715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (msg->findInt32("max-input-size", &maxInputSize)) { 716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(setMinBufferSize(kPortIndexInput, (size_t)maxInputSize), 717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (status_t)OK); 718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) { 719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(setMinBufferSize(kPortIndexInput, 8192), // XXX 720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (status_t)OK); 721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) { 725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_PARAM_PORTDEFINITIONTYPE def; 726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&def); 727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nPortIndex = portIndex; 728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->getParameter( 730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 734526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 735526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 736526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (def.nBufferSize >= size) { 737526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 738526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 739526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 740526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nBufferSize = size; 741526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 742526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mOMX->setParameter( 743526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 744526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 745526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 746526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 747526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 748526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 749526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mOMX->getParameter( 750526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 751526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 752526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 753526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 754526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 755526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 756526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(def.nBufferSize >= size); 757526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 758526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 759526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 760526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 761526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::setupAACDecoder(int32_t numChannels, int32_t sampleRate) { 762526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_AUDIO_PARAM_AACPROFILETYPE profile; 763526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&profile); 764526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt profile.nPortIndex = kPortIndexInput; 765526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 766526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->getParameter( 767526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 768526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 769526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 770526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 771526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 772526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 773526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt profile.nChannels = numChannels; 774526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt profile.nSampleRate = sampleRate; 775526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 776526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 777526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mOMX->setParameter( 778526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 779526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 780526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 781526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 782526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 783526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::setVideoPortFormatType( 784526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_U32 portIndex, 785526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_VIDEO_CODINGTYPE compressionFormat, 786526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_COLOR_FORMATTYPE colorFormat) { 787526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_VIDEO_PARAM_PORTFORMATTYPE format; 788526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&format); 789526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt format.nPortIndex = portIndex; 790526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt format.nIndex = 0; 791526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool found = false; 792526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 793526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_U32 index = 0; 794526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (;;) { 795526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt format.nIndex = index; 796526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->getParameter( 797526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamVideoPortFormat, 798526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &format, sizeof(format)); 799526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 800526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 801526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 802526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 803526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 804526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // The following assertion is violated by TI's video decoder. 805526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // CHECK_EQ(format.nIndex, index); 806526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 807526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) { 808526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (portIndex == kPortIndexInput 809526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt && colorFormat == format.eColorFormat) { 810526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // eCompressionFormat does not seem right. 811526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt found = true; 812526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 813526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 814526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (portIndex == kPortIndexOutput 815526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt && compressionFormat == format.eCompressionFormat) { 816526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // eColorFormat does not seem right. 817526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt found = true; 818526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 819526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 820526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 821526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 822526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (format.eCompressionFormat == compressionFormat 823526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt && format.eColorFormat == colorFormat) { 824526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt found = true; 825526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 826526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 827526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 828526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ++index; 829526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 830526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 831526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!found) { 832526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return UNKNOWN_ERROR; 833526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 834526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 835526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->setParameter( 836526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamVideoPortFormat, 837526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &format, sizeof(format)); 838526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 839526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 840526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 841526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 842526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::setSupportedOutputFormat() { 843526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_VIDEO_PARAM_PORTFORMATTYPE format; 844526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&format); 845526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt format.nPortIndex = kPortIndexOutput; 846526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt format.nIndex = 0; 847526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 848526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->getParameter( 849526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamVideoPortFormat, 850526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &format, sizeof(format)); 851526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(err, (status_t)OK); 852526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); 853526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 854526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 855526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 856526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar 857526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 858526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt || format.eColorFormat == OMX_COLOR_FormatCbYCrY 859526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); 860526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 861526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return mOMX->setParameter( 862526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamVideoPortFormat, 863526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &format, sizeof(format)); 864526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 865526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 866526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::setupVideoDecoder( 867526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *mime, int32_t width, int32_t height) { 868526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 869526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 870526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt compressionFormat = OMX_VIDEO_CodingAVC; 871526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 872526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt compressionFormat = OMX_VIDEO_CodingMPEG4; 873526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 874526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt compressionFormat = OMX_VIDEO_CodingH263; 875526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 876526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TRESPASS(); 877526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 878526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 879526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = setVideoPortFormatType( 880526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 881526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 882526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 883526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 884526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 885526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 886526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = setSupportedOutputFormat(); 887526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 888526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 889526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 890526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 891526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 892526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = setVideoFormatOnPort( 893526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt kPortIndexInput, width, height, compressionFormat); 894526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 895526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 896526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 897526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 898526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 899526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = setVideoFormatOnPort( 900526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused); 901526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 902526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err != OK) { 903526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 904526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 905526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 906526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 907526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 908526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 909526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::setVideoFormatOnPort( 910526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_U32 portIndex, 911526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) { 912526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_PARAM_PORTDEFINITIONTYPE def; 913526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&def); 914526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nPortIndex = portIndex; 915526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 916526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 917526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 918526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status_t err = mOMX->getParameter( 919526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 920526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 921526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(err, (status_t)OK); 922526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 923526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (portIndex == kPortIndexInput) { 924526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt // XXX Need a (much) better heuristic to compute input buffer sizes. 925526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const size_t X = 64 * 1024; 926526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (def.nBufferSize < X) { 927526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nBufferSize = X; 928526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 929526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 930526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 931526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 932526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 933526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt video_def->nFrameWidth = width; 934526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt video_def->nFrameHeight = height; 935526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 936526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (portIndex == kPortIndexInput) { 937526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt video_def->eCompressionFormat = compressionFormat; 938526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt video_def->eColorFormat = OMX_COLOR_FormatUnused; 939526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 940526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 941526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = mOMX->setParameter( 942526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 943526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 944526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return err; 945526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 946526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 947526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatus_t ACodec::initNativeWindow() { 948526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (mNativeWindow != NULL) { 949526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 950526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 951526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 952526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 953526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return OK; 954526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 955526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 956526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtbool ACodec::allYourBuffersAreBelongToUs( 957526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_U32 portIndex) { 958526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 959526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 960526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 961526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (info->mStatus != BufferInfo::OWNED_BY_US 962526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 963526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGV("[%s] Buffer %p on port %ld still has status %d", 964526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mComponentName.c_str(), 965526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info->mBufferID, portIndex, info->mStatus); 966526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return false; 967526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 968526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 969526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 970526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return true; 971526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 972526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 973526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtbool ACodec::allYourBuffersAreBelongToUs() { 974526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return allYourBuffersAreBelongToUs(kPortIndexInput) 975526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt && allYourBuffersAreBelongToUs(kPortIndexOutput); 976526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 977526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 978526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::deferMessage(const sp<AMessage> &msg) { 979526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bool wasEmptyBefore = mDeferredQueue.empty(); 980526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mDeferredQueue.push_back(msg); 981526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 982526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 983526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::processDeferredMessages() { 984526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt List<sp<AMessage> > queue = mDeferredQueue; 985526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mDeferredQueue.clear(); 986526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 987526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt List<sp<AMessage> >::iterator it = queue.begin(); 988526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (it != queue.end()) { 989526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt onMessageReceived(*it++); 990526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 991526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 992526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 993526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ACodec::sendFormatChange() { 994526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sp<AMessage> notify = mNotify->dup(); 995526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->setInt32("what", kWhatOutputFormatChanged); 996526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 997526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_PARAM_PORTDEFINITIONTYPE def; 998526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&def); 999526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt def.nPortIndex = kPortIndexOutput; 1000526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1001526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(mOMX->getParameter( 1002526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), 1003526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (status_t)OK); 1004526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1005526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)def.eDir, (int)OMX_DirOutput); 1006526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1007526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (def.eDomain) { 1008526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case OMX_PortDomainVideo: 1009526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 1010526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 1011526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1012526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 1013526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->setInt32("width", videoDef->nFrameWidth); 1014526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->setInt32("height", videoDef->nFrameHeight); 1015526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1016526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_CONFIG_RECTTYPE rect; 1017526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(&rect); 1018526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nPortIndex = kPortIndexOutput; 1019526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1020526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (mOMX->getConfig( 1021526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexConfigCommonOutputCrop, 1022526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &rect, sizeof(rect)) != OK) { 1023526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nLeft = 0; 1024526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nTop = 0; 1025526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nWidth = videoDef->nFrameWidth; 1026526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nHeight = videoDef->nFrameHeight; 1027526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1028526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1029526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_GE(rect.nLeft, 0); 1030526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_GE(rect.nTop, 0); 1031526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_GE(rect.nWidth, 0u); 1032526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_GE(rect.nHeight, 0u); 1033526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth); 1034526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight); 1035526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1036526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->setRect( 1037526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "crop", 1038526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nLeft, 1039526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nTop, 1040526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nLeft + rect.nWidth - 1, 1041526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rect.nTop + rect.nHeight - 1); 1042526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1043526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (mNativeWindow != NULL) { 1044526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt android_native_rect_t crop; 1045526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt crop.left = rect.nLeft; 1046526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt crop.top = rect.nTop; 1047526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt crop.right = rect.nLeft + rect.nWidth - 1; 1048526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt crop.bottom = rect.nTop + rect.nHeight - 1; 1049526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1050526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(0, native_window_set_crop( 1051526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNativeWindow.get(), &crop)); 1052526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1053526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1054526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1055526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1056526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case OMX_PortDomainAudio: 1057526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 1058526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 1059526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM); 1060526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1061526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_AUDIO_PARAM_PCMMODETYPE params; 1062526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt InitOMXParams(¶ms); 1063526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params.nPortIndex = kPortIndexOutput; 1064526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1065526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(mOMX->getParameter( 1066526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mNode, OMX_IndexParamAudioPcm, 1067526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ¶ms, sizeof(params)), 1068526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (status_t)OK); 1069526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1070526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(params.nChannels == 1 || params.bInterleaved); 1071526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(params.nBitPerSample, 16u); 1072526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); 1073526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); 1074526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1075526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 1076526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->setInt32("channel-count", params.nChannels); 1077526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->setInt32("sample-rate", params.nSamplingRate); 1078526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1079526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1080526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1081526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 1082526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TRESPASS(); 1083526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1084526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1085526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt notify->post(); 1086526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1087526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mSentFormat = true; 1088526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1089526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1090526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt//////////////////////////////////////////////////////////////////////////////// 1091526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1092526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 1093526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt : AState(parentState), 1094526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mCodec(codec) { 1095526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1096526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1097526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) { 1098526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return KEEP_BUFFERS; 1099526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 1102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (msg->what()) { 1103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case kWhatInputBufferFilled: 1104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 1105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt onInputBufferFilled(msg); 1106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case kWhatOutputBufferDrained: 1110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 1111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt onOutputBufferDrained(msg); 1112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case ACodec::kWhatOMXMessage: 1116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 1117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return onOMXMessage(msg); 1118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 1121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return false; 1122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return true; 1125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 1128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int32_t type; 1129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("type", &type)); 1130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IOMX::node_id nodeID; 1132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findPointer("node", &nodeID)); 1133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ(nodeID, mCodec->mNode); 1134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (type) { 1136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case omx_message::EVENT: 1137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 1138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int32_t event, data1, data2; 1139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("event", &event)); 1140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("data1", &data1)); 1141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("data2", &data2)); 1142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return onOMXEvent( 1144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt static_cast<OMX_EVENTTYPE>(event), 1145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt static_cast<OMX_U32>(data1), 1146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt static_cast<OMX_U32>(data2)); 1147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case omx_message::EMPTY_BUFFER_DONE: 1150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 1151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IOMX::buffer_id bufferID; 1152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findPointer("buffer", &bufferID)); 1153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return onOMXEmptyBufferDone(bufferID); 1155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case omx_message::FILL_BUFFER_DONE: 1158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 1159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IOMX::buffer_id bufferID; 1160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findPointer("buffer", &bufferID)); 1161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int32_t rangeOffset, rangeLength, flags; 1163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int64_t timeUs; 1164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *platformPrivate; 1165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *dataPtr; 1166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("range_offset", &rangeOffset)); 1168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("range_length", &rangeLength)); 1169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt32("flags", &flags)); 1170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findInt64("timestamp", &timeUs)); 1171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findPointer("platform_private", &platformPrivate)); 1172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK(msg->findPointer("data_ptr", &dataPtr)); 1173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return onOMXFillBufferDone( 1175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufferID, 1176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (size_t)rangeOffset, (size_t)rangeLength, 1177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (OMX_U32)flags, 1178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeUs, 1179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt platformPrivate, 1180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dataPtr); 1181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 1184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TRESPASS(); 1185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtbool ACodec::BaseState::onOMXEvent( 1190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (event != OMX_EventError) { 1192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)", 1193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mCodec->mComponentName.c_str(), event, data1, data2); 1194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return false; 1196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGE("[%s] ERROR(0x%08lx, 0x%08lx)", 1199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mCodec->mComponentName.c_str(), data1, data2); 1200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mCodec->changeState(mCodec->mErrorState); 1202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return true; 1204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) { 1207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LOGV("[%s] onOMXEmptyBufferDone %p", 1208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mCodec->mComponentName.c_str(), bufferID); 1209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BufferInfo *info = 1211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt mCodec->findBufferByID(kPortIndexInput, bufferID); 1212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 1214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt info->mStatus = BufferInfo::OWNED_BY_US; 1215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PortMode mode = getPortMode(kPortIndexInput); 1217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1218 switch (mode) { 1219 case KEEP_BUFFERS: 1220 break; 1221 1222 case RESUBMIT_BUFFERS: 1223 postFillThisBuffer(info); 1224 break; 1225 1226 default: 1227 { 1228 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 1229 TRESPASS(); // Not currently used 1230 break; 1231 } 1232 } 1233 1234 return true; 1235} 1236 1237void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 1238 if (mCodec->mPortEOS[kPortIndexInput]) { 1239 return; 1240 } 1241 1242 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 1243 1244 sp<AMessage> notify = mCodec->mNotify->dup(); 1245 notify->setInt32("what", ACodec::kWhatFillThisBuffer); 1246 notify->setPointer("buffer-id", info->mBufferID); 1247 1248 info->mData->meta()->clear(); 1249 notify->setObject("buffer", info->mData); 1250 1251 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id()); 1252 reply->setPointer("buffer-id", info->mBufferID); 1253 1254 notify->setMessage("reply", reply); 1255 1256 notify->post(); 1257 1258 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 1259} 1260 1261void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 1262 IOMX::buffer_id bufferID; 1263 CHECK(msg->findPointer("buffer-id", &bufferID)); 1264 1265 sp<RefBase> obj; 1266 int32_t err = OK; 1267 if (!msg->findObject("buffer", &obj)) { 1268 CHECK(msg->findInt32("err", &err)); 1269 1270 LOGV("[%s] saw error %d instead of an input buffer", 1271 mCodec->mComponentName.c_str(), err); 1272 1273 obj.clear(); 1274 } 1275 1276 sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get()); 1277 1278 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 1279 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM); 1280 1281 info->mStatus = BufferInfo::OWNED_BY_US; 1282 1283 PortMode mode = getPortMode(kPortIndexInput); 1284 1285 switch (mode) { 1286 case KEEP_BUFFERS: 1287 { 1288 if (buffer == NULL) { 1289 mCodec->mPortEOS[kPortIndexInput] = true; 1290 } 1291 break; 1292 } 1293 1294 case RESUBMIT_BUFFERS: 1295 { 1296 if (buffer != NULL) { 1297 CHECK(!mCodec->mPortEOS[kPortIndexInput]); 1298 1299 int64_t timeUs; 1300 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 1301 1302 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 1303 1304 int32_t isCSD; 1305 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 1306 flags |= OMX_BUFFERFLAG_CODECCONFIG; 1307 } 1308 1309 if (buffer != info->mData) { 1310 if (0 && !(flags & OMX_BUFFERFLAG_CODECCONFIG)) { 1311 LOGV("[%s] Needs to copy input data.", 1312 mCodec->mComponentName.c_str()); 1313 } 1314 1315 CHECK_LE(buffer->size(), info->mData->capacity()); 1316 memcpy(info->mData->data(), buffer->data(), buffer->size()); 1317 } 1318 1319 LOGV("[%s] calling emptyBuffer %p", 1320 mCodec->mComponentName.c_str(), bufferID); 1321 1322 CHECK_EQ(mCodec->mOMX->emptyBuffer( 1323 mCodec->mNode, 1324 bufferID, 1325 0, 1326 buffer->size(), 1327 flags, 1328 timeUs), 1329 (status_t)OK); 1330 1331 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1332 1333 getMoreInputDataIfPossible(); 1334 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 1335 LOGV("[%s] Signalling EOS on the input port", 1336 mCodec->mComponentName.c_str()); 1337 1338 LOGV("[%s] calling emptyBuffer %p", 1339 mCodec->mComponentName.c_str(), bufferID); 1340 1341 CHECK_EQ(mCodec->mOMX->emptyBuffer( 1342 mCodec->mNode, 1343 bufferID, 1344 0, 1345 0, 1346 OMX_BUFFERFLAG_EOS, 1347 0), 1348 (status_t)OK); 1349 1350 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1351 1352 mCodec->mPortEOS[kPortIndexInput] = true; 1353 } 1354 break; 1355 1356 default: 1357 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 1358 break; 1359 } 1360 } 1361} 1362 1363void ACodec::BaseState::getMoreInputDataIfPossible() { 1364 if (mCodec->mPortEOS[kPortIndexInput]) { 1365 return; 1366 } 1367 1368 BufferInfo *eligible = NULL; 1369 1370 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 1371 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 1372 1373#if 0 1374 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 1375 // There's already a "read" pending. 1376 return; 1377 } 1378#endif 1379 1380 if (info->mStatus == BufferInfo::OWNED_BY_US) { 1381 eligible = info; 1382 } 1383 } 1384 1385 if (eligible == NULL) { 1386 return; 1387 } 1388 1389 postFillThisBuffer(eligible); 1390} 1391 1392bool ACodec::BaseState::onOMXFillBufferDone( 1393 IOMX::buffer_id bufferID, 1394 size_t rangeOffset, size_t rangeLength, 1395 OMX_U32 flags, 1396 int64_t timeUs, 1397 void *platformPrivate, 1398 void *dataPtr) { 1399 LOGV("[%s] onOMXFillBufferDone %p", 1400 mCodec->mComponentName.c_str(), bufferID); 1401 1402 ssize_t index; 1403 BufferInfo *info = 1404 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 1405 1406 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 1407 1408 info->mStatus = BufferInfo::OWNED_BY_US; 1409 1410 PortMode mode = getPortMode(kPortIndexOutput); 1411 1412 switch (mode) { 1413 case KEEP_BUFFERS: 1414 break; 1415 1416 case RESUBMIT_BUFFERS: 1417 { 1418 if (rangeLength == 0) { 1419 if (!(flags & OMX_BUFFERFLAG_EOS)) { 1420 LOGV("[%s] calling fillBuffer %p", 1421 mCodec->mComponentName.c_str(), info->mBufferID); 1422 1423 CHECK_EQ(mCodec->mOMX->fillBuffer( 1424 mCodec->mNode, info->mBufferID), 1425 (status_t)OK); 1426 1427 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1428 } 1429 } else { 1430 if (!mCodec->mSentFormat) { 1431 mCodec->sendFormatChange(); 1432 } 1433 1434 if (mCodec->mNativeWindow == NULL) { 1435 info->mData->setRange(rangeOffset, rangeLength); 1436 } 1437 1438 info->mData->meta()->setInt64("timeUs", timeUs); 1439 1440 sp<AMessage> notify = mCodec->mNotify->dup(); 1441 notify->setInt32("what", ACodec::kWhatDrainThisBuffer); 1442 notify->setPointer("buffer-id", info->mBufferID); 1443 notify->setObject("buffer", info->mData); 1444 1445 sp<AMessage> reply = 1446 new AMessage(kWhatOutputBufferDrained, mCodec->id()); 1447 1448 reply->setPointer("buffer-id", info->mBufferID); 1449 1450 notify->setMessage("reply", reply); 1451 1452 notify->post(); 1453 1454 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 1455 } 1456 1457 if (flags & OMX_BUFFERFLAG_EOS) { 1458 sp<AMessage> notify = mCodec->mNotify->dup(); 1459 notify->setInt32("what", ACodec::kWhatEOS); 1460 notify->post(); 1461 1462 mCodec->mPortEOS[kPortIndexOutput] = true; 1463 } 1464 break; 1465 } 1466 1467 default: 1468 { 1469 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 1470 1471 CHECK_EQ((status_t)OK, 1472 mCodec->freeBuffer(kPortIndexOutput, index)); 1473 break; 1474 } 1475 } 1476 1477 return true; 1478} 1479 1480void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 1481 IOMX::buffer_id bufferID; 1482 CHECK(msg->findPointer("buffer-id", &bufferID)); 1483 1484 ssize_t index; 1485 BufferInfo *info = 1486 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 1487 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); 1488 1489 int32_t render; 1490 if (mCodec->mNativeWindow != NULL 1491 && msg->findInt32("render", &render) && render != 0) { 1492 // The client wants this buffer to be rendered. 1493 1494 CHECK_EQ(mCodec->mNativeWindow->queueBuffer( 1495 mCodec->mNativeWindow.get(), 1496 info->mGraphicBuffer.get()), 1497 0); 1498 1499 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1500 } else { 1501 info->mStatus = BufferInfo::OWNED_BY_US; 1502 } 1503 1504 PortMode mode = getPortMode(kPortIndexOutput); 1505 1506 switch (mode) { 1507 case KEEP_BUFFERS: 1508 { 1509 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 1510 1511 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1512 // We cannot resubmit the buffer we just rendered, dequeue 1513 // the spare instead. 1514 1515 info = mCodec->dequeueBufferFromNativeWindow(); 1516 } 1517 break; 1518 } 1519 1520 case RESUBMIT_BUFFERS: 1521 { 1522 if (!mCodec->mPortEOS[kPortIndexOutput]) { 1523 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1524 // We cannot resubmit the buffer we just rendered, dequeue 1525 // the spare instead. 1526 1527 info = mCodec->dequeueBufferFromNativeWindow(); 1528 } 1529 1530 LOGV("[%s] calling fillBuffer %p", 1531 mCodec->mComponentName.c_str(), info->mBufferID); 1532 1533 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 1534 (status_t)OK); 1535 1536 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1537 } 1538 break; 1539 } 1540 1541 default: 1542 { 1543 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 1544 1545 CHECK_EQ((status_t)OK, 1546 mCodec->freeBuffer(kPortIndexOutput, index)); 1547 break; 1548 } 1549 } 1550} 1551 1552//////////////////////////////////////////////////////////////////////////////// 1553 1554ACodec::UninitializedState::UninitializedState(ACodec *codec) 1555 : BaseState(codec) { 1556} 1557 1558bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 1559 bool handled = false; 1560 1561 switch (msg->what()) { 1562 case ACodec::kWhatSetup: 1563 { 1564 onSetup(msg); 1565 1566 handled = true; 1567 break; 1568 } 1569 1570 case ACodec::kWhatShutdown: 1571 { 1572 sp<AMessage> notify = mCodec->mNotify->dup(); 1573 notify->setInt32("what", ACodec::kWhatShutdownCompleted); 1574 notify->post(); 1575 1576 handled = true; 1577 } 1578 1579 case ACodec::kWhatFlush: 1580 { 1581 sp<AMessage> notify = mCodec->mNotify->dup(); 1582 notify->setInt32("what", ACodec::kWhatFlushCompleted); 1583 notify->post(); 1584 1585 handled = true; 1586 } 1587 1588 default: 1589 return BaseState::onMessageReceived(msg); 1590 } 1591 1592 return handled; 1593} 1594 1595void ACodec::UninitializedState::onSetup( 1596 const sp<AMessage> &msg) { 1597 OMXClient client; 1598 CHECK_EQ(client.connect(), (status_t)OK); 1599 1600 sp<IOMX> omx = client.interface(); 1601 1602 AString mime; 1603 CHECK(msg->findString("mime", &mime)); 1604 1605 AString componentName; 1606 1607 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 1608 componentName = "OMX.Nvidia.h264.decode"; 1609 } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 1610 componentName = "OMX.Nvidia.aac.decoder"; 1611 } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_MPEG)) { 1612 componentName = "OMX.Nvidia.mp3.decoder"; 1613 } else { 1614 TRESPASS(); 1615 } 1616 1617 sp<CodecObserver> observer = new CodecObserver; 1618 1619 IOMX::node_id node; 1620 CHECK_EQ(omx->allocateNode(componentName.c_str(), observer, &node), 1621 (status_t)OK); 1622 1623 sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id()); 1624 observer->setNotificationMessage(notify); 1625 1626 mCodec->mComponentName = componentName; 1627 mCodec->mOMX = omx; 1628 mCodec->mNode = node; 1629 1630 mCodec->mPortEOS[kPortIndexInput] = 1631 mCodec->mPortEOS[kPortIndexOutput] = false; 1632 1633 mCodec->configureCodec(mime.c_str(), msg); 1634 1635 sp<RefBase> obj; 1636 if (msg->findObject("surface", &obj)) { 1637 mCodec->mNativeWindow = static_cast<Surface *>(obj.get()); 1638 } 1639 1640 CHECK_EQ((status_t)OK, mCodec->initNativeWindow()); 1641 1642 CHECK_EQ(omx->sendCommand(node, OMX_CommandStateSet, OMX_StateIdle), 1643 (status_t)OK); 1644 1645 mCodec->changeState(mCodec->mLoadedToIdleState); 1646} 1647 1648//////////////////////////////////////////////////////////////////////////////// 1649 1650ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 1651 : BaseState(codec) { 1652} 1653 1654void ACodec::LoadedToIdleState::stateEntered() { 1655 LOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 1656 1657 CHECK_EQ(allocateBuffers(), (status_t)OK); 1658} 1659 1660status_t ACodec::LoadedToIdleState::allocateBuffers() { 1661 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 1662 1663 if (err != OK) { 1664 return err; 1665 } 1666 1667 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 1668} 1669 1670bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 1671 switch (msg->what()) { 1672 case kWhatShutdown: 1673 { 1674 mCodec->deferMessage(msg); 1675 return true; 1676 } 1677 1678 default: 1679 return BaseState::onMessageReceived(msg); 1680 } 1681} 1682 1683bool ACodec::LoadedToIdleState::onOMXEvent( 1684 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1685 switch (event) { 1686 case OMX_EventCmdComplete: 1687 { 1688 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 1689 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 1690 1691 CHECK_EQ(mCodec->mOMX->sendCommand( 1692 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting), 1693 (status_t)OK); 1694 1695 mCodec->changeState(mCodec->mIdleToExecutingState); 1696 1697 return true; 1698 } 1699 1700 default: 1701 return BaseState::onOMXEvent(event, data1, data2); 1702 } 1703} 1704 1705//////////////////////////////////////////////////////////////////////////////// 1706 1707ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 1708 : BaseState(codec) { 1709} 1710 1711void ACodec::IdleToExecutingState::stateEntered() { 1712 LOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 1713} 1714 1715bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 1716 switch (msg->what()) { 1717 case kWhatShutdown: 1718 { 1719 mCodec->deferMessage(msg); 1720 return true; 1721 } 1722 1723 default: 1724 return BaseState::onMessageReceived(msg); 1725 } 1726} 1727 1728bool ACodec::IdleToExecutingState::onOMXEvent( 1729 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1730 switch (event) { 1731 case OMX_EventCmdComplete: 1732 { 1733 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 1734 CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting); 1735 1736 mCodec->mExecutingState->resume(); 1737 mCodec->changeState(mCodec->mExecutingState); 1738 1739 return true; 1740 } 1741 1742 default: 1743 return BaseState::onOMXEvent(event, data1, data2); 1744 } 1745} 1746 1747//////////////////////////////////////////////////////////////////////////////// 1748 1749ACodec::ExecutingState::ExecutingState(ACodec *codec) 1750 : BaseState(codec), 1751 mActive(false) { 1752} 1753 1754ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 1755 OMX_U32 portIndex) { 1756 return RESUBMIT_BUFFERS; 1757} 1758 1759void ACodec::ExecutingState::submitOutputBuffers() { 1760 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 1761 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 1762 1763 if (mCodec->mNativeWindow != NULL) { 1764 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 1765 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 1766 1767 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1768 continue; 1769 } 1770 1771 status_t err = mCodec->mNativeWindow->lockBuffer( 1772 mCodec->mNativeWindow.get(), 1773 info->mGraphicBuffer.get()); 1774 CHECK_EQ(err, (status_t)OK); 1775 } else { 1776 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 1777 } 1778 1779 LOGV("[%s] calling fillBuffer %p", 1780 mCodec->mComponentName.c_str(), info->mBufferID); 1781 1782 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 1783 (status_t)OK); 1784 1785 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1786 } 1787} 1788 1789void ACodec::ExecutingState::resume() { 1790 if (mActive) { 1791 LOGV("[%s] We're already active, no need to resume.", 1792 mCodec->mComponentName.c_str()); 1793 1794 return; 1795 } 1796 1797 submitOutputBuffers(); 1798 1799 // Post the first input buffer. 1800 CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u); 1801 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0); 1802 1803 postFillThisBuffer(info); 1804 1805 mActive = true; 1806} 1807 1808void ACodec::ExecutingState::stateEntered() { 1809 LOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 1810 1811 mCodec->processDeferredMessages(); 1812} 1813 1814bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 1815 bool handled = false; 1816 1817 switch (msg->what()) { 1818 case kWhatShutdown: 1819 { 1820 mActive = false; 1821 1822 CHECK_EQ(mCodec->mOMX->sendCommand( 1823 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), 1824 (status_t)OK); 1825 1826 mCodec->changeState(mCodec->mExecutingToIdleState); 1827 1828 handled = true; 1829 break; 1830 } 1831 1832 case kWhatFlush: 1833 { 1834 mActive = false; 1835 1836 CHECK_EQ(mCodec->mOMX->sendCommand( 1837 mCodec->mNode, OMX_CommandFlush, OMX_ALL), 1838 (status_t)OK); 1839 1840 mCodec->changeState(mCodec->mFlushingState); 1841 1842 handled = true; 1843 break; 1844 } 1845 1846 case kWhatResume: 1847 { 1848 resume(); 1849 1850 handled = true; 1851 break; 1852 } 1853 1854 default: 1855 handled = BaseState::onMessageReceived(msg); 1856 break; 1857 } 1858 1859 return handled; 1860} 1861 1862bool ACodec::ExecutingState::onOMXEvent( 1863 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1864 switch (event) { 1865 case OMX_EventPortSettingsChanged: 1866 { 1867 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 1868 1869 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 1870 CHECK_EQ(mCodec->mOMX->sendCommand( 1871 mCodec->mNode, 1872 OMX_CommandPortDisable, kPortIndexOutput), 1873 (status_t)OK); 1874 1875 mCodec->freeOutputBuffersNotOwnedByComponent(); 1876 1877 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 1878 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 1879 mCodec->mSentFormat = false; 1880 } else { 1881 LOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx", 1882 mCodec->mComponentName.c_str(), data2); 1883 } 1884 1885 return true; 1886 } 1887 1888 case OMX_EventBufferFlag: 1889 { 1890 return true; 1891 } 1892 1893 default: 1894 return BaseState::onOMXEvent(event, data1, data2); 1895 } 1896} 1897 1898//////////////////////////////////////////////////////////////////////////////// 1899 1900ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 1901 ACodec *codec) 1902 : BaseState(codec) { 1903} 1904 1905ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 1906 OMX_U32 portIndex) { 1907 if (portIndex == kPortIndexOutput) { 1908 return FREE_BUFFERS; 1909 } 1910 1911 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 1912 1913 return RESUBMIT_BUFFERS; 1914} 1915 1916bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 1917 const sp<AMessage> &msg) { 1918 bool handled = false; 1919 1920 switch (msg->what()) { 1921 case kWhatFlush: 1922 case kWhatShutdown: 1923 case kWhatResume: 1924 { 1925 if (msg->what() == kWhatResume) { 1926 LOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 1927 } 1928 1929 mCodec->deferMessage(msg); 1930 handled = true; 1931 break; 1932 } 1933 1934 default: 1935 handled = BaseState::onMessageReceived(msg); 1936 break; 1937 } 1938 1939 return handled; 1940} 1941 1942void ACodec::OutputPortSettingsChangedState::stateEntered() { 1943 LOGV("[%s] Now handling output port settings change", 1944 mCodec->mComponentName.c_str()); 1945} 1946 1947bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 1948 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1949 switch (event) { 1950 case OMX_EventCmdComplete: 1951 { 1952 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 1953 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 1954 1955 LOGV("[%s] Output port now disabled.", 1956 mCodec->mComponentName.c_str()); 1957 1958 CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty()); 1959 mCodec->mDealer[kPortIndexOutput].clear(); 1960 1961 CHECK_EQ(mCodec->mOMX->sendCommand( 1962 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput), 1963 (status_t)OK); 1964 1965 CHECK_EQ(mCodec->allocateBuffersOnPort(kPortIndexOutput), 1966 (status_t)OK); 1967 1968 return true; 1969 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 1970 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 1971 1972 mCodec->mSentFormat = false; 1973 1974 LOGV("[%s] Output port now reenabled.", 1975 mCodec->mComponentName.c_str()); 1976 1977 if (mCodec->mExecutingState->active()) { 1978 mCodec->mExecutingState->submitOutputBuffers(); 1979 } 1980 1981 mCodec->changeState(mCodec->mExecutingState); 1982 1983 return true; 1984 } 1985 1986 return false; 1987 } 1988 1989 default: 1990 return false; 1991 } 1992} 1993 1994//////////////////////////////////////////////////////////////////////////////// 1995 1996ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 1997 : BaseState(codec) { 1998} 1999 2000bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 2001 bool handled = false; 2002 2003 switch (msg->what()) { 2004 case kWhatFlush: 2005 { 2006 // Don't send me a flush request if you previously wanted me 2007 // to shutdown. 2008 TRESPASS(); 2009 break; 2010 } 2011 2012 case kWhatShutdown: 2013 { 2014 // We're already doing that... 2015 2016 handled = true; 2017 break; 2018 } 2019 2020 default: 2021 handled = BaseState::onMessageReceived(msg); 2022 break; 2023 } 2024 2025 return handled; 2026} 2027 2028void ACodec::ExecutingToIdleState::stateEntered() { 2029 LOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 2030 2031 mCodec->mSentFormat = false; 2032} 2033 2034bool ACodec::ExecutingToIdleState::onOMXEvent( 2035 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2036 switch (event) { 2037 case OMX_EventCmdComplete: 2038 { 2039 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 2040 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 2041 2042 changeStateIfWeOwnAllBuffers(); 2043 2044 return true; 2045 } 2046 2047 case OMX_EventPortSettingsChanged: 2048 case OMX_EventBufferFlag: 2049 { 2050 // We're shutting down and don't care about this anymore. 2051 return true; 2052 } 2053 2054 default: 2055 return BaseState::onOMXEvent(event, data1, data2); 2056 } 2057} 2058void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 2059 if (mCodec->allYourBuffersAreBelongToUs()) { 2060 CHECK_EQ(mCodec->mOMX->sendCommand( 2061 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded), 2062 (status_t)OK); 2063 2064 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK); 2065 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK); 2066 2067 mCodec->changeState(mCodec->mIdleToLoadedState); 2068 } 2069} 2070 2071void ACodec::ExecutingToIdleState::onInputBufferFilled( 2072 const sp<AMessage> &msg) { 2073 BaseState::onInputBufferFilled(msg); 2074 2075 changeStateIfWeOwnAllBuffers(); 2076} 2077 2078void ACodec::ExecutingToIdleState::onOutputBufferDrained( 2079 const sp<AMessage> &msg) { 2080 BaseState::onOutputBufferDrained(msg); 2081 2082 changeStateIfWeOwnAllBuffers(); 2083} 2084 2085//////////////////////////////////////////////////////////////////////////////// 2086 2087ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 2088 : BaseState(codec) { 2089} 2090 2091bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 2092 bool handled = false; 2093 2094 switch (msg->what()) { 2095 case kWhatShutdown: 2096 { 2097 // We're already doing that... 2098 2099 handled = true; 2100 break; 2101 } 2102 2103 case kWhatFlush: 2104 { 2105 // Don't send me a flush request if you previously wanted me 2106 // to shutdown. 2107 TRESPASS(); 2108 break; 2109 } 2110 2111 default: 2112 handled = BaseState::onMessageReceived(msg); 2113 break; 2114 } 2115 2116 return handled; 2117} 2118 2119void ACodec::IdleToLoadedState::stateEntered() { 2120 LOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 2121} 2122 2123bool ACodec::IdleToLoadedState::onOMXEvent( 2124 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2125 switch (event) { 2126 case OMX_EventCmdComplete: 2127 { 2128 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 2129 CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded); 2130 2131 LOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 2132 2133 CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK); 2134 2135 mCodec->mNativeWindow.clear(); 2136 mCodec->mNode = NULL; 2137 mCodec->mOMX.clear(); 2138 mCodec->mComponentName.clear(); 2139 2140 mCodec->changeState(mCodec->mUninitializedState); 2141 2142 sp<AMessage> notify = mCodec->mNotify->dup(); 2143 notify->setInt32("what", ACodec::kWhatShutdownCompleted); 2144 notify->post(); 2145 2146 return true; 2147 } 2148 2149 default: 2150 return BaseState::onOMXEvent(event, data1, data2); 2151 } 2152} 2153 2154//////////////////////////////////////////////////////////////////////////////// 2155 2156ACodec::ErrorState::ErrorState(ACodec *codec) 2157 : BaseState(codec) { 2158} 2159 2160bool ACodec::ErrorState::onMessageReceived(const sp<AMessage> &msg) { 2161 return BaseState::onMessageReceived(msg); 2162} 2163 2164void ACodec::ErrorState::stateEntered() { 2165 LOGV("[%s] Now in ErrorState", mCodec->mComponentName.c_str()); 2166} 2167 2168bool ACodec::ErrorState::onOMXEvent( 2169 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2170 LOGV("EVENT(%d, 0x%08lx, 0x%08lx)", event, data1, data2); 2171 return true; 2172} 2173 2174//////////////////////////////////////////////////////////////////////////////// 2175 2176ACodec::FlushingState::FlushingState(ACodec *codec) 2177 : BaseState(codec) { 2178} 2179 2180void ACodec::FlushingState::stateEntered() { 2181 LOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 2182 2183 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 2184} 2185 2186bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 2187 bool handled = false; 2188 2189 switch (msg->what()) { 2190 case kWhatShutdown: 2191 { 2192 mCodec->deferMessage(msg); 2193 break; 2194 } 2195 2196 case kWhatFlush: 2197 { 2198 // We're already doing this right now. 2199 handled = true; 2200 break; 2201 } 2202 2203 default: 2204 handled = BaseState::onMessageReceived(msg); 2205 break; 2206 } 2207 2208 return handled; 2209} 2210 2211bool ACodec::FlushingState::onOMXEvent( 2212 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2213 switch (event) { 2214 case OMX_EventCmdComplete: 2215 { 2216 CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush); 2217 2218 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 2219 CHECK(!mFlushComplete[data2]); 2220 mFlushComplete[data2] = true; 2221 } else { 2222 CHECK_EQ(data2, OMX_ALL); 2223 CHECK(mFlushComplete[kPortIndexInput]); 2224 CHECK(mFlushComplete[kPortIndexOutput]); 2225 2226 changeStateIfWeOwnAllBuffers(); 2227 } 2228 2229 return true; 2230 } 2231 2232 case OMX_EventPortSettingsChanged: 2233 { 2234 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id()); 2235 msg->setInt32("type", omx_message::EVENT); 2236 msg->setPointer("node", mCodec->mNode); 2237 msg->setInt32("event", event); 2238 msg->setInt32("data1", data1); 2239 msg->setInt32("data2", data2); 2240 2241 LOGV("[%s] Deferring OMX_EventPortSettingsChanged", 2242 mCodec->mComponentName.c_str()); 2243 2244 mCodec->deferMessage(msg); 2245 2246 return true; 2247 } 2248 2249 default: 2250 return BaseState::onOMXEvent(event, data1, data2); 2251 } 2252 2253 return true; 2254} 2255 2256void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 2257 BaseState::onOutputBufferDrained(msg); 2258 2259 changeStateIfWeOwnAllBuffers(); 2260} 2261 2262void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 2263 BaseState::onInputBufferFilled(msg); 2264 2265 changeStateIfWeOwnAllBuffers(); 2266} 2267 2268void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 2269 if (mFlushComplete[kPortIndexInput] 2270 && mFlushComplete[kPortIndexOutput] 2271 && mCodec->allYourBuffersAreBelongToUs()) { 2272 sp<AMessage> notify = mCodec->mNotify->dup(); 2273 notify->setInt32("what", ACodec::kWhatFlushCompleted); 2274 notify->post(); 2275 2276 mCodec->mPortEOS[kPortIndexInput] = 2277 mCodec->mPortEOS[kPortIndexOutput] = false; 2278 2279 mCodec->changeState(mCodec->mExecutingState); 2280 } 2281} 2282 2283} // namespace android 2284 2285