1.1 当前开机耗时点

开机动画会等render service启动后创建媒体播放器,循环创建播放器耗时长,多次创建播放器。bootanimation调用Play()播放开机动画MP4

    static const int MAX_WAIT_MEDIA_CREATE_TIME = 5000000; // 5S
    static const int SLEEP_TIME_US = 30000; //30ms
    
    void BootVideoPlayer::Play()
    {
    #ifdef PLAYER_FRAMEWORK_ENABLE
        LOGI("PlayVideo begin");
        int waitMediaCreateTime = 0;
        while ((mediaPlayer_ = Media::PlayerFactory::CreatePlayer()) == nullptr
            && waitMediaCreateTime < MAX_WAIT_MEDIA_CREATE_TIME) {
            LOGI("mediaPlayer is nullptr, try create again");
            usleep(SLEEP_TIME_US);sleep30毫秒
            waitMediaCreateTime += SLEEP_TIME_US;
        }耗时花在循环创建媒体播放器。
    
        if (mediaPlayer_ == nullptr) {
            LOGI("mediaPlayer create fail");
            return;
        }
    
        std::shared_ptr<VideoPlayerCallback> cb = std::make_shared<VideoPlayerCallback>(shared_from_this());
        int32_t ret = mediaPlayer_->SetPlayerCallback(cb);
        if (ret != 0) {
            LOGE("PlayVideo SetPlayerCallback fail, errorCode: %{public}d", ret);
            return;
        }
        std::string path = GetResPath(TYPE_VIDEO);
        LOGI("video res path: %{public}s", path.c_str());
        ret = mediaPlayer_->SetSource(path);
        if (ret != 0) {
            LOGE("PlayVideo SetSource fail, errorCode: %{public}d", ret);
            return;
        }
        if (surface_ == nullptr) {
            LOGE("PlayVideo surface is null");
            return;
        }
        ret = mediaPlayer_->SetVideoSurface(surface_);
        if (ret != 0) {
            LOGE("PlayVideo SetVideoSurface fail, errorCode: %{public}d", ret);
            return;
        }
    
        if (!SetVideoSound()) {
            LOGW("SetVideoSound failed");
        }
    
        ret = mediaPlayer_->Prepare();
        if (ret !=  0) {
            LOGE("PlayVideo Prepare fail, errorCode: %{public}d", ret);
            return;
        }
        LOGI("PlayVideo end");
    #else
        LOGI("player framework is disabled");
    #endif
    }

5.0.0在while循环里面有9次失败的打印,每次1.2秒。以下是日志:

Line 2734: 01-01 08:00:06.817 2201 2298 I C01400/BootAnimation: PlayVideo begin

Line 3802: 01-01 08:00:08.036 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 4352: 01-01 08:00:09.276 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 5934: 01-01 08:00:10.520 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 7785: 01-01 08:00:11.757 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 9166: 01-01 08:00:12.997 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 10496: 01-01 08:00:14.237 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 11938: 01-01 08:00:15.479 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 13300: 01-01 08:00:16.724 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 21760: 01-01 08:00:17.962 2201 2298 I C01400/BootAnimation: mediaPlayer is nullptr, try create again

5.0.3在while循环里面有2次失败的打印,每次4.2秒。

Line 3340: 01-01 08:00:08.321 2242 2359 I C01400/BootAnimation: PlayVideo begin

Line 6265: 01-01 08:00:12.360 2242 2359 I C01400/BootAnimation: mediaPlayer is nullptr, try create again Line 10727: 01-01 08:00:16.541 2242 2359 I C01400/BootAnimation: mediaPlayer is nullptr, try create again

1.2 Media::PlayerFactory::CreatePlayer()往下调用GetMediaProxy()等待PLAYER_DISTRIBUTED_SERVICE

调用到sa的流程CreatePlayer()-->PlayerImpl::Init()-->CreatePlayerService()--> IsAlived()-->GetMediaProxy()-->GetSystemAbility

    sptr<IStandardMediaService> MediaClient::GetMediaProxy()
    {
        MEDIA_LOGD("enter");
        sptr<ISystemAbilityManager> samgr = nullptr;
        samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
        CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr, "system ability manager is nullptr.");
        sptr<IRemoteObject> object = nullptr;
        //调用GetSystemAbility等待sa启动
        object = samgr->GetSystemAbility(OHOS::PLAYER_DISTRIBUTED_SERVICE_ID);
        CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "media object is nullptr.");
    
        mediaProxy_ = iface_cast<IStandardMediaService>(object);
        CHECK_AND_RETURN_RET_LOG(mediaProxy_ != nullptr, nullptr, "media proxy is nullptr.");
    
        pid_t pid = 0;
        deathRecipient_ = new(std::nothrow) MediaDeathRecipient(pid);
        CHECK_AND_RETURN_RET_LOG(deathRecipient_ != nullptr, nullptr, "failed to new MediaDeathRecipient.");
    
        deathRecipient_->SetNotifyCb(std::bind(&MediaClient::MediaServerDied, std::placeholders::_1));
        bool result = object->AddDeathRecipient(deathRecipient_);
        if (!result) {
            MEDIA_LOGE("failed to add deathRecipient");
            return nullptr;
        }
    
        listenerStub_ = new(std::nothrow) MediaListenerStub();
        CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, nullptr, "failed to new MediaListenerStub");
        return mediaProxy_;
    }

GetSystemAbilityWrapper:重试次数原来是20次。执行循环次数。如果没有等待成功,返回nullptr.改成6次后,每次循环等待的时长变成1.2秒。

    const int32_t RETRY_TIME_OUT_NUMBER = 6;//原来是20
    
    sptr<IRemoteObject> SystemAbilityManagerProxy::GetSystemAbility(int32_t systemAbilityId,
        const std::string& deviceId)
    {
        return GetSystemAbilityWrapper(systemAbilityId, deviceId);
    }
    
    sptr<IRemoteObject> SystemAbilityManagerProxy::GetSystemAbilityWrapper(int32_t systemAbilityId, const string& deviceId)
    {
        if (!CheckInputSysAbilityId(systemAbilityId)) {
            HILOGW("GetSaWrap SA invalid:%{public}d!", systemAbilityId);
            return nullptr;
        }
    
        bool isExist = false;
        int32_t timeout = RETRY_TIME_OUT_NUMBER;
        HILOGD("GetSaWrap:Waiting for SA:%{public}d, ", systemAbilityId);
        do {
            sptr<IRemoteObject> svc;
            int32_t errCode = ERR_NONE;
            if (deviceId.empty()) {
                svc = CheckSystemAbility(systemAbilityId, isExist, errCode);
                if (errCode == ERR_PERMISSION_DENIED) {
                    HILOGE("GetSaWrap SA:%{public}d selinux denied", systemAbilityId);
                    return nullptr;
                }
                if (!isExist) {
                    HILOGD("%{public}s:SA:%{public}d is not exist", __func__, systemAbilityId);
                }
            } else {
                svc = CheckSystemAbility(systemAbilityId, deviceId, errCode);
                if (errCode == ERR_PERMISSION_DENIED) {
                    HILOGE("GetSaWrap SA:%{public}d deviceId selinux denied", systemAbilityId);
                    return nullptr;
                }
            }
    
            if (svc != nullptr) {
                return svc;
            }
            if (timeout > 0) {
                usleep(SLEEP_ONE_MILLI_SECOND_TIME * SLEEP_INTERVAL_TIME);
            }
        } while (timeout--);
        HILOGE("GetSaWrap SA:%{public}d not start", systemAbilityId);
        return nullptr;
    }

耗时原因:将重试次数改成20后,由于这个重试次数是全局的,导致其他服务本来花6次等待,现在花了20次等待,所以整个开机耗时变长了。

5.0.0CreatePlayer重试了9次,第10次成功了。每次1.2秒,每次里面sa重试了5次。共计sa重试了45次以上。

5.0.3重试了2次,第3次成功了,每次4.18秒,每次里面sa重试了20次。

改成6次后重试重试变成了7次,第8次成功。

性能优化的大致方向是更新mp4资源,减少服务等待。对于开机耗时由于抓不了开机trace,分析的时候需要根据耗时点优化资源加载和启动服务的减少耗时

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐