Android13 MediaPlayerService setDataSource流程分析

调用MediaPlayer的setDataSource方法后,经过一系列处理,最终后调用MediaPlayerService的setDataSource方法,MediaPlayerService的setDataSource有多个重载方法,具体如下:

//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
        const sp<IMediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers)
{
    ALOGV("setDataSource(%s)", url);
    if (url == NULL)
        return UNKNOWN_ERROR;


    if ((strncmp(url, "http://", 7) == 0) ||
        (strncmp(url, "https://", 8) == 0) ||
        (strncmp(url, "rtsp://", 7) == 0)) {
        if (!checkPermission("android.permission.INTERNET")) {
            return PERMISSION_DENIED;
        }
    }


    if (strncmp(url, "content://", 10) == 0) {
        // get a filedescriptor for the content Uri and
        // pass it to the setDataSource(fd) method


        String16 url16(url);
        int fd = android::openContentProviderFile(url16);
        if (fd < 0)
        {
            ALOGE("Couldn't open fd for %s", url);
            return UNKNOWN_ERROR;
        }
        status_t status = setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus 调用setDataSource重载方法
        close(fd);
        return mStatus = status;
    } else {
        player_type playerType = MediaPlayerFactory::getPlayerType(this, url); //调用MediaPlayerFactory的getPlayerType,获取playerType 
        sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
        if (p == NULL) {
            return NO_INIT;
        }


        return mStatus =
                setDataSource_post(
                p, p->setDataSource(httpService, url, headers)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
    }
}
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
{
    ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld",
            fd, nameForFd(fd).c_str(), (long long) offset, (long long) 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", static_cast<unsigned long long>(sb.st_dev));
    ALOGV("st_mode = %u", sb.st_mode);
    ALOGV("st_uid  = %lu", static_cast<unsigned long>(sb.st_uid));
    ALOGV("st_gid  = %lu", static_cast<unsigned long>(sb.st_gid));
    ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size));


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


    player_type playerType = MediaPlayerFactory::getPlayerType(this,
                                                               fd,
                                                               offset,
                                                               length); //调用MediaPlayerFactory的getPlayerType,获取playerType 
    sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
    if (p == NULL) {
        return NO_INIT;
    }


    // now set data source
    return mStatus = setDataSource_post(p, p->setDataSource(fd, offset, length)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
        const sp<IStreamSource> &source) {
    // create the right type of player
    player_type playerType = MediaPlayerFactory::getPlayerType(this, source); //调用MediaPlayerFactory的getPlayerType,获取playerType
    sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
    if (p == NULL) {
        return NO_INIT;
    }


    // now set data source
    return mStatus = setDataSource_post(p, p->setDataSource(source)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
        const sp<IDataSource> &source) {
    sp<DataSource> dataSource = CreateDataSourceFromIDataSource(source); 
    player_type playerType = MediaPlayerFactory::getPlayerType(this, dataSource); //调用MediaPlayerFactory的getPlayerType,获取playerType
    sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
    if (p == NULL) {
        return NO_INIT;
    }
    // now set data source
    return mStatus = setDataSource_post(p, p->setDataSource(dataSource)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
        const String8& rtpParams) {
    player_type playerType = NU_PLAYER;
    sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
    if (p == NULL) {
        return NO_INIT;
    }
    // now set data source
    return mStatus = setDataSource_post(p, p->setDataSource(rtpParams)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}

上面方法主要处理如下:

调用MediaPlayerFactory的getPlayerType,获取playerType。

调用setDataSource_pre方法。

调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法。

下面我们分别进行分析:

MediaPlayerFactory::getPlayerType

MediaPlayerFactory的getPlayerType有许多重载方法:

//frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp
player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
                                              const char* url) {
    GET_PLAYER_TYPE_IMPL(client, url); 
}


player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
                                              int fd,
                                              int64_t offset,
                                              int64_t length) {
    GET_PLAYER_TYPE_IMPL(client, fd, offset, length);
}


player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
                                              const sp<IStreamSource> &source) {
    GET_PLAYER_TYPE_IMPL(client, source);
}


player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
                                              const sp<DataSource> &source) {
    GET_PLAYER_TYPE_IMPL(client, source);
}

GET_PLAYER_TYPE_IMPL是一个宏,定义如下:

#define GET_PLAYER_TYPE_IMPL(a...)                      \
    Mutex::Autolock lock_(&sLock);                      \
                                                        \
    player_type ret = STAGEFRIGHT_PLAYER;               \
    float bestScore = 0.0;                              \
                                                        \
    for (size_t i = 0; i < sFactoryMap.size(); ++i) {   \
                                                        \
        IFactory* v = sFactoryMap.valueAt(i);           \
        float thisScore;                                \
        CHECK(v != NULL);                               \
        thisScore = v->scoreFactory(a, bestScore);      \
        if (thisScore > bestScore) {                    \
            ret = sFactoryMap.keyAt(i);                 \
            bestScore = thisScore;                      \
        }                                               \
    }                                                   \
                                                        \
    if (0.0 == bestScore) {                             \
        ret = getDefaultPlayerType();                   \
    }                                                   \
                                                        \
    return ret;

MediaPlayerService::Client::setDataSource_pre

我们继续分析MediaPlayerService的setDataSource_pre方法:

        std::vector<DeathNotifier> mDeathNotifiers;
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
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); //调用createPlayer方法
    if (p == NULL) {
        return p;
    }


    std::vector<DeathNotifier> deathNotifiers;


    // Listen to death of media.extractor service
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder = sm->getService(String16("media.extractor"));
    if (binder == NULL) {
        ALOGE("extractor service not available");
        return NULL;
    }
    deathNotifiers.emplace_back(
            binder, [l = wp<MediaPlayerBase>(p)]() {
        sp<MediaPlayerBase> listener = l.promote();
        if (listener) {
            ALOGI("media.extractor died. Sending death notification.");
            listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
                                MEDIAEXTRACTOR_PROCESS_DEATH);
        } else {
            ALOGW("media.extractor died without a death handler.");
        }
    });


    {
        using ::android::hidl::base::V1_0::IBase;


        // Listen to death of OMX service
        {
            sp<IBase> base = ::android::hardware::media::omx::V1_0::
                    IOmx::getService(); //获取IOmx
            if (base == nullptr) {
                ALOGD("OMX service is not available");
            } else {
                deathNotifiers.emplace_back(
                        base, [l = wp<MediaPlayerBase>(p)]() {
                    sp<MediaPlayerBase> listener = l.promote();
                    if (listener) {
                        ALOGI("OMX service died. "
                              "Sending death notification.");
                        listener->sendEvent(
                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
                                MEDIACODEC_PROCESS_DEATH);
                    } else {
                        ALOGW("OMX service died without a death handler.");
                    }
                });
            }
        }


        // Listen to death of Codec2 services
        {
            for (std::shared_ptr<Codec2Client> const& client :
                    Codec2Client::CreateFromAllServices()) {
                sp<IBase> base = client->getBase();
                deathNotifiers.emplace_back(
                        base, [l = wp<MediaPlayerBase>(p),
                               name = std::string(client->getServiceName())]() {
                    sp<MediaPlayerBase> listener = l.promote();
                    if (listener) {
                        ALOGI("Codec2 service \"%s\" died. "
                              "Sending death notification.",
                              name.c_str());
                        listener->sendEvent(
                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
                                MEDIACODEC_PROCESS_DEATH);
                    } else {
                        ALOGW("Codec2 service \"%s\" died "
                              "without a death handler.",
                              name.c_str());
                    }
                });
            }
        }
    }


    Mutex::Autolock lock(mLock);


    mDeathNotifiers.clear();
    mDeathNotifiers.swap(deathNotifiers);
    mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p); //创建AudioDeviceUpdatedNotifier对象


    if (!p->hardwareOutput()) {
        mAudioOutput = new AudioOutput(mAudioSessionId, mAttributionSource,
                mAudioAttributes, mAudioDeviceUpdatedListener); //创建AudioOutput对象
        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); //调用MediaPlayerInterface的setAudioSink方法
    }


    return p;
}

NuPlayerDriver::setDataSource

MediaPlayerBase是一个抽象类,MediaPlayerBase和MediaPlayerHWInterface接口继承于MediaPlayerBase,而NuPlayerDriver又继承于MediaPlayerInterface:

class MediaPlayerInterface : public MediaPlayerBase {}
class MediaPlayerHWInterface : public MediaPlayerBase {}
struct NuPlayerDriver : public MediaPlayerInterface {}

因此调用MediaPlayerBase的setDataSource方法,就会调用到NuPlayerDriver的setDataSource方法,NuPlayerDriver的setDataSource有多个重载方法,具体如下:

const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(
        const sp<IMediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers) {
    ALOGV("setDataSource(%p) url(%s)", this, uriDebugString(url, false).c_str());
    Mutex::Autolock autoLock(mLock);


    if (mState != STATE_IDLE) {
        return INVALID_OPERATION;
    }


    mState = STATE_SET_DATASOURCE_PENDING;


    mPlayer->setDataSourceAsync(httpService, url, headers);


    while (mState == STATE_SET_DATASOURCE_PENDING) {
        mCondition.wait(mLock);
    }


    return mAsyncResult;
}
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) {
    ALOGV("setDataSource(%p) file(%d)", this, fd);
    Mutex::Autolock autoLock(mLock);


    if (mState != STATE_IDLE) {
        return INVALID_OPERATION;
    }


    mState = STATE_SET_DATASOURCE_PENDING;


    mPlayer->setDataSourceAsync(fd, offset, length);


    while (mState == STATE_SET_DATASOURCE_PENDING) {
        mCondition.wait(mLock);
    }


    return mAsyncResult;
}
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
    ALOGV("setDataSource(%p) stream source", this);
    Mutex::Autolock autoLock(mLock);


    if (mState != STATE_IDLE) {
        return INVALID_OPERATION;
    }


    mState = STATE_SET_DATASOURCE_PENDING;


    mPlayer->setDataSourceAsync(source);


    while (mState == STATE_SET_DATASOURCE_PENDING) {
        mCondition.wait(mLock);
    }


    return mAsyncResult;
}
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(const sp<DataSource> &source) {
    ALOGV("setDataSource(%p) callback source", this);
    Mutex::Autolock autoLock(mLock);


    if (mState != STATE_IDLE) {
        return INVALID_OPERATION;
    }


    mState = STATE_SET_DATASOURCE_PENDING;


    mPlayer->setDataSourceAsync(source);


    while (mState == STATE_SET_DATASOURCE_PENDING) {
        mCondition.wait(mLock);
    }


    return mAsyncResult;
}
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(const String8& rtpParams) {
    ALOGV("setDataSource(%p) rtp source", this);
    Mutex::Autolock autoLock(mLock);


    if (mState != STATE_IDLE) {
        return INVALID_OPERATION;
    }


    mState = STATE_SET_DATASOURCE_PENDING;


    mPlayer->setDataSourceAsync(rtpParams);


    while (mState == STATE_SET_DATASOURCE_PENDING) {
        mCondition.wait(mLock);
    }


    return mAsyncResult;
}

调用NuPlayer的setDataSourceAsync方法,NuPlayer相关内容我们在NuPlayer中继续分析:

Android13 NuPlayer::setDataSourceAsync流程分析-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值