一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Android多媒體開(kāi)辟筆記【4】-- 上層mediaPlayer 是如何調(diào)到Stagefright的【2】【圖解】

 kkq292 2014-05-31

Android多媒體開(kāi)辟筆記【4】-- 上層mediaPlayer 是如何調(diào)到Stagefright的【2】【圖解】
2012-10-04


了解與友情的關(guān)系好似調(diào)情之于愛(ài)情——高興,但卻又不滿足。基于android 4.1.1 源碼

科學(xué)家必須在錯(cuò)雜的經(jīng)驗(yàn)事實(shí)中抓住某些可用緊密公式來(lái)默示的廣泛特點(diǎn),由此尋找天然界的廣泛道理。

【1】mediaserver 啟動(dòng)后會(huì)把media相干一些辦事添加到servicemanager中,此中就有mediaPlayerService.如許應(yīng)用啟動(dòng)前,體系就有了mediaPlayerService這個(gè)辦事法度。   

int main(int argc, char** argv)
{
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    AudioFlinger::instantiate();
    MediaPlayerService::instantiate();
    CameraService::instantiate();
    AudioPolicyService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}
void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

【2】應(yīng)用層 mediaPlayer=new MediaPlayer();  調(diào)用SDK中 MediaPlayer.java (frameworksasemediajavaandroidmediaMediaPlayer.java

  public MediaPlayer() {

        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }

        /* Native setup requires a weak reference to our object.
         * It""s easier to create it here than in C++.
         */
        native_setup(new WeakReference<MediaPlayer>(this));
    }

經(jīng)由過(guò)程JNI體式格式調(diào)用到framework層 android_media_MediaPlayer.cpp(frameworksasemediajniandroid_media_MediaPlayer.cpp)

static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
    ALOGV("native_setup");
    sp<MediaPlayer> mp = new MediaPlayer();
    if (mp == NULL) {
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        return;
    }

    // create new listener and give it to MediaPlayer
    sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
    mp->setListener(listener);

    // Stow our new C++ MediaPlayer in an opaque field in the Java object.
    setMediaPlayer(env, thiz, mp);
}

繼而調(diào)用mediaplayer.cpp(frameworksavmedialibmediamediaplayer.cpp)

【3】在全部應(yīng)用法度的過(guò)程中,mediaplayer.cpp 中 setDataSource會(huì)從service manager中獲得mediaPlayerService 辦事,然后經(jīng)由過(guò)程辦事來(lái)創(chuàng)建player。這個(gè)player就是播放器的真實(shí)實(shí)例。

status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source)
{
    ALOGV("setDataSource");
    status_t err = UNKNOWN_ERROR;
    const sp<IMediaPlayerService>& service(getMediaPlayerService());
    if (service != 0) {
        sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
            (NO_ERROR != player->setDataSource(source))) {
            player.clear();
        }
        err = attachNewPlayer(player);
    }
    return err;
}
【4】經(jīng)由過(guò)程 getMediaPlayerService 獲得的service其實(shí)是 BpMediaPlayerService,這是和mediaPlayerService過(guò)程中的BnMediaPlayerService 相對(duì)應(yīng)負(fù)責(zé)binder通信。BpMediaPlayerService中的create其實(shí)經(jīng)由過(guò)程binder機(jī)制將CREATE消息發(fā)送出去。

 virtual sp<IMediaPlayer> create(
            pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId) {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        data.writeInt32(pid);
        data.writeStrongBinder(client->asBinder());
        data.writeInt32(audioSessionId);

        remote()->transact(CREATE, data, &reply);
        return interface_cast<IMediaPlayer>(reply.readStrongBinder());
    }

在對(duì)面的BnMediaPlayerService中,經(jīng)由過(guò)程onTransact()來(lái)接管這些消息。并把成果返回。

status_t BnMediaPlayerService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {
        case CREATE: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            pid_t pid = data.readInt32();
            sp<IMediaPlayerClient> client =
                interface_cast<IMediaPlayerClient>(data.readStrongBinder());
            int audioSessionId = data.readInt32();
            sp<IMediaPlayer> player = create(pid, client, audioSessionId);
            reply->writeStrongBinder(player->asBinder());
            return NO_ERROR;
        } break;
        case DECODE_URL: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            const char* url = data.readCString();
            uint32_t sampleRate;
            int numChannels;
            audio_format_t format;
            sp<IMemory> player = decode(url, &sampleRate, &numChannels, &format);
            reply->writeInt32(sampleRate);
            reply->writeInt32(numChannels);
            reply->writeInt32((int32_t) format);
            reply->writeStrongBinder(player->asBinder());
            return NO_ERROR;
        } break;
        case DECODE_FD: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            int fd = dup(data.readFileDescriptor());
            int64_t offset = data.readInt64();
            int64_t length = data.readInt64();
            uint32_t sampleRate;
            int numChannels;
            audio_format_t format;
            sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels, &format);
            reply->writeInt32(sampleRate);
            reply->writeInt32(numChannels);
            reply->writeInt32((int32_t) format);
            reply->writeStrongBinder(player->asBinder());
            return NO_ERROR;
        } break;
        case CREATE_MEDIA_RECORDER: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            pid_t pid = data.readInt32();
            sp<IMediaRecorder> recorder = createMediaRecorder(pid);
            reply->writeStrongBinder(recorder->asBinder());
            return NO_ERROR;
        } break;
        case CREATE_METADATA_RETRIEVER: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            pid_t pid = data.readInt32();
            sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(pid);
            reply->writeStrongBinder(retriever->asBinder());
            return NO_ERROR;
        } break;
        case GET_OMX: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<IOMX> omx = getOMX();
            reply->writeStrongBinder(omx->asBinder());
            return NO_ERROR;
        } break;
        case MAKE_CRYPTO: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<ICrypto> crypto = makeCrypto();
            reply->writeStrongBinder(crypto->asBinder());
            return NO_ERROR;
        } break;
        case ADD_BATTERY_DATA: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            uint32_t params = data.readInt32();
            addBatteryData(params);
            return NO_ERROR;
        } break;
        case PULL_BATTERY_DATA: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            pullBatteryData(reply);
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}
當(dāng)發(fā)明是CREATE才真正調(diào)用了MediaPlayerService 中的create函數(shù)。在create函數(shù)中其實(shí)是創(chuàng)建了一個(gè)MediaPlayerService::Client的實(shí)例,也就是 說(shuō)MediaPlayerService會(huì)為每個(gè)client應(yīng)用過(guò)程創(chuàng)建一個(gè)響應(yīng)的MediaPlayerService::Client的實(shí)例,來(lái)供給辦事。

sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
        int audioSessionId)
{
    int32_t connId = android_atomic_inc(&mNextConnId);

    sp<Client> c = new Client(
            this, pid, connId, client, audioSessionId,
            IPCThreadState::self()->getCallingUid());

    ALOGV("Create new client(%d)  pid %d, uid %d, ", connId, pid,
         IPCThreadState::self()->getCallingUid());

    wp<Client> w = c;
    {
        Mutex::Autolock lock(mLock);
        mClients.add(w);
    }
    return c;
}

【5】如許mediaplayer.cpp就獲得了一個(gè)player的實(shí)例,對(duì)他來(lái)說(shuō)這個(gè)實(shí)例和本地的其他類的實(shí)例沒(méi)什么用法上的差別,殊不知其實(shí)這個(gè)實(shí)例是運(yùn)行在別的一個(gè)過(guò)程中。實(shí)現(xiàn)這種假象的就是binder機(jī)制。獲得這個(gè)實(shí)例后持續(xù)player->setDataSource().在MediaPlayerService的過(guò)程中他的實(shí)際函數(shù)中,才會(huì)真正的創(chuàng)建Stagefright的具體實(shí)例。
status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
{
    ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
    struct stat sb;
    int ret = fstat(fd, &sb);
    if (ret != 0) {
        ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
        return UNKNOWN_ERROR;
    }

    ALOGV("st_dev  = %llu", sb.st_dev);
    ALOGV("st_mode = %u", sb.st_mode);
    ALOGV("st_uid  = %lu", sb.st_uid);
    ALOGV("st_gid  = %lu", sb.st_gid);
    ALOGV("st_size = %llu", sb.st_size);

    if (offset >= sb.st_size) {
        ALOGE("offset error");
        ::close(fd);
        return UNKNOWN_ERROR;
    }
    if (offset + length > sb.st_size) {
        length = sb.st_size - offset;
        ALOGV("calculated length = %lld", length);
    }

    // Until re-transmit functionality is added to the existing core android
    // players, we use the special AAH TX player whenever we were configured for
    // retransmission.
    player_type playerType = getPlayerType(fd, offset, length);
    sp<MediaPlayerBase> p = setDataSource_pre(playerType);
    if (p == NULL) {
        return NO_INIT;
    }

    // now set data source
    setDataSource_post(p, p->setDataSource(fd, offset, length));
    return mStatus;
}
sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
        player_type playerType)
{
    ALOGV("player type = %d", playerType);

    // create the right type of player
    sp<MediaPlayerBase> p = createPlayer(playerType);
    if (p == NULL) {
        return p;
    }

    if (!p->hardwareOutput()) {
        mAudioOutput = new AudioOutput(mAudioSessionId);
        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
    }

    return p;
}
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
    // determine if we have the right player type
    sp<MediaPlayerBase> p = mPlayer;
    if ((p != NULL) && (p->playerType() != playerType)) {
        ALOGV(" player");
        p.clear();
    }
    if (p == NULL) {
        p = android::createPlayer(playerType, this, notify);
    }

    if (p != NULL) {
        p->setUID(mUID);
    }

    return p;
}
static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
        notify_callback_f notifyFunc)
{
    sp<MediaPlayerBase> p;
    switch (playerType) {
        case SONIVOX_PLAYER:
            ALOGV(" create MidiFile");
            p = new MidiFile();
            break;
        case STAGEFRIGHT_PLAYER:
            ALOGV(" create StagefrightPlayer");
            p = new StagefrightPlayer;
            break;
        case NU_PLAYER:
            ALOGV(" create NuPlayer");
            p = new NuPlayerDriver;
            break;
        case TEST_PLAYER:
            ALOGV("Create Test Player stub");
            p = new TestPlayerStub();
            break;
        case AAH_RX_PLAYER:
            ALOGV(" create A@H RX Player");
            p = createAAH_RXPlayer();
            break;
        case AAH_TX_PLAYER:
            ALOGV(" create A@H TX Player");
            p = createAAH_TXPlayer();
            break;
        default:
            ALOGE("Unknown player type: %d", playerType);
            return NULL;
    }
    if (p != NULL) {
        if (p->initCheck() == NO_ERROR) {
            p->setNotifyCallback(cookie, notifyFunc);
        } else {
            p.clear();
        }
    }
    if (p == NULL) {
        ALOGE("Failed to create player object");
    }
    return p;
}

在上方中已經(jīng)看不到opencore的影子了,creaPlayer 中會(huì)按照類型來(lái)創(chuàng)建播放器的實(shí)例。Stagefright的實(shí)例就是在這里創(chuàng)建的。

下一步我們能真正進(jìn)入到Stagefright里了

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    欧美丝袜诱惑一区二区| 国产精品久久精品国产| 国产欧洲亚洲日产一区二区| 国内胖女人做爰视频有没有| 两性色午夜天堂免费视频| 日韩一区中文免费视频| 91插插插外国一区二区| 欧美精品亚洲精品一区| 国产亚洲不卡一区二区| 粉嫩内射av一区二区| 亚洲天堂男人在线观看| 91麻豆精品欧美视频| 午夜传媒视频免费在线观看| 日韩精品一区二区三区射精| 成年女人下边潮喷毛片免费| 色无极东京热男人的天堂| 狠狠做五月深爱婷婷综合| 日本男人女人干逼视频| 九九热精彩视频在线播放| 国产日韩久久精品一区| 欧美日韩亚洲精品内裤| 亚洲欧美天堂精品在线| 色偷偷偷拍视频在线观看| 九九久久精品久久久精品| 久久精品亚洲精品一区| 国产香蕉国产精品偷在线观看| 国产精品免费视频视频| 亚洲五月婷婷中文字幕| 高跟丝袜av在线一区二区三区| 日本在线不卡高清欧美| 日韩一区二区免费在线观看 | 99精品国产一区二区青青 | 亚洲一区二区三区四区| 成人午夜视频精品一区| 国语对白刺激高潮在线视频| 99热九九热这里只有精品| 91天堂素人精品系列全集| 老司机精品线观看86| 日韩美成人免费在线视频| 亚洲精品黄色片中文字幕| 国产亚洲不卡一区二区|