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。