Android_ics openmax in stagefright学習記録------1
これらの文章はopenmaxの出力を前に学び、ここに記録し、菜鳥を誤導しないで牛たちの指導を受けてほしい.
紙幅を節約してもう1編再開する
android_ics openmax_in_stagefright
/*
* android , C/S
* , ,
* , , 。
*/
<--- , ,stagefright ,OpenMaXIL --->
At first:
OpenMax , android 。
, 。
/////////////////////////////////////////////
//1,OMX ?
////////////////////////////////////////////
awesomeplayer
AwesomePlayer::AwesomePlayer()
: mQueueStarted(false),
...
mTextPlayer(NULL) {
/*mClient OMXClient */
CHECK_EQ(mClient.connect(), (status_t)OK);
DataSource::RegisterDefaultSniffers();
mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);
...
mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate);
mVideoEventPending = false;
mCheckAudioStatusEvent = new AwesomeEvent(
this, &AwesomePlayer::onCheckAudioStatus);
...
}
/*connect */
status_t OMXClient::connect() {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
CHECK(service.get() != NULL);
mOMX = service->getOMX();
CHECK(mOMX.get() != NULL);
return OK;
}
, binder MediaPlayerService getOmx OMX , awesomePlayer
mOMX 。 Client->Service 。 OpenMax 。
/*OMX ,@OMX.cpp*/
OMX::OMX():mMaster(new OMXMaster),mNodeCounter(0) {
}
------------------------- , --------------------------------------------------------->
/* OMX , , , */
class OMX : public BnOMX,
public IBinder::DeathRecipient {
public:
OMX();
virtual bool livesLocally(pid_t pid);
virtual status_t listNodes(List<ComponentInfo> *list);
virtual status_t allocateNode(
const char *name, const sp<IOMXObserver> &observer, node_id *node);
virtual status_t freeNode(node_id node);
virtual status_t sendCommand(
node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param);
virtual status_t getParameter(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size);
virtual status_t setParameter(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size);
virtual status_t getConfig(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size);
virtual status_t setConfig(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size);
virtual status_t getState(
node_id node, OMX_STATETYPE* state);
virtual status_t enableGraphicBuffers(
node_id node, OMX_U32 port_index, OMX_BOOL enable);
virtual status_t getGraphicBufferUsage(
node_id node, OMX_U32 port_index, OMX_U32* usage);
virtual status_t storeMetaDataInBuffers(
node_id node, OMX_U32 port_index, OMX_BOOL enable);
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
buffer_id *buffer);
virtual status_t useGraphicBuffer(
node_id node, OMX_U32 port_index,
const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer);
virtual status_t allocateBuffer(
node_id node, OMX_U32 port_index, size_t size,
buffer_id *buffer, void **buffer_data);
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
buffer_id *buffer);
virtual status_t freeBuffer(
node_id node, OMX_U32 port_index, buffer_id buffer);
virtual status_t fillBuffer(node_id node, buffer_id buffer);
virtual status_t emptyBuffer(
node_id node,
buffer_id buffer,
OMX_U32 range_offset, OMX_U32 range_length,
OMX_U32 flags, OMX_TICKS timestamp);
virtual status_t getExtensionIndex(
node_id node,
const char *parameter_name,
OMX_INDEXTYPE *index);
virtual void binderDied(const wp<IBinder> &the_late_who);
OMX_ERRORTYPE OnEvent(
node_id node,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData);
OMX_ERRORTYPE OnEmptyBufferDone(
node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
OMX_ERRORTYPE OnFillBufferDone(
node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
void invalidateNodeID(node_id node);
protected:
virtual ~OMX();
private:
struct CallbackDispatcherThread; //
struct CallbackDispatcher; //
Mutex mLock;
OMXMaster *mMaster;
int32_t mNodeCounter;
KeyedVector<wp<IBinder>, OMXNodeInstance *> mLiveNodes;
KeyedVector<node_id, OMXNodeInstance *> mNodeIDToInstance;
KeyedVector<node_id, sp<CallbackDispatcher> > mDispatchers;
node_id makeNodeID(OMXNodeInstance *instance);
OMXNodeInstance *findInstance(node_id node);
sp<CallbackDispatcher> findDispatcher(node_id node);
void invalidateNodeID_l(node_id node);
OMX(const OMX &);
OMX &operator=(const OMX &);
};
} // namespace android
#endif // ANDROID_OMX_H_
<------------------------- , ---------------------------------------------------------
, OMX , new OMXMaster mMaster, mMaster OMXPluginBase( )
, ICS 。
#ifndef OMX_MASTER_H_
#define OMX_MASTER_H_
#include <media/stagefright/OMXPluginBase.h>
#include <utils/threads.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
#include <utils/String8.h>
namespace android {
struct OMXMaster : public OMXPluginBase {
OMXMaster();
virtual ~OMXMaster();
virtual OMX_ERRORTYPE makeComponentInstance( // OpenMAX
const char *name,
const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData,
OMX_COMPONENTTYPE **component);
virtual OMX_ERRORTYPE destroyComponentInstance( // OpenMAX
OMX_COMPONENTTYPE *component);
virtual OMX_ERRORTYPE enumerateComponents( // OpenMAX
OMX_STRING name,
size_t size,
OMX_U32 index);
virtual OMX_ERRORTYPE getRolesOfComponent( // OpenMAX
const char *name,
Vector<String8> *roles);
private:
Mutex mLock;
List<OMXPluginBase *> mPlugins;
KeyedVector<String8, OMXPluginBase *> mPluginByComponentName;
KeyedVector<OMX_COMPONENTTYPE *, OMXPluginBase *> mPluginByInstance;
void *mVendorLibHandle;
void addVendorPlugin();
void addPlugin(const char *libname);
void addPlugin(OMXPluginBase *plugin);
void clearPlugins();
OMXMaster(const OMXMaster &);
OMXMaster &operator=(const OMXMaster &);
};
} // namespace android
#endif // OMX_MASTER_H_
----- ,android2.3 ICS -----
OMXMaster , 。
////2.3////
OMXMaster::OMXMaster()
: mVendorLibHandle(NULL) {
addVendorPlugin();
#ifndef NO_OPENCORE
addPlugin(new OMXPVCodecsPlugin);
#endif
}
2.3 , OMX addVendorPlugin(), , ,
,2.3 XXXDecoder
////4.0////
OMXMaster::OMXMaster()
: mVendorLibHandle(NULL) {
addVendorPlugin();
addPlugin(new SoftOMXPlugin);
}
4.0 , OMX , plugins 。 addPlugin(new SoftOMXPlugin)。
/////////////////////////////////////////////
//2, OMXCodecObserver
/////////////////////////////////////////////
OMXCodecObserver OMXCodec , OMXCodec Create , observer->setCodec(codec)
, OMXCodec 。OMXCodecObserver onMessage, observer codec ,
OMXCodecObserver onMessage , , observer codec 。
/////////////////////////////////////////////
//3, OMXCodec create
/////////////////////////////////////////////
sp<MediaSource> OMXCodec::Create(
const sp<IOMX> &omx,
const sp<MetaData> &meta, bool createEncoder,
const sp<MediaSource> &source,
const char *matchComponentName,
uint32_t flags,
const sp<ANativeWindow> &nativeWindow) {
int32_t requiresSecureBuffers;
if (source->getFormat()->findInt32(
kKeyRequiresSecureBuffers,
&requiresSecureBuffers)
&& requiresSecureBuffers) {
flags |= kIgnoreCodecSpecificData;
flags |= kUseSecureInputBuffers;
flags |= kEnableGrallocUsageProtected;
}
else
{
flags &= ~kEnableGrallocUsageProtected;
}
const char *mime;
bool success = meta->findCString(kKeyMIMEType, &mime);
CHECK(success);
Vector<String8> matchingCodecs;
findMatchingCodecs(
mime, createEncoder, matchComponentName, flags, &matchingCodecs);
if (matchingCodecs.isEmpty()) {
return NULL;
}
sp<OMXCodecObserver> observer = new OMXCodecObserver;
IOMX::node_id node = 0;
for (size_t i = 0; i < matchingCodecs.size(); ++i) {
const char *componentNameBase = matchingCodecs[i].string();
const char *componentName = componentNameBase;
AString tmp;
if (flags & kUseSecureInputBuffers) {
tmp = componentNameBase;
tmp.append(".secure");
componentName = tmp.c_str();
}
...
status_t err = omx->allocateNode(componentName, observer, &node);
...
sp<OMXCodec> codec = new OMXCodec(
omx, node, quirks, flags,
createEncoder, mime, componentName,
source, nativeWindow);
observer->setCodec(codec);
err = codec->configureCodec(meta);
if (err == OK) {
if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) {
codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime;
}
return codec;
...
return NULL;
}
OMXCodec::Create , Create :
// , mime , , ComponentName matchingCodecs 。 , matchComponentName。
1,findMatchingCodecs(mime, createEncoder, matchComponentName, flags, &matchingCodecs);
// OMXCodecObserver, , node node_id,id 0
2,sp<OMXCodecObserver> observer = new OMXCodecObserver;
IOMX::node_id node = 0;
//allocateNode binder OMX::allocateNode,
3,status_t err = omx->allocateNode(componentName, observer, &node);
status_t OMX::allocateNode(
const char *name, const sp<IOMXObserver> &observer, node_id *node) {
Mutex::Autolock autoLock(mLock);
*node = 0;
//OMXNodeInstance, node_id , OMX node , OMXNodeInstance , 。
OMXNodeInstance *instance = new OMXNodeInstance(this, observer);
OMX_COMPONENTTYPE *handle;
// OMXPlugins makeComponentInstance , OMX plugin SoftOMXPlugin,
//SoftOMXPlugin makeComponentInstance llibstagefright_soft_XXX.so
// ddlopen dlsym so 。 , , SoftMPEG4,
// , initPorts(),initDecoder()......
OMX_ERRORTYPE err = mMaster->makeComponentInstance(
name, &OMXNodeInstance::kCallbacks,
instance, &handle);
if (err != OMX_ErrorNone) {
LOGV("FAILED to allocate omx component '%s'", name);
instance->onGetHandleFailed();
return UNKNOWN_ERROR;
}
*node = makeNodeID(instance);
// node_id node, node CallbackDispatcher , CallbackDispatcher
// OMXNodeInstance instance 。CallbackDispatcher , , List<omx_message> mQueue;
// omx_message 。 dispatch(msg)。
mDispatchers.add(*node, new CallbackDispatcher(instance));
// OMXNodeInstance node_id, handler, handler mMaster->makeComponentInstance 。
instance->setHandle(*node, handle);
mLiveNodes.add(observer->asBinder(), instance);
observer->asBinder()->linkToDeath(this);
return OK;
}
// OOMXCodec
4,sp<OMXCodec> codec = new OMXCodec(
omx, node, quirks, flags,
createEncoder, mime, componentName,
source, nativeWindow);
// codec observer
observer->setCodec(codec);
// format codec
err = codec->configureCodec(meta);
:
omx stagefright ,
1, awesomeplayer , OMXClient mClient, OMX 。
2,stagefright OMXCodec OMX( OMX )
3, OMX OMXNodeInstance Components 。
4, , CallbackDispatcher , onMessage().
紙幅を節約してもう1編再開する