android (9)
来源:互联网 发布:linux关闭selinux 编辑:程序博客网 时间:2024/04/28 20:37
android (9)
IServiceManager 中定义了addService 这样一个方法
getStrongProxyForHandle 返回的也是一个BpBinder
virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
那么客户是怎么调用服务的?
看看 MediaRecord 这个类
在每个MediaRecorder类中都有这样一个指针
sp<IMediaRecorder> mMediaRecorder;
Recoder的状态有如下几种
enum media_recorder_states {
MEDIA_RECORDER_ERROR = 0,
MEDIA_RECORDER_IDLE = 1 << 0,
MEDIA_RECORDER_INITIALIZED = 1 << 1,
MEDIA_RECORDER_DATASOURCE_CONFIGURED = 1 << 2,
MEDIA_RECORDER_PREPARED = 1 << 3,
MEDIA_RECORDER_RECORDING = 1 << 4,
};
MediaRecorder::setCamera
status_t ret = mMediaRecorder->setCamera(camera);
MediaRecorder::setPreviewSurface
status_t ret = mMediaRecorder->setPreviewSurface(surface->getISurface());
status_t MediaRecorder::init()
status_t ret = mMediaRecorder->init();
ret = mMediaRecorder->setListener(this);
MediaRecorder 就一个包装类
MediaRecorder::MediaRecorder()
{
LOGV("constructor");
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != NULL) {
mMediaRecorder = service->createMediaRecorder(getpid());
}
if (mMediaRecorder != NULL) {
mCurrentState = MEDIA_RECORDER_IDLE;
}
doCleanUp();
}
// establish binder interface to MediaPlayerService
/*static*/const sp<IMediaPlayerService>&
IMediaDeathNotifier::getMediaPlayerService()
{
LOGV("getMediaPlayerService");
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.player"));
if (binder != 0) {
break;
}
LOGW("Media player service not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(sDeathNotifier);
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
LOGE_IF(sMediaPlayerService == 0, "no media player service!?");
return sMediaPlayerService;
}
就是获取了一个binder么
linkToDeath是干嘛的?
binder写了一下,然后放到容器中
status_t BpBinder::linkToDeath(
const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
{
Obituary ob;
ob.recipient = recipient;
ob.cookie = cookie;
ob.flags = flags;
LOG_ALWAYS_FATAL_IF(recipient == NULL,
"linkToDeath(): recipient must be non-NULL");
{
AutoMutex _l(mLock);
if (!mObitsSent) {
if (!mObituaries) {
mObituaries = new Vector<Obituary>;
if (!mObituaries) {
return NO_MEMORY;
}
LOGV("Requesting death notification: %p handle %d\n", this, mHandle);
getWeakRefs()->incWeak(this);
IPCThreadState* self = IPCThreadState::self();
self->requestDeathNotification(mHandle, this);
self->flushCommands();
}
ssize_t res = mObituaries->add(ob);
return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
}
}
return DEAD_OBJECT;
}
代理类封装
VPU 库
vpu_io封装了对 /dev/mxc_vpu的操作
vpu_lib 提供了编解码接口
vpu_util 提供了一些方法
external/linux-lib/vpu 也就是向上层模块提供了一些方法
\frameworks\base\media\libstagefright\codecs 对VPU进行了封装 封装成一个encoder 类
MediaRecorderClient
MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid)
{
LOGV("Client constructor");
mPid = pid;
char value[PROPERTY_VALUE_MAX];
if (!property_get("media.stagefright.enable-record", value, NULL)
|| !strcmp(value, "1") || !strcasecmp(value, "true")) {
mRecorder = new StagefrightRecorder;
} else
#ifndef NO_OPENCORE
{
mRecorder = new PVMediaRecorder();
}
#else
{
mRecorder = NULL;
}
#endif
mMediaPlayerService = service;
}
CallbackDispatcher 类
在构造函数中创建了这样一个线程 ThreadWrapper
// static
void *OMX::CallbackDispatcher::ThreadWrapper(void *me) {
static_cast<CallbackDispatcher *>(me)->threadEntry();
return NULL;
}
调用 threadEntry 方法
void OMX::CallbackDispatcher::threadEntry() {
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
prctl(PR_SET_NAME, (unsigned long)"OMXCallbackDisp", 0, 0, 0);
for (;;) {
omx_message msg;
{
Mutex::Autolock autoLock(mLock);
while (!mDone && mQueue.empty()) {
mQueueChanged.wait(mLock);
}
if (mDone) {
break;
}
msg = *mQueue.begin();
mQueue.erase(mQueue.begin());
}
dispatch(msg);
}
}
本质就是就是一个异步的消息处理线程
有消息就抛
OMX::OMX()
: mMaster(new OMXMaster),
mNodeCounter(0) {
}
一个OMX 就封装了一个OMXMaster
KeyedVector<wp<IBinder>, OMXNodeInstance *> mLiveNodes;
以 IBinder 指针为key OMX节点实例指针为value
ssize_t index = mLiveNodes.indexOfKey(the_late_who);
CHECK(index >= 0);
通过key 找到index
KeyedVector<node_id, sp<CallbackDispatcher> > mDispatchers;
以节点为key
OMXNodeInstance *instance;
{
Mutex::Autolock autoLock(mLock);
ssize_t index = mLiveNodes.indexOfKey(the_late_who);
CHECK(index >= 0);
instance = mLiveNodes.editValueAt(index);
mLiveNodes.removeItemsAt(index);
index = mDispatchers.indexOfKey(instance->nodeID());
CHECK(index >= 0);
mDispatchers.removeItemsAt(index);
invalidateNodeID_l(instance->nodeID());
}
instance->onObserverDied(mMaster);
}
binderDied 是发现binder 死亡后 从2个容器中删除
status_t OMX::listNodes(List<ComponentInfo> *list)
将所有组件的名字和角色都list出来
OMX的主要任务
1 NodeInstance 列表的管理
2 针对NodeInstance的操作和事件管理
一、NodeInstance列表的管理。
这个主要包括NodeInstance的生成(allocateNode)和删除(freeNode)。其实就是对mDispatchers和 mNodeIDToInstance进行添加和删除。
mNodeIDToInstance就是一个key为node_id,value为 NodeInstance的名值对列表。而mDispatchers就是一个key为node_id,value为
OMX::CallbackDispatcher的名值对列表。并且,一个NodeInstance都拥有一个 OMX::CallbackDispatcher。
- android (9)
- Android .9
- 【Android】android中9 path图片
- Android学习历程9-Android事件处理
- Android学习笔记9
- Android开发9:Activity
- Android培训班(9)
- Android 9 patch 图片
- android学习笔记9
- android 9 patch
- android 9patch
- 9、Android中Activity
- Android学习笔记9
- android .9png
- Android 9 patch 图片
- Android 9 patch 图片
- android 9patch
- android 9patch制作
- javascript“未结束的字符串常量”的错误
- 发力平板电脑及车载终端 MeeGo向中国寻出路
- 闪回区设置问题
- 如何通过命令行或者使用代码打开一个apk文件
- JS 数字相加
- android (9)
- 斐波那契数列
- 集成电路 RTL 设计
- 如何为外部程序调用时,可传入参数?如何调试?
- http://www.cnblogs.com/zxp_9527/archive/2009/05/07/1452253.html
- atl-ActiveX-dll-inf-cab-web调用(总结篇)
- 巧用搜索语法搜索外文文献
- 最长回文子串
- web高性能开发系列随笔