优化播放器操作 3032/1 3032/head 3033/target/1
authorxue <2144439972@qq.com>
Tue, 6 Jan 2026 12:13:00 +0000 (20:13 +0800)
committerxue <2144439972@qq.com>
Tue, 6 Jan 2026 12:13:00 +0000 (20:13 +0800)
code/sdk/middleware/services/gui/uikit/ui/frameworks/imgdecode/cache_manager.cpp
code/sdk/middleware/services/media/foundation/player/frameworks/player_control/player/liteplayer.cpp
code/sdk/middleware/services/media/foundation/player/frameworks/player_control/player/liteplayer.h

index c3506b8..58c4b01 100644 (file)
 #include "gfx_utils/graphic_log.h"
 #include "hal_tick.h"
 #include "securec.h"
+#include <cstring>
+#include <cstdio>
+#include <cerrno>
+#include <cstring>  // for strerror
 #if (ENABLE_JPEG_AND_PNG && CACHE_JPEG_AND_PNG)
 #include "common/image.h"
 #include "imgdecode/jpeg_img_decoder.h"
@@ -73,15 +77,18 @@ RetCode CacheEntry::SetSrc(const char* path)
     if (dsc_.srcType == IMG_SRC_FILE) {
         size_t strLen = strlen(path);
         if (strLen > MAX_SRC_LENGTH) {
+            GRAPHIC_LOGE("CacheManager SetSrc %s failed,%d\n", path,__LINE__);
             return RetCode::FAIL;
         }
         char* newStr = static_cast<char*>(UIMalloc(static_cast<uint32_t>(strLen) + 1));
         if (newStr == nullptr) {
+            GRAPHIC_LOGE("CacheManager SetSrc %s failed,%d\n", path,__LINE__);
             return RetCode::FAIL;
         }
         if (memcpy_s(newStr, strLen + 1, path, strLen) != EOK) {
             UIFree(reinterpret_cast<void*>(newStr));
             newStr = nullptr;
+            GRAPHIC_LOGE("CacheManager SetSrc %s failed,%d\n", path,__LINE__);
             return RetCode::FAIL;
         }
         newStr[strLen] = '\0';
@@ -286,6 +293,7 @@ RetCode CacheManager::TryDecode(const char* path, const Style& style, CacheEntry
     RetCode ret = entry.SetSrc(path);
     if (ret != RetCode::OK) {
         Clear(entry);
+        GRAPHIC_LOGE("CacheManager TryDecode %s failed,%d\n", path,__LINE__);
         return ret;
     }
     FileImgDecoder* decoder = &(FileImgDecoder::GetInstance());
@@ -305,6 +313,7 @@ RetCode CacheManager::TryDecode(const char* path, const Style& style, CacheEntry
 #endif
     if (decoder == nullptr) {
         Clear(entry);
+        GRAPHIC_LOGE("CacheManager TryDecode %s failed,%d\n", path,__LINE__);
         return RetCode::FAIL;
     }
     entry.dsc_.decoder = decoder;
@@ -312,12 +321,14 @@ RetCode CacheManager::TryDecode(const char* path, const Style& style, CacheEntry
     ret = entry.dsc_.decoder->Open(entry.dsc_);
     if (ret != RetCode::OK) {
         Clear(entry);
+        GRAPHIC_LOGE("CacheManager TryDecode %s failed,%d\n", path,__LINE__);
         return ret;
     }
 
     ret = entry.dsc_.decoder->GetHeader(entry.dsc_);
     if (ret != RetCode::OK) {
         Clear(entry);
+        GRAPHIC_LOGE("CacheManager TryDecode %s failed,%d\n", path,__LINE__);
         return ret;
     }
 
index 6512086..a914912 100644 (file)
-/*\r
- * Copyright (c) 2020-2023 Huawei Device Co., Ltd.\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "liteplayer.h"\r
-\r
-#ifdef SUPPORT_SYS_PRCTL\r
-#include <sys/prctl.h>\r
-#endif\r
-#include <unistd.h>\r
-#include "player_check.h"\r
-#include "hi_liteplayer_err.h"\r
-#include "liteplayer_comm.h"\r
-#if !defined(UNSUPPORT_AUDIO_DECODER) || !defined(UNSUPPORT_VIDEO_DECODER)\r
-#include "decoder.h"\r
-#endif\r
-\r
-#if !defined(UNSUPPORT_AUDIO_DECODER) || !defined(UNSUPPORT_VIDEO_DECODER)\r
-using OHOS::Media::Decoder;\r
-#endif\r
-using OHOS::Media::PlayerSource;\r
-using OHOS::Media::SinkManager;\r
-\r
-namespace OHOS {\r
-namespace Media {\r
-/* DEFAULT_VID_BUFSIZE: 2 * 1024 * 1024 */\r
-const uint32_t DEFAULT_VID_BUFSIZE = 2097152;\r
-/* DEFAULT_AUD_BUFSIZE: 256 * 1024 */\r
-const uint32_t DEFAULT_AUD_BUFSIZE = 262144;\r
-\r
-const uint32_t GET_BUFFER_TIMEOUT_MS = 0u;\r
-const uint32_t RENDER_FULL_SLEEP_TIME_US = 10000u;\r
-// 1. waiting app response playback complete callback event\r
-// 2. waiting interval time for loop playback\r
-const uint32_t RENDER_EOS_SLEEP_TIME_US = 3000000u;\r
-const uint32_t WAIT_BUFFER_EMPTY_SLEEP_TIME_US = 1000000u;\r
-const uint32_t DECODER_DEFAULT_WIDTH = 1920;\r
-const uint32_t DECODER_DEFAULT_HEIGHT = 1080;\r
-const uint32_t QUEUE_BUFFER_FULL_SLEEP_TIME_US = 10000u;\r
-const uint32_t NO_DATA_READ_SLEEP_TIME_US = 5000u;\r
-const uint32_t MAX_EVENT_MESSAGE_NUM = 128;\r
-const uint32_t MAX_THREAD_STACK_SIZE = 0x1800u;\r
-const uint32_t REQUEST_BUFFER_RETRY_WAIT_TIME_US = 10000u;\r
-const float YCBCR420SP_BUFFER_SIZE_COEFFICIENT = 1.5;\r
-#ifdef DEBUG_LOW_POWER\r
-const uint32_t RENDER_FULL_SLEEP_THRESHOLD_MS_MP3_AACLC_OPUS = 5;\r
-const uint32_t RENDER_FULL_SLEEP_THRESHOLD_MS_PCM = 25;\r
-const uint32_t RENDER_FULL_SLEEP_THRESHOLD_MS_FLAC = 50;\r
-#endif\r
-// In a single-process system, only one thread can work at a time.\r
-// Subthreads need to give CPU resources to the main thread to switch to the playback state.\r
-const uint32_t WAIT_MAIN_THREAD_SWITCH_TO_PLAY_STATUS_TIME_US = 10000u;\r
-// maximum number of consecutive surface buffer request failures retries(converted to time: 100 * 10ms = 1s)\r
-const uint32_t MAX_CONTINOUS_REQUEST_SURFACE_BUFFER_FAIL_COUNT = 100;\r
-\r
-static AudioCodecFormat g_fromCodecFormatToAudioManager[CODEC_BUT + 1] = {\r
-    FORMAT_INVALID, FORMAT_INVALID, FORMAT_INVALID, FORMAT_INVALID,\r
-    AAC_LC, G711A, G711U, PCM, MP3, G726, OPUS, FLAC, VORBIS, APE, SILK, SBC, FORMAT_INVALID\r
-};\r
-static EsFrameType g_fromDemuxTypeToSinkType[FRAME_TYPE_BUT + 1] = {\r
-    ESFRAME_TYPE_NONE, ESFRAME_TYPE_AUDIO, ESFRAME_TYPE_VIDEO, ESFRAME_TYPE_IMAGE, ESFRAME_TYPE_SUB,\r
-    ESFRAME_TYPE_DATA, ESFRAME_INVALID_TYPE\r
-};\r
-\r
-static CodecFormatAndMimePair g_avCodecFormatInfo[CODEC_BUT + 1] = {\r
-    { CODEC_H264, MEDIA_MIMETYPE_VIDEO_AVC },\r
-    { CODEC_H265, MEDIA_MIMETYPE_VIDEO_HEVC },\r
-    { CODEC_JPEG, MEDIA_MIMETYPE_IMAGE_JPEG },\r
-    { CODEC_MJPEG, MEDIA_MIMETYPE_IMAGE_MJPEG },\r
-    { CODEC_AAC, MEDIA_MIMETYPE_AUDIO_AAC },\r
-    { CODEC_G711A, MEDIA_MIMETYPE_AUDIO_G711A },\r
-    { CODEC_G711U, MEDIA_MIMETYPE_AUDIO_G711U },\r
-    { CODEC_PCM, MEDIA_MIMETYPE_AUDIO_PCM },\r
-    { CODEC_MP3, MEDIA_MIMETYPE_AUDIO_MP3 },\r
-    { CODEC_G726, MEDIA_MIMETYPE_AUDIO_G726 },\r
-    { CODEC_BUT, MEDIA_MIMETYPE_INVALID },\r
-};\r
-\r
-namespace {\r
-/* playing position notify interval in ms */\r
-const uint32_t DEFAULT_POS_NOFITY_INTERVAL = 300;\r
-}\r
-\r
-#ifdef DEBUG_LOW_POWER\r
-const int32_t US_2_MS = 1000;\r
-#endif\r
-\r
-void PlayerControl::RecordTime(struct timeval &timeStart)\r
-{\r
-    gettimeofday(&timeStart, nullptr);\r
-}\r
-\r
-uint64_t PlayerControl::CalcTimeDiffUsPrint(const struct timeval &timeStart, struct timeval &timeEnd,\r
-    std::string outString, bool showlog)\r
-{\r
-    gettimeofday(&timeEnd, nullptr);\r
-    const uint64_t timeUs = 1000000;\r
-    uint64_t diffSecToUs = 0;\r
-    bool isOverflow =\r
-        UIntMulIsOverflow64(static_cast<uint64_t>(timeEnd.tv_sec - timeStart.tv_sec), timeUs, &diffSecToUs);\r
-    if (isOverflow) {\r
-        MEDIA_ERR_LOG("PlayerControl::CalcTimeDiffUsPrint calculate reslut overflow!");\r
-        return INVALID_TIME;\r
-    }\r
-    uint64_t diffUsec = static_cast<uint64_t>(timeEnd.tv_usec - timeStart.tv_usec);\r
-    uint64_t diffTimeUS = diffSecToUs + diffUsec;\r
-    if (showlog) {\r
-        MEDIA_INFO_LOG("%s elapsed time: %lld us", outString.c_str(), diffTimeUS);\r
-    }\r
-    return diffTimeUS;\r
-}\r
-\r
-int32_t PlayerControl::GetPlayerControlDumpInfo(PlayerControlDebugInfo &playerControlInfo)\r
-{\r
-    playerControlInfo.currentPosition = currentPosition_;\r
-    playerControlInfo.hasRenderAudioEos = hasRenderAudioEos_;\r
-    playerControlInfo.hasRenderVideoEos = hasRenderVideoEos_;\r
-    playerControlInfo.isAudioStarted = isAudioStarted_;\r
-    playerControlInfo.isVideoStarted = isVideoStarted_;\r
-    playerControlInfo.offloadAudio = offloadAudio_;\r
-    playerControlInfo.outDevice = outDeviceId_;\r
-    playerControlInfo.sessionId = audioSession_;\r
-    return 0;\r
-}\r
-\r
-int32_t PlayerControl::GetPlayerVideoDumpInfo(PlayerVideoDebugInfo &videoDebugInfo)\r
-{\r
-    videoDebugInfo.frameBufCnt = vdecAttr_.frameBufCnt;\r
-    videoDebugInfo.u32Height = vdecAttr_.maxHeight;\r
-    videoDebugInfo.u32Width = vdecAttr_.maxWidth;\r
-    videoDebugInfo.enVideoType = vdecAttr_.type;\r
-    return 0;\r
-}\r
-\r
-int32_t PlayerControl::GetPlayerAudioDumpInfo(PlayerAudioDebugInfo &audioDebugInfo)\r
-{\r
-    audioDebugInfo.bitWidth = adecAttr_.bitWidth;\r
-    audioDebugInfo.enAudioType = adecAttr_.type;\r
-    return 0;\r
-}\r
-\r
-int32_t PlayerControl::GetPlayerFileDumpInfo(PlayerFileDebugInfo &fileDebugInfo)\r
-{\r
-    fileDebugInfo.filePath = filePath_;\r
-    fileDebugInfo.fd = fd_;\r
-    fileDebugInfo.offset = offset_;\r
-    return 0;\r
-}\r
-\r
-void PlayerControl::PrintKpiTime()\r
-{\r
-#ifdef PLAYER_KPI_ON\r
-    if (!recordFirstFrameCost_ && currentPosition_ >= 0) {\r
-        std::string startPlay("KPI_PlayNewFileTime");\r
-        CalcTimeDiffUsPrint(startPlayStartTime_, startPlayEndTime_, startPlay, KPI_PRINT);\r
-        recordFirstFrameCost_ = true;\r
-    }\r
-#endif\r
-}\r
-\r
-PlayerControl::PlayerControl()\r
-    : isInited_(false),\r
-      isPlayEnd_(false),\r
-      isAudPlayEos_(false),\r
-      cachedPacket_(false),\r
-      lastRendPos_(0),\r
-      lastNotifyTime_(0),\r
-      lastReadPktStrmIdx_(-1),\r
-      lastReadPktPts_(0),\r
-      lastSendPktPts_(0),\r
-      isVideoStarted_(false),\r
-      isAudioStarted_(false),\r
-      strmReadEnd_(false),\r
-      isPlayErr_(false),\r
-      lastSendAdecPts_(AV_INVALID_PTS),\r
-      currentPosition_(0),\r
-      paused_(false),\r
-      schThreadExit_(false),\r
-      loop_(false),\r
-      hasRenderAudioEos_(false),\r
-      hasRenderVideoEos_(false),\r
-      renderSleepTime_(0),\r
-      leftVolume_(-1.0f),\r
-      rightVolume_(-1.0f),\r
-      schMutex_(nullptr),\r
-      schCond_(nullptr),\r
-      schProcess_(nullptr),\r
-      seekToTimeMs_(-1),\r
-      sourceType_(SOURCE_TYPE_BUT),\r
-      firstAudioFrameAfterSeek_(false),\r
-      firstPosAfterSeek_(0),\r
-      fd_(-1),\r
-      offset_(0),\r
-      playerSource_(nullptr),\r
-      sinkManager_(nullptr),\r
-      surface_(nullptr),\r
-      surfaceBuf_(nullptr),\r
-      curState_(PLAY_STATUS_IDLE),\r
-      offloadAudio_(false),\r
-      audioSession_(0),\r
-      streamType_(AUDIO_STREAM_MUSIC),\r
-      recordFirstFrameCost_(false),\r
-      renderEsTotalTime_(0),\r
-      readPktTotalTime_(0),\r
-      renderEsFrameCnt_(0),\r
-      readPacketCnt_(0),\r
-      outDeviceId_(OUT_BUILTIN_SPEAKER),\r
-      headInSendSuccessInterval_(-1),\r
-      tailInSendSuccessInterval_(-1),\r
-      hasAudio_(false),\r
-      hasVideo_(false),\r
-      isAudio_(false),\r
-      isVideo_(false)\r
-{\r
-    eventCallback_.player = nullptr;\r
-    eventCallback_.callbackFun = nullptr;\r
-    if (memset_s(&fmtFileInfo_, sizeof(fmtFileInfo_), 0, sizeof(FormatFileInfo)) != EOK) {\r
-        MEDIA_ERR_LOG("memset_s failed");\r
-    }\r
-    fmtFileInfo_.s32UsedAudioStreamIndex = HI_DEMUXER_NO_MEDIA_STREAM;\r
-    fmtFileInfo_.s32UsedVideoStreamIndex = HI_DEMUXER_NO_MEDIA_STREAM;\r
-    playerParam_.u32PlayPosNotifyIntervalMs = DEFAULT_POS_NOFITY_INTERVAL;\r
-    playerParam_.u32VideoEsBufSize = DEFAULT_POS_NOFITY_INTERVAL;\r
-    playerParam_.u32AudioEsBufSize = DEFAULT_POS_NOFITY_INTERVAL;\r
-    playerParam_.u32VdecFrameBufCnt = DEFAULT_POS_NOFITY_INTERVAL;\r
-    if (memset_s(&formatPacket_, sizeof(formatPacket_), 0, sizeof(FormatFrame)) != EOK) {\r
-        MEDIA_ERR_LOG("memset_s failed");\r
-    }\r
-    streamAttr_.videoBufSize = 0;\r
-    streamAttr_.audioBufSize = 0;\r
-    adecAttr_.type = 0;\r
-    adecAttr_.sampleRate = 0;\r
-    adecAttr_.channel = 0;\r
-    adecAttr_.bitWidth = 0;\r
-    streamSource_.param.sampleRate = 0;\r
-    streamSource_.param.sampleFormat = 0;\r
-    streamSource_.param.channelCount = 0;\r
-    streamSource_.param.channelLayout = 0;\r
-    streamSource_.stream.ReadData = nullptr;\r
-    streamSource_.stream.GetReadableSize = nullptr;\r
-    streamSource_.stream.handle = nullptr;\r
-    eventQueue_.clear();\r
-    startPlayStartTime_.tv_sec = 0;\r
-    startPlayStartTime_.tv_usec = 0;\r
-    startPlayEndTime_.tv_sec = 0;\r
-    startPlayEndTime_.tv_usec = 0;\r
-    streamEndTime_.tv_sec = 0;\r
-    streamEndTime_.tv_usec = 0;\r
-    metaData_.key = 0;\r
-    metaData_.size = 0;\r
-#if !defined(UNSUPPORT_AUDIO_DECODER)\r
-    audioDecoder_ = nullptr;\r
-#endif\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-    videoDecoder_ = nullptr;\r
-#endif\r
-}\r
-\r
-PlayerControl::~PlayerControl()\r
-{\r
-    (void)Deinit();\r
-    eventQueue_.clear();\r
-}\r
-\r
-int32_t PlayerControl::InitAttr(const PlayerControlParam &createParam)\r
-{\r
-    if (memset_s(&fmtFileInfo_, sizeof(fmtFileInfo_), 0x00, sizeof(FormatFileInfo)) != EOK) {\r
-        MEDIA_ERR_LOG("memset_s failed");\r
-        return HI_ERR_PLAYERCONTROL_MEM_SET;\r
-    }\r
-    fmtFileInfo_.s32UsedAudioStreamIndex = HI_DEMUXER_NO_MEDIA_STREAM;\r
-    fmtFileInfo_.s32UsedVideoStreamIndex = HI_DEMUXER_NO_MEDIA_STREAM;\r
-    streamAttr_.playMode = RENDER_MODE_NORMAL;\r
-    streamAttr_.videoBufSize = DEFAULT_VID_BUFSIZE;\r
-    streamAttr_.audioBufSize = DEFAULT_AUD_BUFSIZE;\r
-\r
-    lastReadPktPts_ = 0;\r
-    lastSendPktPts_ = 0;\r
-    CHECK_FAILED_PRINT(memcpy_s(&playerParam_, sizeof(playerParam_), &createParam, sizeof(PlayerControlParam)), EOK,\r
-        "copy playerParam_ fail");\r
-    playerParam_.u32PlayPosNotifyIntervalMs = (createParam.u32PlayPosNotifyIntervalMs == 0) ?\r
-        DEFAULT_POS_NOFITY_INTERVAL :\r
-        createParam.u32PlayPosNotifyIntervalMs;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::Init(const PlayerControlParam &createParam)\r
-{\r
-    MEDIA_INFO_LOG("Init in");\r
-    CHECK_TRUE_CONDITION_RETURN(isInited_, HI_SUCCESS, "already be inited");\r
-    CHECK_FAILED_RETURN(InitAttr(createParam), HI_SUCCESS, HI_FAILURE, "InitAttr failed");\r
-    schMutex_ = MediaMutexCreate(nullptr);\r
-    if (schMutex_ == nullptr) {\r
-        MEDIA_ERR_LOG("create mutex failed");\r
-        return HI_FAILURE;\r
-    }\r
-    schCond_ = MediaThreadCondCreate();\r
-    if (schCond_ == nullptr) {\r
-        MEDIA_ERR_LOG("create cond failed");\r
-        MediaMutexDestroy(&schMutex_);\r
-        return HI_FAILURE;\r
-    }\r
-    isInited_ = true;\r
-#ifdef PLAYER_KPI_ON\r
-    RecordTime(startPlayStartTime_);\r
-#endif\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::Deinit()\r
-{\r
-    if (!isInited_) {\r
-        return HI_SUCCESS;\r
-    }\r
-    DestroyDecoder();\r
-    MediaMutexDestroy(&schMutex_);\r
-    MediaThreadCondDestroy(&schCond_);\r
-    isInited_ = false;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::RegCallback(PlayerCtrlCallbackParam &eventCallback)\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_REGCALLBACK;\r
-    msg.msgData = static_cast<void *>(&eventCallback);\r
-    msg.msgDataLen = 0;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::SetDataSource(const std::string filepath)\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_SET_DATASOURCE_URI;\r
-    msg.msgData = const_cast<void *>(static_cast<const void *>(filepath.c_str()));\r
-    msg.msgDataLen = 0;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::SetDataSource(SourceFdParam &fdSrc)\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_SET_DATASOURCE_FD;\r
-    msg.msgData = static_cast<void *>(&fdSrc);\r
-    msg.msgDataLen = 0;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::SetDataSource(StreamSourceParam &streamSource)\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_SET_DATASOURCE_STREAM;\r
-    msg.msgData = static_cast<void *>(&streamSource);\r
-    msg.msgDataLen = 0;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::Prepare()\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_PREPARE;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::Play()\r
-{\r
-    int32_t ret;\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_PLAY;\r
-    ret = OnMessageReceived(msg);\r
-    CHECK_FAILED_PRINT(ret, HI_SUCCESS, "play failed");\r
-    return ret;\r
-}\r
-\r
-int32_t PlayerControl::SetVolume(const VolumeAttr &volumeAttr)\r
-{\r
-    VolumeAttr attr = volumeAttr;\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_SET_VOLUME;\r
-    msg.msgData = static_cast<void *>(&attr);\r
-    msg.msgDataLen = 0;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::Stop()\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_STOP;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::Pause()\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_PAUSE;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::Seek(int64_t timeInMs)\r
-{\r
-    if (fmtFileInfo_.enVideoType == CODEC_JPEG) {\r
-        MEDIA_ERR_LOG("seek action not support for play picture");\r
-        return HI_ERR_PLAYERCONTROL_NOT_SUPPORT;\r
-    }\r
-    if ((fmtFileInfo_.s64Duration > 0) && (fmtFileInfo_.s64Duration < timeInMs)) {\r
-        return HI_ERR_PLAYERCONTROL_ILLEGAL_PARAM;\r
-    }\r
-    seekToTimeMs_ = timeInMs;\r
-    MediaThreadCondSignal(schCond_);\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::GetFileInfo(FormatFileInfo &formatInfo)\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_GETFILEINFO;\r
-    msg.msgData = &formatInfo;\r
-    msg.msgDataLen = sizeof(FormatFileInfo);\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::SetMedia(PlayerControlStreamAttr &mediaAttr)\r
-{\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_SETATTR;\r
-    msg.msgData = &mediaAttr;\r
-    msg.msgDataLen = sizeof(PlayerControlStreamAttr);\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-#if defined(ENABLE_UIKIT)\r
-int32_t PlayerControl::SetSurface(Surface *surface)\r
-#elif defined(ENABLE_LVGL)\r
-int32_t PlayerControl::SetSurface(LvSurfaceView *surface)\r
-#endif\r
-{\r
-    surface_ = surface;\r
-    return 0;\r
-}\r
-\r
-int32_t PlayerControl::SetPlaybackSpeed(float speed)\r
-{\r
-    float setSpeed = speed;\r
-    MsgInfo msg = {};\r
-    msg.what = PLAYERCONTROL_MSG_SETSPEED;\r
-    msg.msgData = static_cast<void *>(&setSpeed);\r
-    msg.msgDataLen = 0;\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-void PlayerControl::ClearCachePacket()\r
-{\r
-    if (cachedPacket_) {\r
-        if (formatPacket_.data != nullptr) {\r
-            if (playerSource_ != nullptr && playerSource_->FreeFrame(formatPacket_) != 0) {\r
-                MEDIA_ERR_LOG("FreeFrame failed \n");\r
-            }\r
-            formatPacket_.data = nullptr;\r
-            formatPacket_.len = 0;\r
-            formatPacket_.trackId = -1;\r
-        }\r
-        /* end packet is null do not need to demux free */\r
-        cachedPacket_ = false;\r
-    }\r
-}\r
-\r
-void PlayerControl::OnVideoEndOfStream()\r
-{\r
-    if (!hasAudio_ && (lastSendVdecPts_ > AV_INVALID_PTS)) {\r
-        EventCallback(PLAYERCONTROL_EVENT_PROGRESS, &lastSendVdecPts_);\r
-    }\r
-    isVidPlayEos_ = true;\r
-    isPlayEnd_ = IsPlayEos() ? true : isPlayEnd_;\r
-}\r
-\r
-void PlayerControl::EventProcess(EventCbType event)\r
-{\r
-    PlayerControlError playerError;\r
-    MEDIA_DEBUG_LOG("handleEvent %d", event);\r
-    switch (event) {\r
-        case EVNET_VIDEO_PLAY_EOS:\r
-            OnVideoEndOfStream();\r
-            break;\r
-        case EVNET_VIDEO_PLAY_SOS:\r
-            MEDIA_INFO_LOG("video sos recv");\r
-            break;\r
-        case EVNET_AUDIO_PLAY_EOS:\r
-            isAudPlayEos_ = true;\r
-            isPlayEnd_ = IsPlayEos() ? true : isPlayEnd_;\r
-            if (lastSendAdecPts_ > AV_INVALID_PTS) {\r
-                EventCallback(PLAYERCONTROL_EVENT_PROGRESS, &lastSendAdecPts_);\r
-            }\r
-            break;\r
-        case EVNET_VIDEO_RUNNING_ERR:\r
-        case EVNET_AUDIO_RUNNING_ERR:\r
-            playerError = PLAYERCONTROL_ERROR_AUD_PLAY_FAIL;\r
-            isPlayErr_ = true;\r
-            EventCallback(PLAYERCONTROL_EVENT_ERROR, &playerError);\r
-            break;\r
-        default:\r
-            break;\r
-    }\r
-}\r
-\r
-void PlayerControl::EventQueueProcess(void)\r
-{\r
-    size_t queSize;\r
-    PalayControlEventItem *item = nullptr;\r
-\r
-    queSize = eventQueue_.size();\r
-    if (queSize > MAX_EVENT_MESSAGE_NUM) {\r
-        MEDIA_WARNING_LOG("mesaage except, num:%u", queSize);\r
-    }\r
-    for (size_t i = 0; i < queSize && i < MAX_EVENT_MESSAGE_NUM; i++) {\r
-        item = &eventQueue_[i];\r
-        EventProcess(item->event);\r
-    }\r
-    eventQueue_.clear();\r
-}\r
-\r
-int32_t PlayerControl::OnPlayControlEvent(void *priv, const EventCbType event) const\r
-{\r
-    // audio play eos event needs to be handled immediately\r
-    if (event == EVNET_AUDIO_PLAY_EOS) {\r
-        MEDIA_INFO_LOG("Received audio play eos event");\r
-        EventCallback(PLAYERCONTROL_EVENT_EOF, nullptr);\r
-        return HI_SUCCESS;\r
-    } else if (event == EVNET_AUDIO_BUFFER_EMPTY) {\r
-        EventCallback(PLAYERCONTROL_BUFFER_EMPTY, nullptr);\r
-        return HI_SUCCESS;\r
-    } else if (event == EVNET_OUTPUT_DEVICE_CHANGED) {\r
-        PlayerControl *player = static_cast<PlayerControl *>(priv);\r
-        player->RecordLastPosition();\r
-        return HI_SUCCESS;\r
-    } else if (event == EVNET_AUDIO_RUNNING_ERR ||\r
-        event == EVNET_VIDEO_RUNNING_ERR) {\r
-        PlayerControlError playerError = PLAYERCONTROL_ERROR_AUD_PLAY_FAIL;\r
-        EventCallback(PLAYERCONTROL_EVENT_ERROR, &playerError);\r
-        return HI_SUCCESS;\r
-    }\r
-\r
-    PalayControlEventItem item;\r
-    PlayerControl *player = static_cast<PlayerControl *>(priv);\r
-\r
-    item.event = event;\r
-    player->eventQueue_.push_back(item);\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::PauseResume(void)\r
-{\r
-    CHECK_NULL_RETURN(sinkManager_, HI_ERR_PLAYERCONTROL_NULL_PTR, "sinkManager_ nullptr");\r
-    MediaMutexLock(schMutex_);\r
-    int32_t ret = sinkManager_->Resume();\r
-    if (ret != HI_SUCCESS) {\r
-        if (ret != NOT_FOUND_ACTIVE_STREAME) {\r
-            MEDIA_ERR_LOG("resume failed");\r
-            hasVideo_ ? NotifyError(PLAYERCONTROL_ERROR_VID_PLAY_FAIL) : NotifyError(PLAYERCONTROL_ERROR_AUD_PLAY_FAIL);\r
-        }\r
-        MediaMutexUnLock(schMutex_);\r
-        return ret;\r
-    }\r
-    paused_ = false;\r
-    // played to the end no need to signal\r
-    if (!IsPlayEos()) {\r
-        MediaThreadCondSignal(schCond_);\r
-    }\r
-    MediaMutexUnLock(schMutex_);\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::CheckMediaInfo(void) const\r
-{\r
-    if (fmtFileInfo_.s32UsedAudioStreamIndex >= HI_DEMUXER_RESOLUTION_CNT ||\r
-        fmtFileInfo_.s32UsedVideoStreamIndex >= HI_DEMUXER_RESOLUTION_CNT) {\r
-        MEDIA_ERR_LOG("input file error video track: %d audio %d", fmtFileInfo_.s32UsedVideoStreamIndex,\r
-            fmtFileInfo_.s32UsedAudioStreamIndex);\r
-        return HI_ERR_PLAYERCONTROL_DEMUX_ERROR;\r
-    }\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::GetVideoResolution(int32_t streamIdx, StreamResolution &resolution)\r
-{\r
-    if (streamIdx == HI_DEMUXER_NO_MEDIA_STREAM) {\r
-        MEDIA_ERR_LOG("stream id [%d] in invalid", streamIdx);\r
-        return HI_FAILURE;\r
-    }\r
-\r
-    for (uint32_t i = 0; i < HI_DEMUXER_RESOLUTION_CNT; i++) {\r
-        if (fmtFileInfo_.stSteamResolution[i].s32VideoStreamIndex == streamIdx) {\r
-            resolution.enVideoType = fmtFileInfo_.stSteamResolution[i].enVideoType;\r
-            resolution.s32VideoStreamIndex = fmtFileInfo_.stSteamResolution[i].s32VideoStreamIndex;\r
-            resolution.u32Width = fmtFileInfo_.stSteamResolution[i].u32Width;\r
-            resolution.u32Height = fmtFileInfo_.stSteamResolution[i].u32Height;\r
-            return HI_SUCCESS;\r
-        }\r
-    }\r
-\r
-    MEDIA_ERR_LOG("not found stream[%d] in file", streamIdx);\r
-    return HI_FAILURE;\r
-}\r
-\r
-int32_t PlayerControl::SetVDecAttr(void)\r
-{\r
-    StreamResolution resolution = {};\r
-    if (GetVideoResolution(fmtFileInfo_.s32UsedVideoStreamIndex, resolution) != HI_SUCCESS) {\r
-        MEDIA_ERR_LOG("GetVideoResolution failed");\r
-        return HI_FAILURE;\r
-    }\r
-    vdecAttr_.maxWidth = resolution.u32Width;\r
-    vdecAttr_.maxHeight = resolution.u32Height;\r
-    vdecAttr_.type = resolution.enVideoType;\r
-    vdecAttr_.frameBufCnt = playerParam_.u32VdecFrameBufCnt;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::SetADecAttr(void)\r
-{\r
-    adecAttr_.bitWidth = AUDIO_BITWIDTH;\r
-    adecAttr_.channel = fmtFileInfo_.u32AudioChannelCnt;\r
-    adecAttr_.sampleRate = fmtFileInfo_.u32SampleRate;\r
-    adecAttr_.type = fmtFileInfo_.enAudioType;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::SetStreamAttr()\r
-{\r
-    if (hasVideo_) {\r
-        StreamResolution resolution = {};\r
-        if (GetVideoResolution(fmtFileInfo_.s32UsedVideoStreamIndex, resolution) != HI_SUCCESS) {\r
-            MEDIA_ERR_LOG("GetVideoResolution failed");\r
-            return HI_ERR_PLAYERCONTROL_ILLEGAL_PARAM;\r
-        }\r
-        streamAttr_.videoBufSize = playerParam_.u32VideoEsBufSize;\r
-    }\r
-\r
-    if (hasAudio_) {\r
-        streamAttr_.audioBufSize =\r
-            (playerParam_.u32AudioEsBufSize) ? (playerParam_.u32AudioEsBufSize) : streamAttr_.audioBufSize;\r
-    }\r
-\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::SetDecoderAndStreamAttr(void)\r
-{\r
-    int ret;\r
-\r
-    if (hasAudio_) {\r
-        ret = SetADecAttr();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetADecAttr failed");\r
-    }\r
-\r
-    if (hasVideo_) {\r
-        ret = SetVDecAttr();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetVDecAttr failed");\r
-    }\r
-\r
-    ret = SetStreamAttr();\r
-    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetStreamAttr failed");\r
-    return HI_SUCCESS;\r
-}\r
-\r
-#if !defined(UNSUPPORT_VIDEO_DECODER) || !defined(UNSUPPORT_AUDIO_DECODER)\r
-static AvCodecMime TransformCodecFormatToAvCodecMime(CodecFormat format)\r
-{\r
-    AvCodecMime mime = MEDIA_MIMETYPE_INVALID;\r
-    uint32_t size = sizeof(g_avCodecFormatInfo) / sizeof(CodecFormatAndMimePair);\r
-\r
-    for (uint32_t i = 0; i < size; i++) {\r
-        if (g_avCodecFormatInfo[i].format == format) {\r
-            mime = g_avCodecFormatInfo[i].mime;\r
-            break;\r
-        }\r
-    }\r
-\r
-    return mime;\r
-}\r
-#endif\r
-\r
-#ifndef UNSUPPORT_VIDEO_DECODER\r
-static void GetCurVideoSolution(const FormatFileInfo &info, uint32_t &width, uint32_t &height)\r
-{\r
-    for (int i = 0; i < HI_DEMUXER_RESOLUTION_CNT; i++) {\r
-        if (info.stSteamResolution[i].s32VideoStreamIndex == info.s32UsedVideoStreamIndex) {\r
-            width = info.stSteamResolution[i].u32Width;\r
-            height = info.stSteamResolution[i].u32Height;\r
-            break;\r
-        }\r
-    }\r
-}\r
-#endif\r
-\r
-#ifndef UNSUPPORT_AUDIO_DECODER\r
-static std::string GetAudioNameByAvCodecMime(AvCodecMime mime)\r
-{\r
-    std::string audioName = "codec.unknow.soft.decoder";\r
-    switch (mime) {\r
-        case MEDIA_MIMETYPE_AUDIO_AAC:\r
-            audioName = "codec.aac.soft.decoder";\r
-            break;\r
-        case MEDIA_MIMETYPE_AUDIO_MP3:\r
-            audioName = "codec.mp3.soft.decoder";\r
-            break;\r
-        default:\r
-            MEDIA_ERR_LOG("not support codec type:%d", mime);\r
-            break;\r
-    }\r
-    return audioName;\r
-}\r
-\r
-int32_t PlayerControl::AudioDecoderStart(void)\r
-{\r
-    AvCodecMime mime = TransformCodecFormatToAvCodecMime(fmtFileInfo_.enAudioType);\r
-    if (mime == MEDIA_MIMETYPE_INVALID) {\r
-        MEDIA_ERR_LOG("DecoderStart not support codec:%d", fmtFileInfo_.enAudioType);\r
-        return -1;\r
-    }\r
-    audioDecoder_ = std::make_shared<Decoder>();\r
-    CHECK_NULL_RETURN(audioDecoder_, -1, "new decoder failed");\r
-    AvAttribute attr;\r
-    attr.type = AUDIO_DECODER;\r
-    attr.adecAttr.mime = mime;\r
-    attr.adecAttr.priv = nullptr;\r
-    attr.adecAttr.bufSize = 0x400; /* 1024 */\r
-    attr.adecAttr.channelCnt = (mime == MEDIA_MIMETYPE_AUDIO_PCM) ? fmtFileInfo_.u32AudioChannelCnt : 0;\r
-    const std::string audioName = GetAudioNameByAvCodecMime(mime);\r
-    int32_t ret = audioDecoder_->CreateHandle(audioName, attr);\r
-    CHECK_FAILED_RETURN(ret, 0, -1, "create audio decoder failed");\r
-    ret = audioDecoder_->StartDec();\r
-    CHECK_FAILED_RETURN(ret, 0, -1, "start audio decoder failed");\r
-    MEDIA_INFO_LOG("audio decoder started");\r
-\r
-    return 0;\r
-}\r
-#endif\r
-\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-int32_t PlayerControl::VideoDecoderStart(void)\r
-{\r
-    AvAttribute attr;\r
-    uint32_t width = DECODER_DEFAULT_WIDTH;\r
-    uint32_t height = DECODER_DEFAULT_HEIGHT;\r
-\r
-    AvCodecMime mime = TransformCodecFormatToAvCodecMime(fmtFileInfo_.enVideoType);\r
-    if (mime == MEDIA_MIMETYPE_INVALID) {\r
-        MEDIA_ERR_LOG("DecoderStart not support codec:%d", fmtFileInfo_.enVideoType);\r
-        return -1;\r
-    }\r
-    GetCurVideoSolution(fmtFileInfo_, width, height);\r
-\r
-    videoDecoder_ = std::make_shared<Decoder>();\r
-    CHECK_NULL_RETURN(videoDecoder_, -1, "new decoder failed");\r
-    attr.type = VIDEO_DECODER;\r
-    attr.vdecAttr.mime = mime;\r
-    attr.vdecAttr.priv = nullptr;\r
-    attr.vdecAttr.bufSize = 0;\r
-    attr.vdecAttr.maxWidth = width;\r
-    attr.vdecAttr.maxHeight = height;\r
-    const std::string videoName = "codec.avc.soft.decoder";\r
-    int32_t ret = videoDecoder_->CreateHandle(videoName, attr);\r
-    CHECK_FAILED_RETURN(ret, 0, -1, "create video decoder failed");\r
-    ret = videoDecoder_->StartDec();\r
-    CHECK_FAILED_RETURN(ret, 0, -1, "start video decoder failed");\r
-    MEDIA_INFO_LOG("video decoder started");\r
-\r
-    return 0;\r
-}\r
-#endif\r
-\r
-int32_t PlayerControl::DecoderStart(void)\r
-{\r
-    if (!hasAudio_ && !hasVideo_) {\r
-        MEDIA_ERR_LOG("not decoder need start");\r
-        return -1;\r
-    }\r
-\r
-    MEDIA_INFO_LOG("audio stream id: %d, video stream id: %d", fmtFileInfo_.s32UsedAudioStreamIndex,\r
-        fmtFileInfo_.s32UsedVideoStreamIndex);\r
-\r
-    /* if offload audio is false, need audio decoder, not support */\r
-    if (hasAudio_) {\r
-        if (!offloadAudio_) {\r
-            MEDIA_ERR_LOG("not support offload, need audio decoder, return failed");\r
-            return -1;\r
-        }\r
-    }\r
-\r
-    if (hasVideo_) {\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-        if (VideoDecoderStart() != 0) {\r
-            return -1;\r
-        }\r
-#endif\r
-    }\r
-    return 0;\r
-}\r
-\r
-void PlayerControl::DestroyDecoder() const\r
-{\r
-#ifndef UNSUPPORT_AUDIO_DECODER\r
-    if (audioDecoder_ != nullptr) {\r
-        audioDecoder_->DestroyHandle();\r
-    }\r
-#endif\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-    if (videoDecoder_ != nullptr) {\r
-        videoDecoder_->DestroyHandle();\r
-    }\r
-#endif\r
-}\r
-\r
-void PlayerControl::StopSinkAndDecoder()\r
-{\r
-    OutputInfo outInfo = {};\r
-    EsFrameInfo frameInfo = {};\r
-    if (sinkManager_ != nullptr) {\r
-        sinkManager_->Stop();\r
-#ifdef UNSUPPORT_AUDIO_DECODER\r
-        while (sinkManager_->DequeReleaseEsFrame(true, frameInfo) == HI_SUCCESS) {\r
-        }\r
-#else\r
-        if (audioDecoder_ != nullptr) {\r
-            while (sinkManager_->DequeReleaseFrame(true, outInfo) == 0) {\r
-                audioDecoder_->QueueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);\r
-            }\r
-            audioDecoder_->StopDec();\r
-        }\r
-#endif\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-        if (videoDecoder_ != nullptr) {\r
-            while (sinkManager_->DequeReleaseFrame(false, outInfo) == 0) {\r
-                videoDecoder_->QueueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);\r
-            }\r
-            videoDecoder_->StopDec();\r
-        }\r
-#endif\r
-    }\r
-\r
-    isVideoStarted_ = false;\r
-    isAudioStarted_ = false;\r
-}\r
-\r
-int32_t PlayerControl::AddAudioSink(void)\r
-{\r
-    CHECK_TRUE_CONDITION_RETURN(isAudioStarted_, HI_SUCCESS, "already started");\r
-    SinkAttr attr;\r
-    attr.sinkType = SINK_TYPE_AUDIO;\r
-    attr.trackId = fmtFileInfo_.s32UsedAudioStreamIndex;\r
-    attr.audAttr.format = g_fromCodecFormatToAudioManager[fmtFileInfo_.enAudioType];\r
-    attr.audAttr.sampleRate = adecAttr_.sampleRate;\r
-    attr.audAttr.channel = fmtFileInfo_.u32AudioChannelCnt;\r
-    attr.audAttr.sessionID = audioSession_;\r
-    attr.audAttr.streamType = streamType_;\r
-    attr.audAttr.bitWidth = adecAttr_.bitWidth;\r
-    attr.audAttr.sampleFmt = fmtFileInfo_.sampleFmt;\r
-    MEDIA_INFO_LOG("AddAudioSink, format:%d, sampleRate:%d, channel:%d, session:%d, streamType:%d, bitWidth:%d",\r
-        attr.audAttr.format, attr.audAttr.sampleRate, attr.audAttr.channel, attr.audAttr.sessionID,\r
-        attr.audAttr.streamType, attr.audAttr.bitWidth);\r
-    if (sinkManager_->AddNewSink(attr) != 0) {\r
-        MEDIA_ERR_LOG("AddNewSink  failed");\r
-        return -1;\r
-    }\r
-    isAudioStarted_ = true;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::GetOffloadSupport(void)\r
-{\r
-    if (sinkManager_ == nullptr) {\r
-        MEDIA_ERR_LOG("sinkManager_ is invalid");\r
-        return -1;\r
-    }\r
-    AudioOffloadParam curOffloadInfo;\r
-    curOffloadInfo.streamType = streamType_;\r
-    curOffloadInfo.format = g_fromCodecFormatToAudioManager[fmtFileInfo_.enAudioType];\r
-    curOffloadInfo.sampleRate = adecAttr_.sampleRate;\r
-    curOffloadInfo.channel = fmtFileInfo_.u32AudioChannelCnt;\r
-    curOffloadInfo.bitWidth = 0;\r
-    MEDIA_INFO_LOG("GetOffloadSupport format:%d, audio:%d", curOffloadInfo.format, fmtFileInfo_.enAudioType);\r
-    offloadAudio_ = sinkManager_->IsOffloadSupported(curOffloadInfo);\r
-    MEDIA_INFO_LOG("%s audio offload", offloadAudio_ ? "supported" : "unsupported");\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::AddVideoSink()\r
-{\r
-    CHECK_TRUE_CONDITION_RETURN(isVideoStarted_, HI_SUCCESS, "already started");\r
-    SinkAttr attr;\r
-    attr.sinkType = SINK_TYPE_VIDEO;\r
-    attr.trackId = fmtFileInfo_.s32UsedVideoStreamIndex;\r
-    attr.vidAttr.width = fmtFileInfo_.u32Width;\r
-    attr.vidAttr.height = fmtFileInfo_.u32Height;\r
-    attr.vidAttr.frameRate = fmtFileInfo_.fFrameRate;\r
-    attr.vidAttr.format = fmtFileInfo_.enVideoType;\r
-    attr.vidAttr.surface = surface_;\r
-    if (sinkManager_->AddNewSink(attr) != 0) {\r
-        MEDIA_ERR_LOG("AddNewSink  failed");\r
-        return -1;\r
-    }\r
-    isVideoStarted_ = true;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::SinkStart(void)\r
-{\r
-    int32_t ret;\r
-    sinkManager_ = std::make_shared<SinkManager>();\r
-    CHECK_NULL_RETURN(sinkManager_, HI_FAILURE, "new sinkManager_ nullptr");\r
-    if (hasVideo_ && !isVideoStarted_) {\r
-        ret = AddVideoSink();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "AddVideoSink failed");\r
-        isVideoStarted_ = true;\r
-    }\r
-    if (hasAudio_ && !isAudioStarted_) {\r
-        ret = AddAudioSink();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "AddAudioSink failed");\r
-        isAudioStarted_ = true;\r
-    }\r
-\r
-    PlayEventCallback callback;\r
-    GetPlayElementEventCallBack(callback);\r
-    ret = sinkManager_->RegisterCallBack(callback);\r
-    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "RegisterCallBack failed");\r
-    /* get offload flag */\r
-    GetOffloadSupport();\r
-\r
-    if (metaData_.key == KEY_TYPE_EXTRADATA && hasAudio_) {\r
-        std::string key("extradata");\r
-        ret = sinkManager_->SetParam(key, DATA_TYPE_PTR, metaData_.value.pValue, metaData_.size);\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "sinkManager_ SetParam failed");\r
-    }\r
-\r
-    ret = sinkManager_->Start();\r
-    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "sinkManager_ Start failed");\r
-\r
-    if (leftVolume_ >= 0.0f || rightVolume_ >= 0.0f) {\r
-        sinkManager_->SetVolume(leftVolume_, rightVolume_);\r
-    }\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::ReadFrameFromSource(FormatFrame &fmtFrame)\r
-{\r
-    CHECK_NULL_RETURN(playerSource_, HI_ERR_PLAYERCONTROL_NULL_PTR, "playerSource_ nullptr");\r
-    int ret = playerSource_->ReadFrame(fmtFrame);\r
-    // Check consistency of fmtFrame\r
-    if ((ret == HI_SUCCESS) && (fmtFrame.data != nullptr) && (fmtFrame.len == 0)) {\r
-        MEDIA_ERR_LOG("ReadFrame ERROR : u32Size is invalid");\r
-        ret = HI_FAILURE;\r
-    }\r
-    return ret;\r
-}\r
-\r
-// message begin\r
-int32_t PlayerControl::DoRegCallback(const PlayerCtrlCallbackParam &eventCallback)\r
-{\r
-    if (eventCallback_.callbackFun != nullptr) {\r
-        MEDIA_WARNING_LOG("you have reg callback,now the before callback fun pointer will be overwrite");\r
-    }\r
-    eventCallback_ = eventCallback;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::DoSetDataSource(const char *filepath)\r
-{\r
-    filePath_ = std::string(filepath);\r
-    sourceType_ = SOURCE_TYPE_URI;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::DoSetDataSource(const SourceFdParam &fdSrc)\r
-{\r
-    fd_ = fdSrc.fd;\r
-    offset_ = fdSrc.offset;\r
-    sourceType_ = SOURCE_TYPE_FD;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::DoSetDataSource(const StreamSourceParam &streamSource)\r
-{\r
-    streamSource_ = streamSource;\r
-    sourceType_ = SOURCE_TYPE_STREAM;\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::DoPrepare(void)\r
-{\r
-    MEDIA_DEBUG_LOG("Process in");\r
-    CHECK_NULL_RETURN(eventCallback_.callbackFun, HI_ERR_PLAYERCONTROL_CALLBACK_ERROR, "callbackFun nullptr");\r
-    isPlayEnd_ = false;\r
-    int32_t ret = SyncPrepare();\r
-    CHECK_FAILED_RETURN(ret, HI_SUCCESS, HI_ERR_PLAYERCONTROL_OTHER, "SyncPrepare failed");\r
-    if (playerParam_.u32PlayPosNotifyIntervalMs >= fmtFileInfo_.s64Duration) {\r
-        MEDIA_WARNING_LOG("play postion notify interval %d ms oversize file duration, user will never receive notify",\r
-            playerParam_.u32PlayPosNotifyIntervalMs);\r
-    }\r
-    MEDIA_DEBUG_LOG("Process out");\r
-    return HI_SUCCESS;\r
-}\r
-\r
-#if !defined(UNSUPPORT_VIDEO_DECODER) || !defined(UNSUPPORT_AUDIO_DECODER)\r
-static void InitOutputBuffer(OutputInfo &outInfo, CodecType type)\r
-{\r
-    if (outInfo.buffers != nullptr) {\r
-        free(outInfo.buffers);\r
-        outInfo.buffers = nullptr;\r
-    }\r
-\r
-    outInfo.bufferCnt = 0;\r
-    outInfo.buffers = nullptr;\r
-    outInfo.timeStamp = -1;\r
-    outInfo.sequence = 0;\r
-    outInfo.flag = 0;\r
-    outInfo.type = type;\r
-    outInfo.vendorPrivate = nullptr;\r
-}\r
-#endif\r
-\r
-#ifndef UNSUPPORT_AUDIO_DECODER\r
-void PlayerControl::ReleaseADecoderOutputFrame(void)\r
-{\r
-    if (audioDecoder_ == nullptr || sinkManager_ == nullptr) {\r
-        return;\r
-    }\r
-    while (true) {\r
-        OutputInfo outInfo;\r
-        if (sinkManager_->DequeReleaseFrame(true, outInfo) != 0) {\r
-            break;\r
-        }\r
-        audioDecoder_->QueueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);\r
-    }\r
-}\r
-#endif\r
-\r
-void PlayerControl::ReleaseAudioSinkESFrame(void)\r
-{\r
-    CHECK_NULL_RETURN_NONE(sinkManager_, "sink manager is null");\r
-\r
-    EsFrameInfo outInfo = {};\r
-    while (sinkManager_->DequeReleaseEsFrame(true, outInfo) == HI_SUCCESS) {\r
-    }\r
-}\r
-\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-void PlayerControl::ReleaseVDecoderOutputFrame(void) const\r
-{\r
-    if (videoDecoder_ == nullptr || sinkManager_ == nullptr) {\r
-        return;\r
-    }\r
-    while (true) {\r
-        OutputInfo outInfo;\r
-        if (sinkManager_->DequeReleaseFrame(false, outInfo) != 0) {\r
-            break;\r
-        }\r
-    }\r
-}\r
-#endif\r
-\r
-void PlayerControl::ReportRenderPosition(void)\r
-{\r
-    int64_t position = -1;\r
-    CHECK_NULL_RETURN_NONE(sinkManager_, "sinkManager_ nullptr");\r
-    sinkManager_->GetRenderPosition(position);\r
-    if (position >= 0 && currentPosition_ != position) {\r
-        if (lastRendPos_ >= 0) {\r
-            currentPosition_ = position - lastRendPos_ + firstPosAfterSeek_;\r
-        } else {\r
-            currentPosition_ = position;\r
-        }\r
-        EventCallback(PLAYERCONTROL_EVENT_PROGRESS, &currentPosition_);\r
-    }\r
-}\r
-\r
-void PlayerControl::GetRenderFullSleepThresholdTime(AudioCodecFormat codecFormat)\r
-{\r
-#ifdef DEBUG_LOW_POWER\r
-    if (codecFormat == PCM) {\r
-        renderFullSleepThresholdMs_ = RENDER_FULL_SLEEP_THRESHOLD_MS_PCM;\r
-    } else if (codecFormat == MP3 || codecFormat == AAC_LC || codecFormat == OPUS) {\r
-        renderFullSleepThresholdMs_ = RENDER_FULL_SLEEP_THRESHOLD_MS_MP3_AACLC_OPUS;\r
-    } else if (codecFormat == FLAC) {\r
-        renderFullSleepThresholdMs_ = RENDER_FULL_SLEEP_THRESHOLD_MS_FLAC;\r
-    }\r
-#else\r
-    MEDIA_UNUSED(codecFormat);\r
-#endif\r
-}\r
-\r
-void PlayerControl::DataSchPreProcess(PlayerControl *play, bool *isContinue)\r
-{\r
-    if (play->hasRenderAudioEos_) {\r
-        int32_t info = PLAYERCONTROL_ERROR_AUD_PLAY_FAIL;\r
-        play->EventCallback(PLAYERCONTROL_EVENT_ERROR, &info);\r
-        MEDIA_ERR_LOG("player waiting for the EOS callback timed out.");\r
-    }\r
-    play->DoSeekIfNeed();\r
-\r
-    play->renderSleepTime_ = 0;\r
-\r
-    if (play->paused_) {\r
-        // blocking wait ensures that the system goes into deep sleep for reducing power consumption\r
-        MediaThreadCondWait(play->schCond_, play->schMutex_);\r
-        *isContinue = true;\r
-    }\r
-}\r
-\r
-void PlayerControl::DataSchPostProcess(PlayerControl *play)\r
-{\r
-    play->EventQueueProcess();\r
-\r
-    play->ReportRenderPosition();\r
-\r
-    play->PrintKpiTime();\r
-\r
-    // process pure video eos\r
-    if (play->hasVideo_ && !play->hasAudio_ && play->hasRenderVideoEos_) {\r
-        MEDIA_INFO_LOG("Received video play eos flag");\r
-        play->EventCallback(PLAYERCONTROL_EVENT_EOF, nullptr);\r
-    }\r
-\r
-    if (play->IsPlayEos()) {\r
-        play->renderSleepTime_ = RENDER_EOS_SLEEP_TIME_US;\r
-    }\r
-}\r
-\r
-#if !defined(UNSUPPORT_VIDEO_DECODER) || !defined(UNSUPPORT_AUDIO_DECODER)\r
-inline static bool IsValidPacket(FormatFrame &packet)\r
-{\r
-    return (packet.data != nullptr && packet.len != 0) ? true : false;\r
-}\r
-#endif\r
-\r
-int32_t PlayerControl::DequeueInputDataFromDemuxer(void)\r
-{\r
-    if (GetCurState() != PLAY_STATUS_PLAY) {\r
-        renderSleepTime_ = WAIT_MAIN_THREAD_SWITCH_TO_PLAY_STATUS_TIME_US;\r
-        return HI_FAILURE;\r
-    }\r
-\r
-    CHECK_TRUE_CONDITION_RETURN(strmReadEnd_, HI_SUCCESS, "read stream end");\r
-\r
-#ifdef PLAYER_KPI_ON\r
-    struct timeval readPacketStartTime;\r
-    RecordTime(readPacketStartTime);\r
-#endif\r
-\r
-    int32_t ret = ReadPacket();\r
-    if (ret == HI_RET_NODATA) {\r
-        renderSleepTime_ = NO_DATA_READ_SLEEP_TIME_US;\r
-        goto RE_SEND;\r
-    } else if (ret != HI_SUCCESS) {\r
-        goto RE_SEND;\r
-    }\r
-\r
-#ifdef PLAYER_KPI_ON\r
-    ReadPacketAvgCostTime(readPacketStartTime);\r
-#endif\r
-\r
-    if (formatPacket_.data == nullptr && formatPacket_.len == 0) {\r
-        strmReadEnd_ = true;\r
-        formatPacket_.timestampUs = -1;\r
-        gettimeofday(&streamEndTime_, nullptr);\r
-        if (loop_) {\r
-            seekToTimeMs_ = 0;\r
-            return HI_FAILURE;\r
-        }\r
-    }\r
-\r
-    isAudio_ = (formatPacket_.frameType == FRAME_TYPE_AUDIO) ? true : false;\r
-    isVideo_ = (formatPacket_.frameType == FRAME_TYPE_VIDEO) ? true : false;\r
-\r
-    return HI_SUCCESS;\r
-\r
-RE_SEND:\r
-    ClearCachePacket();\r
-    return ret;\r
-}\r
-\r
-int32_t PlayerControl::QueueInputDataToAudioSink(void)\r
-{\r
-    CHECK_NULL_RETURN(sinkManager_, HI_FAILURE, "sink manager is null");\r
-    CHECK_TRUE_CONDITION_RETURN(hasRenderAudioEos_, HI_FAILURE, "has render audio eos");\r
-\r
-    if (strmReadEnd_) {\r
-        sinkManager_->RenderEos(true);\r
-    } else {\r
-        CHECK_FALSE_CONDITION_RETURN(cachedPacket_, HI_FAILURE, "no cache packet");\r
-    }\r
-\r
-    EsFrameInfo outInfo = {};\r
-    FillAudioFrameInfo(outInfo);\r
-    int32_t ret = sinkManager_->RenderEsFrame(outInfo);\r
-    if (ret == SINK_RENDER_FULL || ret == SINK_RENDER_DELAY) {\r
-#ifdef DEBUG_LOW_POWER\r
-        static uint32_t renderSuccessCount = 0;\r
-        LowPowerProcess(outInfo.pts, renderSuccessCount, false);\r
-#else\r
-        if (ret == SINK_RENDER_FULL && fmtFileInfo_.s32UsedVideoStreamIndex < 0) {\r
-            renderSleepTime_ = WAIT_BUFFER_EMPTY_SLEEP_TIME_US;\r
-        } else {\r
-            renderSleepTime_ = RENDER_FULL_SLEEP_TIME_US;\r
-        }\r
-#endif\r
-        return ret;\r
-    } else {\r
-#ifdef DEBUG_LOW_POWER\r
-        LowPowerProcess(outInfo.pts, renderSuccessCount, true);\r
-#endif\r
-        renderSleepTime_ = 0;\r
-    }\r
-    ReleaseAudioSinkESFrame();\r
-    if (ret == SINK_RENDER_EOS) {\r
-        hasRenderAudioEos_ = true;\r
-        MEDIA_INFO_LOG("have render audio eos");\r
-        if (IsPlayEos()) {\r
-            isPlayEnd_ = true;\r
-        }\r
-    }\r
-    if (firstAudioFrameAfterSeek_) {\r
-        firstAudioFrameAfterSeek_ = false;\r
-        sinkManager_->GetRenderPosition(lastRendPos_);\r
-        firstPosAfterSeek_ = formatPacket_.timestampUs;\r
-        MEDIA_INFO_LOG("push firstAudioFrameAfterSeek_ success, pts:%lld", formatPacket_.timestampUs);\r
-    }\r
-    if (formatPacket_.data != nullptr || formatPacket_.len != 0) {\r
-        lastSendAdecPts_ = formatPacket_.timestampUs;\r
-    }\r
-    ClearCachePacket();\r
-    return ret;\r
-}\r
-\r
-#ifndef UNSUPPORT_AUDIO_DECODER\r
-void PlayerControl::QueueInputDataToAudioDecoder(void)\r
-{\r
-    CHECK_NULL_RETURN_NONE(audioDecoder_, "audio decoder is null");\r
-    CHECK_TRUE_CONDITION_RETURN_NONE(cachedPacket_, "no cache packet");\r
-\r
-    InputInfo inputData = { 0, nullptr, 0, 0 };\r
-    CodecBufferInfo inBufInfo = {};\r
-\r
-    int32_t ret = audioDecoder_->DequeInputBuffer(inputData, GET_BUFFER_TIMEOUT_MS);\r
-    CHECK_FAILED_RETURN_NONE(ret, HI_SUCCESS, "deque input buffer failed");\r
-\r
-    inBufInfo.addr = formatPacket_.data;\r
-    inBufInfo.length = formatPacket_.len;\r
-    inputData.bufferCnt = 1;\r
-    inputData.buffers = &inBufInfo;\r
-    inputData.pts = formatPacket_.timestampUs;\r
-    inputData.flag = 0;\r
-    ret = audioDecoder_->QueueInputBuffer(inputData, GET_BUFFER_TIMEOUT_MS);\r
-    if (ret == CODEC_ERR_STREAM_BUF_FULL) {\r
-        renderSleepTime_ = QUEUE_BUFFER_FULL_SLEEP_TIME_US;\r
-        return;\r
-    }\r
-    if (firstAudioFrameAfterSeek_ && IsValidPacket(formatPacket_)) {\r
-        firstAudioFrameAfterSeek_ = false;\r
-        MEDIA_INFO_LOG("push firstAudioFrameAfterSeek_ success, pts:%lld", inputData.pts);\r
-    }\r
-    if (formatPacket_.data != nullptr || formatPacket_.len != 0) {\r
-        lastSendAdecPts_ = formatPacket_.timestampUs;\r
-    }\r
-    ClearCachePacket();\r
-}\r
-\r
-void PlayerControl::DequeueOutputBufferAndRenderAudioFrame(void)\r
-{\r
-    CHECK_NULL_RETURN_NONE(audioDecoder_, "audio decoder is null");\r
-    CHECK_NULL_RETURN_NONE(sinkManager_, "sink manager is null");\r
-    CHECK_FAILED_RETURN_NONE(hasRenderAudioEos_, false, "has render audio eos");\r
-\r
-    OutputInfo outInfo = {};\r
-    int32_t ret = audioDecoder_->DequeueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);\r
-    if (ret != HI_SUCCESS) {\r
-        InitOutputBuffer(outInfo, AUDIO_DECODER);\r
-        if (ret == CODEC_RECEIVE_EOS && strmReadEnd_) {\r
-            // all frame have been send to audio sink\r
-            sinkManager_->RenderEos(true);\r
-        }\r
-    }\r
-\r
-    ret = sinkManager_->RenderFrame(outInfo);\r
-    if (ret == SINK_RENDER_FULL || ret == SINK_RENDER_DELAY) {\r
-        renderSleepTime_ = RENDER_FULL_SLEEP_TIME_US;\r
-    } else if (ret == SINK_QUE_EMPTY) {\r
-        renderSleepTime_ = 0;\r
-    }\r
-    ReleaseADecoderOutputFrame();\r
-    // all frame in frameCacheQue_ is processed\r
-    if (ret == SINK_RENDER_EOS) {\r
-        hasRenderAudioEos_ = true;\r
-        MEDIA_INFO_LOG("have render audio eos");\r
-        if (IsPlayEos()) {\r
-            isPlayEnd_ = true;\r
-        }\r
-    }\r
-}\r
-#endif\r
-\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-int32_t PlayerControl::QueueOutputBufferToVideoDecoder(void)\r
-{\r
-    CHECK_NULL_RETURN(surface_, HI_FAILURE, "surface is null");\r
-    CHECK_NULL_RETURN(sinkManager_, HI_FAILURE, "sink manager is null");\r
-    CHECK_NULL_RETURN(videoDecoder_, HI_FAILURE, "video decoder is null");\r
-\r
-    // 1. if video sink have cache, means have remain buffer not send to surface, don't need request buffer from surface\r
-    bool haveCache = sinkManager_->HaveCacheFrame(false);\r
-    if (haveCache) {\r
-        MEDIA_DEBUG_LOG("have cache frame skip this");\r
-        return HI_SUCCESS;\r
-    }\r
-\r
-    // 2. request video output buffer from surface\r
-#if defined(ENABLE_UIKIT)\r
-    surfaceBuf_ = surface_->RequestBuffer();\r
-#elif defined(ENABLE_LVGL)\r
-    surfaceBuf_ = LvRequestBuffer(reinterpret_cast<lv_obj_t *>(surface_), 0);\r
-#endif\r
-    if (surfaceBuf_ == nullptr) {\r
-        if (continousRequestSurfaceBufferFailCount_ == MAX_CONTINOUS_REQUEST_SURFACE_BUFFER_FAIL_COUNT) {\r
-            PalayControlEventItem item = { EVNET_VIDEO_RUNNING_ERR };\r
-            eventQueue_.push_back(item);\r
-            MEDIA_FATAL_LOG("continous request buffer fail count exceed upper limit");\r
-            return REQUEST_SURFACE_BUFFER_FATAL;\r
-        }\r
-        MEDIA_DEBUG_LOG("no free surface buffer retry");\r
-        renderSleepTime_ = REQUEST_BUFFER_RETRY_WAIT_TIME_US;\r
-        continousRequestSurfaceBufferFailCount_++;\r
-        return HI_FAILURE;\r
-    }\r
-    continousRequestSurfaceBufferFailCount_ = 0;\r
-\r
-    // 3. queue output buffer to video decoder\r
-    OutputInfo outInfo = {};\r
-    outInfo.type = VIDEO_DECODER;\r
-    outInfo.bufferCnt = 1;\r
-    outInfo.buffers = (CodecBufferInfo *)malloc(sizeof(CodecBufferInfo));\r
-    if (outInfo.buffers == nullptr) {\r
-        MEDIA_ERR_LOG("malloc failed");\r
-        return HI_FAILURE;\r
-    }\r
-    outInfo.buffers[0].type = BUFFER_TYPE_VIRTUAL;\r
-    outInfo.buffers[0].addr = reinterpret_cast<uint8_t *>(surfaceBuf_->addr);\r
-    outInfo.buffers[0].length = surfaceBuf_->width * surfaceBuf_->height * YCBCR420SP_BUFFER_SIZE_COEFFICIENT;\r
-    outInfo.vendorPrivate = surfaceBuf_;\r
-\r
-    int32_t ret = videoDecoder_->QueueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);\r
-    if (ret != HI_SUCCESS) {\r
-        free(outInfo.buffers);\r
-        MEDIA_ERR_LOG("queue output buffer to video decoder failed: 0x%x", ret);\r
-        return HI_FAILURE;\r
-    }\r
-\r
-    free(outInfo.buffers);\r
-    return HI_SUCCESS;\r
-}\r
-\r
-void PlayerControl::QueueInputDataToVideoDecoder(void)\r
-{\r
-    CHECK_NULL_RETURN_NONE(videoDecoder_, "video decoder is null");\r
-    CHECK_NULL_RETURN_NONE(sinkManager_, "sink manager is null");\r
-\r
-    bool haveCache = sinkManager_->HaveCacheFrame(false);\r
-    if (haveCache) {\r
-        MEDIA_DEBUG_LOG("have cache frame skip this");\r
-        return;\r
-    }\r
-\r
-    if (!strmReadEnd_) {\r
-        CHECK_FALSE_CONDITION_RETURN_NONE(cachedPacket_, "no cache packet");\r
-    }\r
-\r
-    InputInfo inputData = { 0, nullptr, 0, 0 };\r
-    CodecBufferInfo inBufInfo = {};\r
-\r
-    int32_t ret = videoDecoder_->DequeInputBuffer(inputData, GET_BUFFER_TIMEOUT_MS);\r
-    CHECK_FAILED_RETURN_NONE(ret, HI_SUCCESS, "deque input buffer failed");\r
-\r
-    MEDIA_DEBUG_LOG("queue input buffer len: %u, pts: %lld", formatPacket_.len, formatPacket_.timestampUs);\r
-\r
-    inBufInfo.addr = formatPacket_.data;\r
-    inBufInfo.length = formatPacket_.len;\r
-    inputData.bufferCnt = 1;\r
-    inputData.buffers = &inBufInfo;\r
-    inputData.pts = formatPacket_.timestampUs;\r
-    inputData.flag = (formatPacket_.data == nullptr && formatPacket_.len == 0) ? STREAM_FLAG_EOS : 0;\r
-    ret = videoDecoder_->QueueInputBuffer(inputData, GET_BUFFER_TIMEOUT_MS);\r
-    if (ret == CODEC_ERR_STREAM_BUF_FULL) {\r
-        renderSleepTime_ = QUEUE_BUFFER_FULL_SLEEP_TIME_US;\r
-        return;\r
-    }\r
-    if (firstVideoFrameAfterSeek_ && IsValidPacket(formatPacket_)) {\r
-        firstVideoFrameAfterSeek_ = false;\r
-        MEDIA_INFO_LOG("push firstVideoFrameAfterSeek_ success, pts:%lld", inputData.pts);\r
-    }\r
-    if (formatPacket_.data != nullptr && formatPacket_.len != 0) {\r
-        lastSendVdecPts_ = formatPacket_.timestampUs;\r
-    }\r
-    ClearCachePacket();\r
-}\r
-\r
-void PlayerControl::DequeueOutputBufferAndRenderVideoFrame(void)\r
-{\r
-    CHECK_NULL_RETURN_NONE(videoDecoder_, "video decoder is null");\r
-    CHECK_NULL_RETURN_NONE(sinkManager_, "sink manager is null");\r
-    CHECK_TRUE_CONDITION_RETURN_NONE(hasRenderVideoEos_, "has render video eos");\r
-\r
-    OutputInfo outInfo = {};\r
-    outInfo.buffers = (CodecBufferInfo *)malloc(sizeof(CodecBufferInfo));\r
-    if (outInfo.buffers == nullptr) {\r
-        MEDIA_ERR_LOG("malloc failed");\r
-        return;\r
-    }\r
-    int ret = videoDecoder_->DequeueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);\r
-    if (ret != 0) {\r
-        InitOutputBuffer(outInfo, VIDEO_DECODER);\r
-        if (surface_ != nullptr) {\r
-#if defined(ENABLE_UIKIT)\r
-            surface_->CancelBuffer(surfaceBuf_);\r
-#elif defined(ENABLE_LVGL)\r
-            LvCancelBuffer(reinterpret_cast<lv_obj_t *>(surface_), surfaceBuf_);\r
-#endif\r
-        }\r
-        if (ret == CODEC_RECEIVE_EOS) {\r
-            sinkManager_->RenderEos(false); /* all frame have been send to video sink */\r
-        } else {\r
-            goto EXIT;\r
-        }\r
-    }\r
-\r
-    ret = sinkManager_->RenderFrame(outInfo);\r
-    if (ret == SINK_RENDER_FULL || ret == SINK_RENDER_DELAY) {\r
-        renderSleepTime_ = RENDER_FULL_SLEEP_TIME_US;\r
-    } else if (ret == SINK_QUE_EMPTY) {\r
-        renderSleepTime_ = 0;\r
-    }\r
-EXIT:\r
-    ReleaseVDecoderOutputFrame();\r
-    /* fuction RenderFrame will return SINK_RENDER_EOS when all frame in queue that have been processed */\r
-    if (ret == SINK_RENDER_EOS) {\r
-        hasRenderVideoEos_ = true;\r
-        MEDIA_INFO_LOG("have render video eos");\r
-        if (IsPlayEos()) {\r
-            isPlayEnd_ = true;\r
-        }\r
-    }\r
-\r
-    if (outInfo.buffers != nullptr) {\r
-        free(outInfo.buffers);\r
-    }\r
-    return;\r
-}\r
-#endif\r
-\r
-int32_t PlayerControl::DealWithInputEos(bool hasAudio, bool hasVideo)\r
-{\r
-    if (hasAudio) {\r
-#ifdef UNSUPPORT_AUDIO_DECODER\r
-        QueueInputDataToAudioSink();\r
-#else\r
-        QueueInputDataToAudioDecoder();\r
-        DequeueOutputBufferAndRenderAudioFrame();\r
-#endif\r
-    }\r
-\r
-    if (hasVideo) {\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-        int32_t ret = QueueOutputBufferToVideoDecoder();\r
-        if (ret != HI_SUCCESS) {\r
-            return ret;\r
-        }\r
-        QueueInputDataToVideoDecoder();\r
-        DequeueOutputBufferAndRenderVideoFrame();\r
-#endif\r
-    }\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::ProcessInputData(bool isAudio, bool isVideo)\r
-{\r
-    if (isAudio) {\r
-#ifdef UNSUPPORT_AUDIO_DECODER\r
-        return QueueInputDataToAudioSink();\r
-#else\r
-        QueueInputDataToAudioDecoder();\r
-        DequeueOutputBufferAndRenderAudioFrame();\r
-#endif\r
-    } else if (isVideo) {\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-        int32_t retValue = QueueOutputBufferToVideoDecoder();\r
-        if (retValue != HI_SUCCESS) {\r
-            return retValue;\r
-        }\r
-        QueueInputDataToVideoDecoder();\r
-        DequeueOutputBufferAndRenderVideoFrame();\r
-#endif\r
-    }\r
-    return HI_SUCCESS;\r
-}\r
-\r
-void *PlayerControl::DataSchProcess(void *priv)\r
-{\r
-    CHECK_NULL_RETURN(priv, nullptr, "priv is null");\r
-\r
-    PlayerControl *play = (PlayerControl *)priv;\r
-\r
-#ifdef SUPPORT_SYS_PRCTL\r
-    prctl(PR_SET_NAME, "PlaySch", 0, 0, 0);\r
-#endif\r
-\r
-    MEDIA_INFO_LOG("start work");\r
-\r
-    // for low power\r
-    play->GetRenderFullSleepThresholdTime(g_fromCodecFormatToAudioManager[play->fmtFileInfo_.enAudioType]);\r
-\r
-    int32_t ret = HI_FAILURE;\r
-    while (true) {\r
-        MediaMutexLock(play->schMutex_);\r
-        if (play->schThreadExit_) {\r
-            MediaMutexUnLock(play->schMutex_);\r
-            break;\r
-        }\r
-\r
-        bool isContinue = false;\r
-        DataSchPreProcess(play, &isContinue);\r
-        if (isContinue) {\r
-            goto CONTINUE;\r
-        }\r
-\r
-        if (play->DequeueInputDataFromDemuxer() != HI_SUCCESS) {\r
-            goto CONTINUE;\r
-        }\r
-\r
-        if (play->strmReadEnd_) {\r
-            ret = play->DealWithInputEos(play->hasAudio_, play->hasVideo_);\r
-        } else {\r
-            ret = play->ProcessInputData(play->isAudio_, play->isVideo_);\r
-        }\r
-\r
-        if (ret == SINK_RENDER_FATEL || ret == REQUEST_SURFACE_BUFFER_FATAL) {\r
-            play->EventQueueProcess();\r
-            MediaMutexUnLock(play->schMutex_);\r
-            break;\r
-        } else if (ret != HI_SUCCESS) {\r
-            goto CONTINUE;\r
-        }\r
-\r
-        DataSchPostProcess(play);\r
-\r
-    CONTINUE:\r
-        if (play->renderSleepTime_ > 0) {\r
-            MediaThreadCondTimeWait(play->schCond_, play->schMutex_, play->renderSleepTime_);\r
-        }\r
-        MediaMutexUnLock(play->schMutex_);\r
-    }\r
-\r
-    MediaMutexLock(play->schMutex_);\r
-    play->schThreadExit_ = true;\r
-    MediaMutexUnLock(play->schMutex_);\r
-\r
-    MEDIA_INFO_LOG("end work");\r
-    return nullptr;\r
-}\r
-\r
-int32_t PlayerControl::DoPlay()\r
-{\r
-    MEDIA_DEBUG_LOG("Process in");\r
-    CHECK_NULL_RETURN(playerSource_, HI_ERR_PLAYERCONTROL_NULL_PTR, "playerSource_ nullptr");\r
-\r
-    int32_t ret = HI_SUCCESS;\r
-    PlayerStatus playerState = GetCurState();\r
-    CHECK_STATE_SAME_RETURN(playerState, PLAY_STATUS_PLAY, "state same");\r
-    if (playerState == PLAY_STATUS_PREPARED) {\r
-        ret = CheckMediaInfo();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "CheckMediaInfo failed");\r
-        ret = SetDecoderAndStreamAttr();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetDecoderAndStreamAttr failed");\r
-        ret = SinkStart();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SinkStart failed");\r
-        ret = DecoderStart();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "DecoderStart failed");\r
-        ret = playerSource_->Start();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "playerSource_ Start failed");\r
-        MediaMutexLock(schMutex_);\r
-        paused_ = true;\r
-        MediaThreadattr attr = { "PlaySch", MAX_THREAD_STACK_SIZE, THREAD_SCHED_INVALID, 80, false };\r
-        schProcess_ = MediaThreadCreate(DataSchProcess, this, &attr);\r
-        if (schProcess_ == nullptr) {\r
-            MEDIA_ERR_LOG("thread create failed %d", ret);\r
-            schThreadExit_ = false;\r
-            MediaMutexUnLock(schMutex_);\r
-            return -1;\r
-        }\r
-        paused_ = false;\r
-        MediaMutexUnLock(schMutex_);\r
-    } else if (playerState == PLAY_STATUS_PAUSE) {\r
-        ret = PauseResume();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "PauseResume failed");\r
-    } else {\r
-        return HI_ERR_PLAYERCONTROL_ILLEGAL_STATE_ACTION;\r
-    }\r
-    return ret;\r
-}\r
-\r
-int32_t PlayerControl::DoSetVolume(const VolumeAttr &volumeAttr)\r
-{\r
-    leftVolume_ = volumeAttr.leftVolume;\r
-    rightVolume_ = volumeAttr.rightVolume;\r
-    CHECK_NULL_RETURN(sinkManager_, HI_SUCCESS, "sinkManager_ nullptr, it will be setted after play");\r
-    return sinkManager_->SetVolume(volumeAttr.leftVolume, volumeAttr.rightVolume);\r
-}\r
-\r
-int32_t PlayerControl::ReadPacket()\r
-{\r
-    int32_t ret = HI_SUCCESS;\r
-    if (cachedPacket_) {\r
-        return ret;\r
-    }\r
-    ret = ReadFrameFromSource(formatPacket_);\r
-    if (ret != HI_RET_FILE_EOF && formatPacket_.data == nullptr && formatPacket_.len == 0) {\r
-        return HI_RET_NODATA;\r
-    }\r
-    if (ret == HI_RET_FILE_EOF) {\r
-        CHECK_FAILED_RETURN(memset_s(&formatPacket_, sizeof(formatPacket_), 0, sizeof(FormatFrame)), EOK, -1,\r
-            "memset_s failed");\r
-        ret = HI_SUCCESS;\r
-    } else if (ret == HI_RET_NODATA) {\r
-        CHECK_FAILED_RETURN(memset_s(&formatPacket_, sizeof(formatPacket_), 0, sizeof(FormatFrame)), EOK, -1,\r
-            "memset_s failed");\r
-        strmReadEnd_ = false;\r
-        return ret;\r
-    } else if (ret != HI_SUCCESS) {\r
-        MEDIA_ERR_LOG("ReadFrameFromSource failed , ret:%d", ret);\r
-        NotifyError(PLAYERCONTROL_ERROR_DEMUX_FAIL);\r
-        return HI_FAILURE;\r
-    }\r
-    strmReadEnd_ = false;\r
-    cachedPacket_ = true;\r
-    return ret;\r
-}\r
-\r
-#ifdef PLAYER_KPI_ON\r
-void PlayerControl::PrintRenderEsTime(const struct timeval &esFrameStartTime)\r
-{\r
-    std::string renderEsFrame("KPI_PlayerRenderEsFrame");\r
-    struct timeval esFrameEndTime = {};\r
-    uint64_t renderEsOnceTime = CalcTimeDiffUsPrint(esFrameStartTime, esFrameEndTime, renderEsFrame, false);\r
-    if (renderEsOnceTime != INVALID_TIME) {\r
-        renderEsTotalTime_ += renderEsOnceTime;\r
-        renderEsFrameCnt_++;\r
-    }\r
-    if (renderEsFrameCnt_ == 500) { /* 500:Print Interval */\r
-        MEDIA_INFO_LOG("KPI_PlayerRenderEsFrame avg time: %lld us", renderEsTotalTime_ /= renderEsFrameCnt_);\r
-        renderEsTotalTime_ = 0;\r
-        renderEsFrameCnt_ = 0;\r
-    }\r
-}\r
-#endif\r
-\r
-void PlayerControl::FillAudioFrameInfo(EsFrameInfo &outInfo)\r
-{\r
-    if (memset_s(&outInfo, sizeof(outInfo), 0, sizeof(EsFrameInfo)) != EOK) {\r
-        return;\r
-    }\r
-\r
-    outInfo.addr = formatPacket_.data;\r
-    outInfo.size = formatPacket_.len;\r
-    outInfo.pts = formatPacket_.timestampUs;\r
-    outInfo.flag = 0;\r
-    EsFrameType frameType = g_fromDemuxTypeToSinkType[formatPacket_.frameType];\r
-    outInfo.type = (frameType == ESFRAME_TYPE_NONE) ? ESFRAME_TYPE_AUDIO : frameType;\r
-}\r
-\r
-#ifdef DEBUG_LOW_POWER\r
-void PlayerControl::LowPowerProcess(int64_t pts, uint32_t &renderSuccessCount, bool renderFrameSuccess)\r
-{\r
-    if (renderFrameSuccess) {\r
-        if (headInSendSuccessInterval_ == -1) {\r
-            headInSendSuccessInterval_ = pts;\r
-            tailInSendSuccessInterval_ = -1;\r
-        }\r
-        renderSuccessCount++;\r
-    } else {\r
-        if (tailInSendSuccessInterval_ == -1) {\r
-            tailInSendSuccessInterval_ = pts;\r
-            int64_t diffMs = tailInSendSuccessInterval_ - headInSendSuccessInterval_ - renderFullSleepThresholdMs_;\r
-            renderSleepTime_ = (diffMs > 0) ? (diffMs * US_2_MS) : RENDER_FULL_SLEEP_TIME_US;\r
-        }\r
-\r
-        /* MEAIA_XXX_LOG have performance problem, use printf instead */\r
-        printf("render %d audio frames, from %lldms to %lldms, thread wait %ums\n", renderSuccessCount,\r
-            tailInSendSuccessInterval_, headInSendSuccessInterval_, renderSleepTime_ / US_2_MS);\r
-\r
-        headInSendSuccessInterval_ = -1;\r
-        renderSuccessCount = 0;\r
-    }\r
-}\r
-#endif\r
-\r
-#ifdef PLAYER_KPI_ON\r
-void PlayerControl::ReadPacketAvgCostTime(const struct timeval &readPacketStartTime)\r
-{\r
-    struct timeval readPacketEndTime;\r
-    std::string readPacketCost("KPI_Player_demux_cost_time");\r
-    uint64_t readPktOnceTime = CalcTimeDiffUsPrint(readPacketStartTime, readPacketEndTime, readPacketCost, false);\r
-    if (readPktOnceTime != INVALID_TIME) {\r
-        readPktTotalTime_ += readPktOnceTime;\r
-        readPacketCnt_++;\r
-    }\r
-    if (readPacketCnt_ == 500) { /* 500:Print Interval */\r
-        MEDIA_INFO_LOG("KPI_Player_demux_cost_time avg time: %lld us", readPktTotalTime_ /= readPacketCnt_);\r
-        readPktTotalTime_ = 0;\r
-        readPacketCnt_ = 0;\r
-    }\r
-}\r
-#endif\r
-\r
-int32_t PlayerControl::DoStop()\r
-{\r
-    int32_t ret = HI_SUCCESS;\r
-    PlayerStatus playerState = GetCurState();\r
-    CHECK_STATE_SAME_RETURN(playerState, PLAY_STATUS_IDLE, "state same");\r
-\r
-    if (schProcess_ != nullptr) {\r
-        MediaMutexLock(schMutex_);\r
-        schThreadExit_ = true;\r
-        MediaThreadCondSignal(schCond_);\r
-        MediaMutexUnLock(schMutex_);\r
-        MediaThreadJoin(&schProcess_);\r
-    }\r
-    StopSinkAndDecoder();\r
-    ClearCachePacket();\r
-    if (playerSource_ != nullptr) {\r
-        ret = playerSource_->Stop();\r
-        CHECK_FAILED_PRINT(ret, HI_SUCCESS, "playerSource_ stop failed");\r
-    }\r
-    isPlayEnd_ = false;\r
-    strmReadEnd_ = false;\r
-    isPlayErr_ = false;\r
-    lastRendPos_ = 0;\r
-    lastReadPktPts_ = 0;\r
-    lastSendPktPts_ = 0;\r
-    isAudPlayEos_ = false;\r
-    hasRenderAudioEos_ = false;\r
-    hasRenderAudioEos_ = false;\r
-    lastNotifyTime_ = 0;\r
-    seekToTimeMs_ = -1;\r
-    if (memset_s(&(fmtFileInfo_), sizeof(fmtFileInfo_), 0, sizeof(FormatFileInfo)) != EOK) {\r
-        MEDIA_ERR_LOG("memset_s failed");\r
-        return HI_ERR_PLAYERCONTROL_MEM_SET;\r
-    }\r
-    return ret;\r
-}\r
-\r
-int32_t PlayerControl::DoPause(void)\r
-{\r
-    PlayerStatus playerState = GetCurState();\r
-    CHECK_STATE_SAME_RETURN(playerState, PLAY_STATUS_PAUSE, "state same");\r
-    CHECK_NULL_RETURN(sinkManager_, HI_FAILURE, "sinkManager_ nullptr");\r
-\r
-    if (playerState == PLAY_STATUS_PLAY) {\r
-        MediaMutexLock(schMutex_);\r
-        int32_t ret = sinkManager_->Pause();\r
-        CHECK_FAILED_PRINT(ret, 0, "sinkManager_ pause failed:%d");\r
-        paused_ = true;\r
-        MediaMutexUnLock(schMutex_);\r
-    } else {\r
-        return HI_ERR_PLAYERCONTROL_ILLEGAL_STATE_ACTION;\r
-    }\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::DoSeekIfNeed(void)\r
-{\r
-    if (seekToTimeMs_ == -1) {\r
-        return HI_SUCCESS;\r
-    }\r
-    MEDIA_INFO_LOG("seek start");\r
-    int32_t ret = AyncSeek(seekToTimeMs_);\r
-    if (ret != HI_SUCCESS) {\r
-        MEDIA_ERR_LOG(" AyncSeek  failed , ret:%d", ret);\r
-        NotifyError(PLAYERCONTROL_ERROR_AUD_PLAY_FAIL);\r
-        return ret;\r
-    }\r
-    strmReadEnd_ = false;\r
-    isAudPlayEos_ = false;\r
-    isVidPlayEos_ = false;\r
-    hasRenderVideoEos_ = false;\r
-    hasRenderAudioEos_ = false;\r
-    isPlayEnd_ = false;\r
-    seekToTimeMs_ = -1;\r
-    firstAudioFrameAfterSeek_ = true;\r
-    firstVideoFrameAfterSeek_ = true;\r
-    MEDIA_INFO_LOG("seek end");\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::DoSeek(int64_t timeInMs)\r
-{\r
-    seekToTimeMs_ = timeInMs;\r
-    return DoSeekIfNeed();\r
-}\r
-\r
-int32_t PlayerControl::DoGetFileInfo(FormatFileInfo &fileInfo) const\r
-{\r
-    return memcpy_s(&fileInfo, sizeof(FormatFileInfo), &fmtFileInfo_, sizeof(fmtFileInfo_));\r
-}\r
-\r
-int32_t PlayerControl::DoSetMedia(const PlayerControlStreamAttr &mediaAttr)\r
-{\r
-    CHECK_NULL_RETURN(playerSource_, HI_ERR_PLAYERCONTROL_NULL_PTR, "playerSource_ nullptr");\r
-\r
-    int32_t ret = HI_SUCCESS;\r
-    if (hasVideo_) {\r
-        ret = playerSource_->SelectTrack(0, mediaAttr.s32VidStreamId);\r
-        CHECK_FAILED_RETURN(ret, 0, HI_ERR_PLAYERCONTROL_DEMUX_ERROR, "select video track failed");\r
-    }\r
-    if (hasAudio_) {\r
-        ret = playerSource_->SelectTrack(0, mediaAttr.s32AudStreamId);\r
-        CHECK_FAILED_RETURN(ret, 0, HI_ERR_PLAYERCONTROL_DEMUX_ERROR, "select audio track failed");\r
-    }\r
-\r
-    fmtFileInfo_.s32UsedVideoStreamIndex = mediaAttr.s32VidStreamId;\r
-    fmtFileInfo_.s32UsedAudioStreamIndex = mediaAttr.s32AudStreamId;\r
-\r
-    hasAudio_ = (fmtFileInfo_.s32UsedAudioStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) ? true : false;\r
-    hasVideo_ = (fmtFileInfo_.s32UsedVideoStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) ? true : false;\r
-\r
-    return ret;\r
-}\r
-\r
-int32_t PlayerControl::DoSetPlaybackSpeed(float speed) const\r
-{\r
-    MediaMutexLock(schMutex_);\r
-    int ret = sinkManager_->SetSpeed(speed);\r
-    if (ret != HI_SUCCESS) {\r
-        MEDIA_ERR_LOG("DoSetPlaybackSpeed failed:%d", ret);\r
-    }\r
-    MediaMutexUnLock(schMutex_);\r
-    return HI_SUCCESS;\r
-}\r
-\r
-void PlayerControl::RecordLastPosition()\r
-{\r
-    sinkManager_->RecordLastPosition();\r
-}\r
-\r
-// util bigein\r
-void PlayerControl::EventCallback(PlayerControlEvent event, const void *data) const\r
-{\r
-    CHECK_NULL_RETURN_NONE(eventCallback_.callbackFun, "callbackFun nullptr");\r
-    eventCallback_.callbackFun(eventCallback_.player, event, data);\r
-}\r
-\r
-void PlayerControl::PlayerControlCondSignal(void)\r
-{\r
-    if (fmtFileInfo_.s32UsedVideoStreamIndex < 0) {\r
-        MediaThreadCondSignal(schCond_);\r
-    }\r
-}\r
-\r
-void PlayerControl::EnableSingleLooping(bool loop)\r
-{\r
-    MediaMutexLock(schMutex_);\r
-    loop_ = loop;\r
-    MediaMutexUnLock(schMutex_);\r
-}\r
-\r
-int32_t PlayerControl::SetParam(const std::string &key, const void *value, uint32_t len)\r
-{\r
-    CHECK_NULL_RETURN(sinkManager_, HI_ERR_PLAYERCONTROL_NULL_PTR, "sinkManager_ nullptr");\r
-    MediaMutexLock(schMutex_);\r
-    int32_t ret = sinkManager_->SetParam(key, DATA_TYPE_STRING, value, len);\r
-    if (ret != HI_SUCCESS) {\r
-        MediaMutexUnLock(schMutex_);\r
-        return ret;\r
-    }\r
-    MediaMutexUnLock(schMutex_);\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::GetParam(const std::string &key, void *value, uint32_t size)\r
-{\r
-    CHECK_NULL_RETURN(sinkManager_, HI_ERR_PLAYERCONTROL_NULL_PTR, "sinkManager_ nullptr");\r
-    MediaMutexLock(schMutex_);\r
-    int32_t ret = sinkManager_->GetParam(key, DATA_TYPE_PTR, value, size);\r
-    if (ret != HI_SUCCESS) {\r
-        MediaMutexUnLock(schMutex_);\r
-        return ret;\r
-    }\r
-    MediaMutexUnLock(schMutex_);\r
-    return HI_SUCCESS;\r
-}\r
-\r
-void PlayerControl::NotifyError(PlayerControlError playerError) const\r
-{\r
-    EventCallback(PLAYERCONTROL_EVENT_ERROR, static_cast<void *>(&playerError));\r
-}\r
-\r
-void PlayerControl::StateChangeCallback(PlayerStatus state) const\r
-{\r
-    EventCallback(PLAYERCONTROL_EVENT_STATE_CHANGED, static_cast<void *>(&state));\r
-}\r
-\r
-void PlayerControl::FlushDecoder(void) const\r
-{\r
-#ifndef UNSUPPORT_AUDIO_DECODER\r
-    ReleaseADecoderOutputFrame();\r
-    if (audioDecoder_ != nullptr) {\r
-        audioDecoder_->FlushDec();\r
-    }\r
-#endif\r
-\r
-#if !defined(UNSUPPORT_VIDEO_DECODER)\r
-    ReleaseVDecoderOutputFrame();\r
-    if (videoDecoder_ != nullptr) {\r
-        videoDecoder_->FlushDec();\r
-    }\r
-#endif\r
-}\r
-\r
-int32_t PlayerControl::DecoderAndSinkReset(void)\r
-{\r
-    if (strmReadEnd_ && loop_) {\r
-        return HI_SUCCESS;\r
-    }\r
-    int32_t ret;\r
-    bool isNeedResume = false;\r
-    ret = sinkManager_->Pause();\r
-    if ((ret == HI_SUCCESS) && (!paused_)) {\r
-        isNeedResume = true;\r
-    }\r
-    ret = sinkManager_->Reset();\r
-    if (ret != HI_SUCCESS) {\r
-        MEDIA_ERR_LOG("m_render reset failed");\r
-        (void)sinkManager_->Resume();\r
-        return ret;\r
-    }\r
-    FlushDecoder();\r
-    if (isNeedResume) {\r
-        ret = sinkManager_->Resume();\r
-        CHECK_FAILED_RETURN(ret, HI_SUCCESS, HI_FAILURE, "sinkManager_ Resume failed");\r
-    }\r
-    return HI_SUCCESS;\r
-}\r
-\r
-int32_t PlayerControl::AyncSeek(int64_t seekTime)\r
-{\r
-    CHECK_NULL_RETURN(playerSource_, HI_FAILURE, "playerSource_ nullptr");\r
-    int64_t seekTimeInMs = seekTime;\r
-    int32_t ret = 0;\r
-    ClearCachePacket();\r
-    if (fmtFileInfo_.s32UsedVideoStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) {\r
-        ret = playerSource_->Seek(fmtFileInfo_.s32UsedVideoStreamIndex, seekTimeInMs, FORMAT_SEEK_MODE_BACKWARD_KEY);\r
-        if (ret != HI_SUCCESS) {\r
-            MEDIA_INFO_LOG("exec fmt_seek video stream failed, ret:%d", ret);\r
-            seekTimeInMs = currentPosition_;\r
-        }\r
-    }\r
-    if (fmtFileInfo_.s32UsedAudioStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) {\r
-        ret = playerSource_->Seek(fmtFileInfo_.s32UsedAudioStreamIndex, seekTimeInMs, FORMAT_SEEK_MODE_BACKWARD_KEY);\r
-        if (ret != HI_SUCCESS) {\r
-            MEDIA_INFO_LOG("exec fmt_seek audio stream failed, ret:%d", ret);\r
-            seekTimeInMs = currentPosition_;\r
-        }\r
-    }\r
-    currentPosition_ = seekTimeInMs;\r
-    EventCallback(PLAYERCONTROL_EVENT_PROGRESS, &currentPosition_);\r
-    EventCallback(PLAYERCONTROL_EVENT_SEEK_END, static_cast<void *>(&seekTimeInMs));\r
-    return HI_SUCCESS;\r
-}\r
-\r
-void PlayerControl::GetPlayElementEventCallBack(PlayEventCallback &callback)\r
-{\r
-    callback.onEventCallback = PlayerControlOnEvent;\r
-    callback.priv = static_cast<void *>(this);\r
-}\r
-int32_t PlayerControl::SyncPrepare()\r
-{\r
-    int ret;\r
-    playerSource_ = std::make_shared<PlayerSource>();\r
-    CHECK_NULL_RETURN(playerSource_, HI_FAILURE, "new playerSource_ nullptr");\r
-    playerSource_->Init();\r
-\r
-    if (sourceType_ == SOURCE_TYPE_FD) {\r
-        playerSource_->SetSource(fd_, offset_);\r
-    } else if (sourceType_ == SOURCE_TYPE_STREAM) {\r
-        playerSource_->SetSource(streamSource_);\r
-    } else {\r
-        playerSource_->SetSource(filePath_.c_str());\r
-    }\r
-\r
-    PlayEventCallback callback;\r
-    GetPlayElementEventCallBack(callback);\r
-    ret = playerSource_->SetCallBack(callback);\r
-    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetCallBack failed");\r
-\r
-    ret = playerSource_->Prepare();\r
-    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "Prepare failed");\r
-    ret = playerSource_->GetFileInfo(fmtFileInfo_);\r
-    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "GetFileInfo failed");\r
-    metaData_.key = KEY_TYPE_EXTRADATA;\r
-    ret = playerSource_->GetParam(0, metaData_);\r
-    if (ret != HI_SUCCESS) {\r
-        MEDIA_INFO_LOG("no extradata metadata");\r
-        metaData_.key = 0;\r
-    }\r
-\r
-    hasAudio_ = (fmtFileInfo_.s32UsedAudioStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) ? true : false;\r
-    hasVideo_ = (fmtFileInfo_.s32UsedVideoStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) ? true : false;\r
-\r
-    MEDIA_INFO_LOG("used audiostream index %d", fmtFileInfo_.s32UsedAudioStreamIndex);\r
-    MEDIA_INFO_LOG("used videostream index %d", fmtFileInfo_.s32UsedVideoStreamIndex);\r
-\r
-    return HI_SUCCESS;\r
-}\r
-\r
-bool PlayerControl::IsPlayEos() const\r
-{\r
-    bool isEos = false;\r
-    if (hasAudio_) {\r
-        if (hasVideo_) {\r
-            return (!isAudioStarted_ || hasRenderAudioEos_) && (!isVideoStarted_ || hasRenderVideoEos_);\r
-        } else {\r
-            return (!isAudioStarted_ || hasRenderAudioEos_);\r
-        }\r
-    } else {\r
-        if (hasVideo_) {\r
-            return (!isVideoStarted_ || hasRenderVideoEos_);\r
-        } else {\r
-            MEDIA_ERR_LOG("neither audio nor video");\r
-            isEos = false;\r
-        }\r
-    }\r
-\r
-    return isEos;\r
-}\r
-\r
-int32_t PlayerControl::Invoke(PlayerInvoke invokeId, const void *param)\r
-{\r
-    MsgInfo msg = {};\r
-    InvokeParameter invokeParam;\r
-    invokeParam.id = invokeId;\r
-    invokeParam.param = param;\r
-\r
-    msg.what = PLAYERCONTROL_MSG_INVOKE;\r
-    msg.msgData = &invokeParam;\r
-    msg.msgDataLen = sizeof(InvokeParameter);\r
-    return OnMessageReceived(msg);\r
-}\r
-\r
-int32_t PlayerControl::DoInvoke(const InvokeParameter &invokeParam)\r
-{\r
-    switch (invokeParam.id) {\r
-        case INVOKE_ENABLE_PAUSE_AFTER_PLAYER:\r
-            if (invokeParam.param == nullptr) {\r
-                return -1;\r
-            }\r
-            break;\r
-\r
-        case INVOKE_SET_AUDIO_SESSION:\r
-            if (invokeParam.param == nullptr) {\r
-                return -1;\r
-            }\r
-            audioSession_ = *(static_cast<const uint32_t *>(invokeParam.param));\r
-            MEDIA_INFO_LOG("audio sessionId: %d", audioSession_);\r
-            break;\r
-\r
-        case INVOKE_SET_OUTPUT_DEVICE:\r
-            if (invokeParam.param == nullptr) {\r
-                return -1;\r
-            }\r
-            outDeviceId_ = *(static_cast<const uint32_t *>(invokeParam.param));\r
-            MEDIA_INFO_LOG("outputDevice: 0x%x", outDeviceId_);\r
-            if (sinkManager_ != nullptr) {\r
-                return sinkManager_->SetOutputDevice(outDeviceId_);\r
-            }\r
-            break;\r
-\r
-        case INVOKE_SET_AUDIOSTREAM_TYPE:\r
-            if (invokeParam.param == nullptr) {\r
-                return -1;\r
-            }\r
-            streamType_ = *(static_cast<const uint32_t *>(invokeParam.param));\r
-            MEDIA_INFO_LOG("streamType: 0x%x", streamType_);\r
-            break;\r
-        default:\r
-            MEDIA_ERR_LOG("unsupport invoke: 0x%x", invokeParam.id);\r
-            return -1;\r
-    }\r
-    return 0;\r
-}\r
-\r
-int PlayerControl::HandleMsgWithParam(const MsgInfo &msgInfo)\r
-{\r
-    int32_t ret;\r
-    if (msgInfo.msgData == nullptr) {\r
-        MEDIA_ERR_LOG("data is null, msg:%d", msgInfo.what);\r
-        return HI_ERR_PLAYERCONTROL_NULL_PTR;\r
-    }\r
-    switch (msgInfo.what) {\r
-        case PLAYERCONTROL_MSG_REGCALLBACK:\r
-            ret = DoRegCallback(*static_cast<PlayerCtrlCallbackParam *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_SET_DATASOURCE_URI:\r
-            ret = DoSetDataSource(static_cast<const char *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_SET_DATASOURCE_FD:\r
-            ret = DoSetDataSource(*static_cast<SourceFdParam *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_SET_DATASOURCE_STREAM:\r
-            ret = DoSetDataSource(*static_cast<StreamSourceParam *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_SETATTR:\r
-            ret = DoSetMedia(*static_cast<PlayerControlStreamAttr *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_SETSPEED:\r
-            ret = DoSetPlaybackSpeed(*static_cast<const float *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_SET_VOLUME:\r
-            ret = DoSetVolume(*static_cast<VolumeAttr *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_SEEK:\r
-            ret = DoSeek(*static_cast<int64_t *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_GETFILEINFO:\r
-            ret = DoGetFileInfo(*static_cast<FormatFileInfo *>(msgInfo.msgData));\r
-            break;\r
-        case PLAYERCONTROL_MSG_INVOKE:\r
-            ret = DoInvoke(*static_cast<InvokeParameter *>(msgInfo.msgData));\r
-            break;\r
-        default:\r
-            ret = HI_ERR_PLAYERCONTROL_ILLEGAL_PARAM;\r
-            break;\r
-    }\r
-\r
-    return ret;\r
-}\r
-\r
-int PlayerControl::HandleMsgWithNoParam(const MsgInfo &msgInfo)\r
-{\r
-    int32_t ret;\r
-    switch (msgInfo.what) {\r
-        case PLAYERCONTROL_MSG_PREPARE:\r
-            ret = DoPrepare();\r
-            break;\r
-        case PLAYERCONTROL_MSG_PLAY:\r
-            ret = DoPlay();\r
-            break;\r
-        case PLAYERCONTROL_MSG_PAUSE:\r
-            ret = DoPause();\r
-            break;\r
-        case PLAYERCONTROL_MSG_STOP:\r
-            ret = DoStop();\r
-            break;\r
-        case PLAYERCONTROL_MSG_HANDLEDATA:\r
-            ret = HI_SUCCESS;\r
-            break;\r
-        default:\r
-            ret = HI_ERR_PLAYERCONTROL_ILLEGAL_PARAM;\r
-            break;\r
-    }\r
-\r
-    return ret;\r
-}\r
-\r
-int PlayerControl::HandleMessage(const MsgInfo &msgInfo)\r
-{\r
-    int32_t ret = HI_FAILURE;\r
-    if (!EventValidAtCurState(static_cast<PlayerControlMsgType>(msgInfo.what))) {\r
-        MEDIA_ERR_LOG("invalid event :%d at current state: %d", msgInfo.what, GetCurState());\r
-        return HI_ERR_PLAYERCONTROL_ILLEGAL_STATE_ACTION;\r
-    }\r
-\r
-    switch (msgInfo.what) {\r
-        case PLAYERCONTROL_MSG_REGCALLBACK:\r
-        case PLAYERCONTROL_MSG_SET_DATASOURCE_URI:\r
-        case PLAYERCONTROL_MSG_SET_DATASOURCE_FD:\r
-        case PLAYERCONTROL_MSG_SET_DATASOURCE_STREAM:\r
-        case PLAYERCONTROL_MSG_SETATTR:\r
-        case PLAYERCONTROL_MSG_SETSPEED:\r
-        case PLAYERCONTROL_MSG_SET_VOLUME:\r
-        case PLAYERCONTROL_MSG_SEEK:\r
-        case PLAYERCONTROL_MSG_GETFILEINFO:\r
-        case PLAYERCONTROL_MSG_INVOKE:\r
-            ret = HandleMsgWithParam(msgInfo);\r
-            break;\r
-        case PLAYERCONTROL_MSG_PAUSE:\r
-        case PLAYERCONTROL_MSG_PREPARE:\r
-        case PLAYERCONTROL_MSG_PLAY:\r
-        case PLAYERCONTROL_MSG_HANDLEDATA:\r
-        case PLAYERCONTROL_MSG_STOP:\r
-            ret = HandleMsgWithNoParam(msgInfo);\r
-            break;\r
-        default:\r
-            break;\r
-    }\r
-    return ret;\r
-}\r
-\r
-void PlayerControl::OnEventHandled(int event, int result) const\r
-{\r
-    if ((result == HI_ERR_PLAYERCONTROL_ILLEGAL_STATE_ACTION) && (event == PLAYERCONTROL_MSG_SEEK)) {\r
-        NotifyError(PLAYERCONTROL_ERROR_ILLEGAL_STATEACTION);\r
-    }\r
-}\r
-\r
-int32_t PlayerControl::OnMessageReceived(const MsgInfo &msg)\r
-{\r
-    int32_t ret = HandleMessage(msg);\r
-    if (ret == HI_SUCCESS) {\r
-        PlayerStatus nextState = FindTransition(GetCurState(), msg.what);\r
-        curState_ = nextState;\r
-        StateChangeCallback(curState_);\r
-    }\r
-    OnEventHandled(msg.what, ret);\r
-    return ret;\r
-}\r
-\r
-PlayerStatus PlayerControl::GetCurState(void)\r
-{\r
-    return curState_;\r
-}\r
-\r
-PlayerStatus PlayerControl::FindTransition(PlayerStatus state, int32_t event) const\r
-{\r
-    for (uint32_t i = 0; i < STATE_TRANS_STATE_SIZE; i++) {\r
-        if (event == STATE_MACHINE[state][i].msgType) {\r
-            return STATE_MACHINE[state][i].newState;\r
-        }\r
-    }\r
-    return state;\r
-}\r
-\r
-bool PlayerControl::EventValidAtCurState(PlayerControlMsgType type)\r
-{\r
-    if (type < PLAYERCONTROL_MSG_SETATTR || type >= PLAYERCONTROL_MSG_BUTT) {\r
-        MEDIA_ERR_LOG("EventValidAtCurState MSG type not support %d", type);\r
-        return false;\r
-    }\r
-    if (GetCurState() < 0 || GetCurState() >= PLAY_STATUS_BUTT) {\r
-        MEDIA_ERR_LOG("EventValidAtCurState cur state not support %d", GetCurState());\r
-        return false;\r
-    }\r
-    return LITEPLAY_STATE[type][GetCurState()];\r
-}\r
-bool PlayerControl::UIntMulIsOverflow64(uint64_t a, uint64_t b, uint64_t *value) const\r
-{\r
-    if (a == 0 || b == 0) {\r
-        return false;\r
-    }\r
-    if (UINT64_MAX / a < b) {\r
-        return true;\r
-    }\r
-\r
-    uint64_t result = static_cast<uint64_t>((a) * (b));\r
-    if (value != nullptr) {\r
-        *value = result;\r
-    }\r
-    return false;\r
-}\r
-bool PlayerControl::UIntMulIsOverflow32(uint32_t a, uint32_t b, uint32_t *value) const\r
-{\r
-    if (a == 0 || b == 0) {\r
-        return false;\r
-    }\r
-    if (UINT32_MAX / a < b) {\r
-        return true;\r
-    }\r
-\r
-    long long result = static_cast<long long>((a) * (b));\r
-    if (value != nullptr) {\r
-        *value = static_cast<uint32_t>(result);\r
-    }\r
-    return false;\r
-}\r
-}\r
-}\r
+/*
+ * Copyright (c) 2020-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "liteplayer.h"
+
+#ifdef SUPPORT_SYS_PRCTL
+#include <sys/prctl.h>
+#endif
+#include <unistd.h>
+#include "player_check.h"
+#include "hi_liteplayer_err.h"
+#include "liteplayer_comm.h"
+#if !defined(UNSUPPORT_AUDIO_DECODER) || !defined(UNSUPPORT_VIDEO_DECODER)
+#include "decoder.h"
+#endif
+
+#if !defined(UNSUPPORT_AUDIO_DECODER) || !defined(UNSUPPORT_VIDEO_DECODER)
+using OHOS::Media::Decoder;
+#endif
+using OHOS::Media::PlayerSource;
+using OHOS::Media::SinkManager;
+
+namespace OHOS {
+namespace Media {
+/* DEFAULT_VID_BUFSIZE: 2 * 1024 * 1024 */
+const uint32_t DEFAULT_VID_BUFSIZE = 2097152;
+/* DEFAULT_AUD_BUFSIZE: 256 * 1024 */
+const uint32_t DEFAULT_AUD_BUFSIZE = 262144;
+
+const uint32_t GET_BUFFER_TIMEOUT_MS = 0u;
+const uint32_t RENDER_FULL_SLEEP_TIME_US = 10000u;
+// 1. waiting app response playback complete callback event
+// 2. waiting interval time for loop playback
+const uint32_t RENDER_EOS_SLEEP_TIME_US = 3000000u;
+const uint32_t WAIT_BUFFER_EMPTY_SLEEP_TIME_US = 1000000u;
+const uint32_t DECODER_DEFAULT_WIDTH = 1920;
+const uint32_t DECODER_DEFAULT_HEIGHT = 1080;
+const uint32_t QUEUE_BUFFER_FULL_SLEEP_TIME_US = 10000u;
+const uint32_t NO_DATA_READ_SLEEP_TIME_US = 5000u;
+const uint32_t MAX_EVENT_MESSAGE_NUM = 128;
+const uint32_t MAX_THREAD_STACK_SIZE = 0x1800u;
+const uint32_t REQUEST_BUFFER_RETRY_WAIT_TIME_US = 10000u;
+const float YCBCR420SP_BUFFER_SIZE_COEFFICIENT = 1.5;
+#ifdef DEBUG_LOW_POWER
+const uint32_t RENDER_FULL_SLEEP_THRESHOLD_MS_MP3_AACLC_OPUS = 5;
+const uint32_t RENDER_FULL_SLEEP_THRESHOLD_MS_PCM = 25;
+const uint32_t RENDER_FULL_SLEEP_THRESHOLD_MS_FLAC = 50;
+#endif
+// In a single-process system, only one thread can work at a time.
+// Subthreads need to give CPU resources to the main thread to switch to the playback state.
+const uint32_t WAIT_MAIN_THREAD_SWITCH_TO_PLAY_STATUS_TIME_US = 10000u;
+// maximum number of consecutive surface buffer request failures retries(converted to time: 100 * 10ms = 1s)
+const uint32_t MAX_CONTINOUS_REQUEST_SURFACE_BUFFER_FAIL_COUNT = 100;
+
+static AudioCodecFormat g_fromCodecFormatToAudioManager[CODEC_BUT + 1] = {
+    FORMAT_INVALID, FORMAT_INVALID, FORMAT_INVALID, FORMAT_INVALID,
+    AAC_LC, G711A, G711U, PCM, MP3, G726, OPUS, FLAC, VORBIS, APE, SILK, SBC, FORMAT_INVALID
+};
+static EsFrameType g_fromDemuxTypeToSinkType[FRAME_TYPE_BUT + 1] = {
+    ESFRAME_TYPE_NONE, ESFRAME_TYPE_AUDIO, ESFRAME_TYPE_VIDEO, ESFRAME_TYPE_IMAGE, ESFRAME_TYPE_SUB,
+    ESFRAME_TYPE_DATA, ESFRAME_INVALID_TYPE
+};
+
+static CodecFormatAndMimePair g_avCodecFormatInfo[CODEC_BUT + 1] = {
+    { CODEC_H264, MEDIA_MIMETYPE_VIDEO_AVC },
+    { CODEC_H265, MEDIA_MIMETYPE_VIDEO_HEVC },
+    { CODEC_JPEG, MEDIA_MIMETYPE_IMAGE_JPEG },
+    { CODEC_MJPEG, MEDIA_MIMETYPE_IMAGE_MJPEG },
+    { CODEC_AAC, MEDIA_MIMETYPE_AUDIO_AAC },
+    { CODEC_G711A, MEDIA_MIMETYPE_AUDIO_G711A },
+    { CODEC_G711U, MEDIA_MIMETYPE_AUDIO_G711U },
+    { CODEC_PCM, MEDIA_MIMETYPE_AUDIO_PCM },
+    { CODEC_MP3, MEDIA_MIMETYPE_AUDIO_MP3 },
+    { CODEC_G726, MEDIA_MIMETYPE_AUDIO_G726 },
+    { CODEC_BUT, MEDIA_MIMETYPE_INVALID },
+};
+
+namespace {
+/* playing position notify interval in ms */
+const uint32_t DEFAULT_POS_NOFITY_INTERVAL = 300;
+}
+
+#ifdef DEBUG_LOW_POWER
+const int32_t US_2_MS = 1000;
+#endif
+
+void PlayerControl::RecordTime(struct timeval &timeStart)
+{
+    gettimeofday(&timeStart, nullptr);
+}
+
+uint64_t PlayerControl::CalcTimeDiffUsPrint(const struct timeval &timeStart, struct timeval &timeEnd,
+    std::string outString, bool showlog)
+{
+    gettimeofday(&timeEnd, nullptr);
+    const uint64_t timeUs = 1000000;
+    uint64_t diffSecToUs = 0;
+    bool isOverflow =
+        UIntMulIsOverflow64(static_cast<uint64_t>(timeEnd.tv_sec - timeStart.tv_sec), timeUs, &diffSecToUs);
+    if (isOverflow) {
+        MEDIA_ERR_LOG("PlayerControl::CalcTimeDiffUsPrint calculate reslut overflow!");
+        return INVALID_TIME;
+    }
+    uint64_t diffUsec = static_cast<uint64_t>(timeEnd.tv_usec - timeStart.tv_usec);
+    uint64_t diffTimeUS = diffSecToUs + diffUsec;
+    if (showlog) {
+        MEDIA_INFO_LOG("%s elapsed time: %lld us", outString.c_str(), diffTimeUS);
+    }
+    return diffTimeUS;
+}
+
+int32_t PlayerControl::GetPlayerControlDumpInfo(PlayerControlDebugInfo &playerControlInfo)
+{
+    playerControlInfo.currentPosition = currentPosition_;
+    playerControlInfo.hasRenderAudioEos = hasRenderAudioEos_;
+    playerControlInfo.hasRenderVideoEos = hasRenderVideoEos_;
+    playerControlInfo.isAudioStarted = isAudioStarted_;
+    playerControlInfo.isVideoStarted = isVideoStarted_;
+    playerControlInfo.offloadAudio = offloadAudio_;
+    playerControlInfo.outDevice = outDeviceId_;
+    playerControlInfo.sessionId = audioSession_;
+    return 0;
+}
+
+int32_t PlayerControl::GetPlayerVideoDumpInfo(PlayerVideoDebugInfo &videoDebugInfo)
+{
+    videoDebugInfo.frameBufCnt = vdecAttr_.frameBufCnt;
+    videoDebugInfo.u32Height = vdecAttr_.maxHeight;
+    videoDebugInfo.u32Width = vdecAttr_.maxWidth;
+    videoDebugInfo.enVideoType = vdecAttr_.type;
+    return 0;
+}
+
+int32_t PlayerControl::GetPlayerAudioDumpInfo(PlayerAudioDebugInfo &audioDebugInfo)
+{
+    audioDebugInfo.bitWidth = adecAttr_.bitWidth;
+    audioDebugInfo.enAudioType = adecAttr_.type;
+    return 0;
+}
+
+int32_t PlayerControl::GetPlayerFileDumpInfo(PlayerFileDebugInfo &fileDebugInfo)
+{
+    fileDebugInfo.filePath = filePath_;
+    fileDebugInfo.fd = fd_;
+    fileDebugInfo.offset = offset_;
+    return 0;
+}
+
+void PlayerControl::PrintKpiTime()
+{
+#ifdef PLAYER_KPI_ON
+    if (!recordFirstFrameCost_ && currentPosition_ >= 0) {
+        std::string startPlay("KPI_PlayNewFileTime");
+        CalcTimeDiffUsPrint(startPlayStartTime_, startPlayEndTime_, startPlay, KPI_PRINT);
+        recordFirstFrameCost_ = true;
+    }
+#endif
+}
+
+PlayerControl::PlayerControl()
+    : isInited_(false),
+      isPlayEnd_(false),
+      isAudPlayEos_(false),
+      cachedPacket_(false),
+      lastRendPos_(0),
+      lastNotifyTime_(0),
+      lastReadPktStrmIdx_(-1),
+      lastReadPktPts_(0),
+      lastSendPktPts_(0),
+      isVideoStarted_(false),
+      isAudioStarted_(false),
+      strmReadEnd_(false),
+      isPlayErr_(false),
+      lastSendAdecPts_(AV_INVALID_PTS),
+      currentPosition_(0),
+      paused_(false),
+      schThreadExit_(false),
+      loop_(false),
+      hasRenderAudioEos_(false),
+      hasRenderVideoEos_(false),
+      renderSleepTime_(0),
+      leftVolume_(-1.0f),
+      rightVolume_(-1.0f),
+      schMutex_(nullptr),
+      schCond_(nullptr),
+      schProcess_(nullptr),
+      seekToTimeMs_(-1),
+      sourceType_(SOURCE_TYPE_BUT),
+      firstAudioFrameAfterSeek_(false),
+      firstPosAfterSeek_(0),
+      fd_(-1),
+      offset_(0),
+      playerSource_(nullptr),
+      sinkManager_(nullptr),
+      surface_(nullptr),
+      surfaceBuf_(nullptr),
+      curState_(PLAY_STATUS_IDLE),
+      offloadAudio_(false),
+      audioSession_(0),
+      streamType_(AUDIO_STREAM_MUSIC),
+      recordFirstFrameCost_(false),
+      renderEsTotalTime_(0),
+      readPktTotalTime_(0),
+      renderEsFrameCnt_(0),
+      readPacketCnt_(0),
+      outDeviceId_(OUT_BUILTIN_SPEAKER),
+      headInSendSuccessInterval_(-1),
+      tailInSendSuccessInterval_(-1),
+      hasAudio_(false),
+      hasVideo_(false),
+      isAudio_(false),
+      isVideo_(false)
+{
+    eventCallback_.player = nullptr;
+    eventCallback_.callbackFun = nullptr;
+    if (memset_s(&fmtFileInfo_, sizeof(fmtFileInfo_), 0, sizeof(FormatFileInfo)) != EOK) {
+        MEDIA_ERR_LOG("memset_s failed");
+    }
+    fmtFileInfo_.s32UsedAudioStreamIndex = HI_DEMUXER_NO_MEDIA_STREAM;
+    fmtFileInfo_.s32UsedVideoStreamIndex = HI_DEMUXER_NO_MEDIA_STREAM;
+    playerParam_.u32PlayPosNotifyIntervalMs = DEFAULT_POS_NOFITY_INTERVAL;
+    playerParam_.u32VideoEsBufSize = DEFAULT_POS_NOFITY_INTERVAL;
+    playerParam_.u32AudioEsBufSize = DEFAULT_POS_NOFITY_INTERVAL;
+    playerParam_.u32VdecFrameBufCnt = DEFAULT_POS_NOFITY_INTERVAL;
+    if (memset_s(&formatPacket_, sizeof(formatPacket_), 0, sizeof(FormatFrame)) != EOK) {
+        MEDIA_ERR_LOG("memset_s failed");
+    }
+    streamAttr_.videoBufSize = 0;
+    streamAttr_.audioBufSize = 0;
+    adecAttr_.type = 0;
+    adecAttr_.sampleRate = 0;
+    adecAttr_.channel = 0;
+    adecAttr_.bitWidth = 0;
+    streamSource_.param.sampleRate = 0;
+    streamSource_.param.sampleFormat = 0;
+    streamSource_.param.channelCount = 0;
+    streamSource_.param.channelLayout = 0;
+    streamSource_.stream.ReadData = nullptr;
+    streamSource_.stream.GetReadableSize = nullptr;
+    streamSource_.stream.handle = nullptr;
+    eventQueue_.clear();
+    startPlayStartTime_.tv_sec = 0;
+    startPlayStartTime_.tv_usec = 0;
+    startPlayEndTime_.tv_sec = 0;
+    startPlayEndTime_.tv_usec = 0;
+    streamEndTime_.tv_sec = 0;
+    streamEndTime_.tv_usec = 0;
+    metaData_.key = 0;
+    metaData_.size = 0;
+#if !defined(UNSUPPORT_AUDIO_DECODER)
+    audioDecoder_ = nullptr;
+#endif
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+    videoDecoder_ = nullptr;
+#endif
+}
+
+PlayerControl::~PlayerControl()
+{
+    (void)Deinit();
+    eventQueue_.clear();
+}
+
+int32_t PlayerControl::InitAttr(const PlayerControlParam &createParam)
+{
+    if (memset_s(&fmtFileInfo_, sizeof(fmtFileInfo_), 0x00, sizeof(FormatFileInfo)) != EOK) {
+        MEDIA_ERR_LOG("memset_s failed");
+        return HI_ERR_PLAYERCONTROL_MEM_SET;
+    }
+    fmtFileInfo_.s32UsedAudioStreamIndex = HI_DEMUXER_NO_MEDIA_STREAM;
+    fmtFileInfo_.s32UsedVideoStreamIndex = HI_DEMUXER_NO_MEDIA_STREAM;
+    streamAttr_.playMode = RENDER_MODE_NORMAL;
+    streamAttr_.videoBufSize = DEFAULT_VID_BUFSIZE;
+    streamAttr_.audioBufSize = DEFAULT_AUD_BUFSIZE;
+
+    lastReadPktPts_ = 0;
+    lastSendPktPts_ = 0;
+    CHECK_FAILED_PRINT(memcpy_s(&playerParam_, sizeof(playerParam_), &createParam, sizeof(PlayerControlParam)), EOK,
+        "copy playerParam_ fail");
+    playerParam_.u32PlayPosNotifyIntervalMs = (createParam.u32PlayPosNotifyIntervalMs == 0) ?
+        DEFAULT_POS_NOFITY_INTERVAL :
+        createParam.u32PlayPosNotifyIntervalMs;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::Init(const PlayerControlParam &createParam)
+{
+    MEDIA_INFO_LOG("Init in");
+    CHECK_TRUE_CONDITION_RETURN(isInited_, HI_SUCCESS, "already be inited");
+    CHECK_FAILED_RETURN(InitAttr(createParam), HI_SUCCESS, HI_FAILURE, "InitAttr failed");
+    schMutex_ = MediaMutexCreate(nullptr);
+    if (schMutex_ == nullptr) {
+        MEDIA_ERR_LOG("create mutex failed");
+        return HI_FAILURE;
+    }
+    schCond_ = MediaThreadCondCreate();
+    if (schCond_ == nullptr) {
+        MEDIA_ERR_LOG("create cond failed");
+        MediaMutexDestroy(&schMutex_);
+        return HI_FAILURE;
+    }
+    isInited_ = true;
+#ifdef PLAYER_KPI_ON
+    RecordTime(startPlayStartTime_);
+#endif
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::Deinit()
+{
+    if (!isInited_) {
+        return HI_SUCCESS;
+    }
+    DestroyDecoder();
+    MediaMutexDestroy(&schMutex_);
+    MediaThreadCondDestroy(&schCond_);
+    isInited_ = false;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::RegCallback(PlayerCtrlCallbackParam &eventCallback)
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_REGCALLBACK;
+    msg.msgData = static_cast<void *>(&eventCallback);
+    msg.msgDataLen = 0;
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::SetDataSource(const std::string filepath)
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_SET_DATASOURCE_URI;
+    msg.msgData = const_cast<void *>(static_cast<const void *>(filepath.c_str()));
+    msg.msgDataLen = 0;
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::SetDataSource(SourceFdParam &fdSrc)
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_SET_DATASOURCE_FD;
+    msg.msgData = static_cast<void *>(&fdSrc);
+    msg.msgDataLen = 0;
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::SetDataSource(StreamSourceParam &streamSource)
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_SET_DATASOURCE_STREAM;
+    msg.msgData = static_cast<void *>(&streamSource);
+    msg.msgDataLen = 0;
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::Prepare()
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_PREPARE;
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::Play()
+{
+    int32_t ret;
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_PLAY;
+    ret = OnMessageReceived(msg);
+    CHECK_FAILED_PRINT(ret, HI_SUCCESS, "play failed");
+    return ret;
+}
+
+int32_t PlayerControl::SetVolume(const VolumeAttr &volumeAttr)
+{
+    VolumeAttr attr = volumeAttr;
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_SET_VOLUME;
+    msg.msgData = static_cast<void *>(&attr);
+    msg.msgDataLen = 0;
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::Stop()
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_STOP;
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::Pause()
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_PAUSE;
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::Seek(int64_t timeInMs)
+{
+    if (fmtFileInfo_.enVideoType == CODEC_JPEG) {
+        MEDIA_ERR_LOG("seek action not support for play picture");
+        return HI_ERR_PLAYERCONTROL_NOT_SUPPORT;
+    }
+    if ((fmtFileInfo_.s64Duration > 0) && (fmtFileInfo_.s64Duration < timeInMs)) {
+        return HI_ERR_PLAYERCONTROL_ILLEGAL_PARAM;
+    }
+    seekToTimeMs_ = timeInMs;
+    MediaThreadCondSignal(schCond_);
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::GetFileInfo(FormatFileInfo &formatInfo)
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_GETFILEINFO;
+    msg.msgData = &formatInfo;
+    msg.msgDataLen = sizeof(FormatFileInfo);
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::SetMedia(PlayerControlStreamAttr &mediaAttr)
+{
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_SETATTR;
+    msg.msgData = &mediaAttr;
+    msg.msgDataLen = sizeof(PlayerControlStreamAttr);
+    return OnMessageReceived(msg);
+}
+
+#if defined(ENABLE_UIKIT)
+int32_t PlayerControl::SetSurface(Surface *surface)
+#elif defined(ENABLE_LVGL)
+int32_t PlayerControl::SetSurface(LvSurfaceView *surface)
+#endif
+{
+    surface_ = surface;
+    return 0;
+}
+
+int32_t PlayerControl::SetPlaybackSpeed(float speed)
+{
+    float setSpeed = speed;
+    MsgInfo msg = {};
+    msg.what = PLAYERCONTROL_MSG_SETSPEED;
+    msg.msgData = static_cast<void *>(&setSpeed);
+    msg.msgDataLen = 0;
+    return OnMessageReceived(msg);
+}
+
+void PlayerControl::ClearCachePacket()
+{
+    if (cachedPacket_) {
+        if (formatPacket_.data != nullptr) {
+            if (playerSource_ != nullptr && playerSource_->FreeFrame(formatPacket_) != 0) {
+                MEDIA_ERR_LOG("FreeFrame failed \n");
+            }
+            formatPacket_.data = nullptr;
+            formatPacket_.len = 0;
+            formatPacket_.trackId = -1;
+        }
+        /* end packet is null do not need to demux free */
+        cachedPacket_ = false;
+    }
+}
+
+void PlayerControl::OnVideoEndOfStream()
+{
+    if (!hasAudio_ && (lastSendVdecPts_ > AV_INVALID_PTS)) {
+        EventCallback(PLAYERCONTROL_EVENT_PROGRESS, &lastSendVdecPts_);
+    }
+    isVidPlayEos_ = true;
+    isPlayEnd_ = IsPlayEos() ? true : isPlayEnd_;
+}
+
+void PlayerControl::EventProcess(EventCbType event)
+{
+    PlayerControlError playerError;
+    MEDIA_DEBUG_LOG("handleEvent %d", event);
+    switch (event) {
+        case EVNET_VIDEO_PLAY_EOS:
+            OnVideoEndOfStream();
+            break;
+        case EVNET_VIDEO_PLAY_SOS:
+            MEDIA_INFO_LOG("video sos recv");
+            break;
+        case EVNET_AUDIO_PLAY_EOS:
+            isAudPlayEos_ = true;
+            isPlayEnd_ = IsPlayEos() ? true : isPlayEnd_;
+            if (lastSendAdecPts_ > AV_INVALID_PTS) {
+                EventCallback(PLAYERCONTROL_EVENT_PROGRESS, &lastSendAdecPts_);
+            }
+            break;
+        case EVNET_VIDEO_RUNNING_ERR:
+        case EVNET_AUDIO_RUNNING_ERR:
+            playerError = PLAYERCONTROL_ERROR_AUD_PLAY_FAIL;
+            isPlayErr_ = true;
+            EventCallback(PLAYERCONTROL_EVENT_ERROR, &playerError);
+            break;
+        default:
+            break;
+    }
+}
+
+void PlayerControl::EventQueueProcess(void)
+{
+    size_t queSize;
+    PalayControlEventItem *item = nullptr;
+
+    queSize = eventQueue_.size();
+    if (queSize > MAX_EVENT_MESSAGE_NUM) {
+        MEDIA_WARNING_LOG("mesaage except, num:%u", queSize);
+    }
+    for (size_t i = 0; i < queSize && i < MAX_EVENT_MESSAGE_NUM; i++) {
+        item = &eventQueue_[i];
+        EventProcess(item->event);
+    }
+    eventQueue_.clear();
+}
+
+int32_t PlayerControl::OnPlayControlEvent(void *priv, const EventCbType event) const
+{
+    // audio play eos event needs to be handled immediately
+    if (event == EVNET_AUDIO_PLAY_EOS) {
+        MEDIA_INFO_LOG("Received audio play eos event");
+        EventCallback(PLAYERCONTROL_EVENT_EOF, nullptr);
+        return HI_SUCCESS;
+    } else if (event == EVNET_AUDIO_BUFFER_EMPTY) {
+        EventCallback(PLAYERCONTROL_BUFFER_EMPTY, nullptr);
+        return HI_SUCCESS;
+    } else if (event == EVNET_OUTPUT_DEVICE_CHANGED) {
+        PlayerControl *player = static_cast<PlayerControl *>(priv);
+        player->RecordLastPosition();
+        return HI_SUCCESS;
+    } else if (event == EVNET_AUDIO_RUNNING_ERR ||
+        event == EVNET_VIDEO_RUNNING_ERR) {
+        PlayerControlError playerError = PLAYERCONTROL_ERROR_AUD_PLAY_FAIL;
+        EventCallback(PLAYERCONTROL_EVENT_ERROR, &playerError);
+        return HI_SUCCESS;
+    }
+
+    PalayControlEventItem item;
+    PlayerControl *player = static_cast<PlayerControl *>(priv);
+
+    item.event = event;
+    player->eventQueue_.push_back(item);
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::PauseResume(void)
+{
+    CHECK_NULL_RETURN(sinkManager_, HI_ERR_PLAYERCONTROL_NULL_PTR, "sinkManager_ nullptr");
+    MediaMutexLock(schMutex_);
+    int32_t ret = sinkManager_->Resume();
+    if (ret != HI_SUCCESS) {
+        if (ret != NOT_FOUND_ACTIVE_STREAME) {
+            MEDIA_ERR_LOG("resume failed");
+            hasVideo_ ? NotifyError(PLAYERCONTROL_ERROR_VID_PLAY_FAIL) : NotifyError(PLAYERCONTROL_ERROR_AUD_PLAY_FAIL);
+        }
+        MediaMutexUnLock(schMutex_);
+        return ret;
+    }
+    paused_ = false;
+    // played to the end no need to signal
+    if (!IsPlayEos()) {
+        MediaThreadCondSignal(schCond_);
+    }
+    MediaMutexUnLock(schMutex_);
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::CheckMediaInfo(void) const
+{
+    if (fmtFileInfo_.s32UsedAudioStreamIndex >= HI_DEMUXER_RESOLUTION_CNT ||
+        fmtFileInfo_.s32UsedVideoStreamIndex >= HI_DEMUXER_RESOLUTION_CNT) {
+        MEDIA_ERR_LOG("input file error video track: %d audio %d", fmtFileInfo_.s32UsedVideoStreamIndex,
+            fmtFileInfo_.s32UsedAudioStreamIndex);
+        return HI_ERR_PLAYERCONTROL_DEMUX_ERROR;
+    }
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::GetVideoResolution(int32_t streamIdx, StreamResolution &resolution)
+{
+    if (streamIdx == HI_DEMUXER_NO_MEDIA_STREAM) {
+        MEDIA_ERR_LOG("stream id [%d] in invalid", streamIdx);
+        return HI_FAILURE;
+    }
+
+    for (uint32_t i = 0; i < HI_DEMUXER_RESOLUTION_CNT; i++) {
+        if (fmtFileInfo_.stSteamResolution[i].s32VideoStreamIndex == streamIdx) {
+            resolution.enVideoType = fmtFileInfo_.stSteamResolution[i].enVideoType;
+            resolution.s32VideoStreamIndex = fmtFileInfo_.stSteamResolution[i].s32VideoStreamIndex;
+            resolution.u32Width = fmtFileInfo_.stSteamResolution[i].u32Width;
+            resolution.u32Height = fmtFileInfo_.stSteamResolution[i].u32Height;
+            return HI_SUCCESS;
+        }
+    }
+
+    MEDIA_ERR_LOG("not found stream[%d] in file", streamIdx);
+    return HI_FAILURE;
+}
+
+int32_t PlayerControl::SetVDecAttr(void)
+{
+    StreamResolution resolution = {};
+    if (GetVideoResolution(fmtFileInfo_.s32UsedVideoStreamIndex, resolution) != HI_SUCCESS) {
+        MEDIA_ERR_LOG("GetVideoResolution failed");
+        return HI_FAILURE;
+    }
+    vdecAttr_.maxWidth = resolution.u32Width;
+    vdecAttr_.maxHeight = resolution.u32Height;
+    vdecAttr_.type = resolution.enVideoType;
+    vdecAttr_.frameBufCnt = playerParam_.u32VdecFrameBufCnt;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::SetADecAttr(void)
+{
+    adecAttr_.bitWidth = AUDIO_BITWIDTH;
+    adecAttr_.channel = fmtFileInfo_.u32AudioChannelCnt;
+    adecAttr_.sampleRate = fmtFileInfo_.u32SampleRate;
+    adecAttr_.type = fmtFileInfo_.enAudioType;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::SetStreamAttr()
+{
+    if (hasVideo_) {
+        StreamResolution resolution = {};
+        if (GetVideoResolution(fmtFileInfo_.s32UsedVideoStreamIndex, resolution) != HI_SUCCESS) {
+            MEDIA_ERR_LOG("GetVideoResolution failed");
+            return HI_ERR_PLAYERCONTROL_ILLEGAL_PARAM;
+        }
+        streamAttr_.videoBufSize = playerParam_.u32VideoEsBufSize;
+    }
+
+    if (hasAudio_) {
+        streamAttr_.audioBufSize =
+            (playerParam_.u32AudioEsBufSize) ? (playerParam_.u32AudioEsBufSize) : streamAttr_.audioBufSize;
+    }
+
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::SetDecoderAndStreamAttr(void)
+{
+    int ret;
+
+    if (hasAudio_) {
+        ret = SetADecAttr();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetADecAttr failed");
+    }
+
+    if (hasVideo_) {
+        ret = SetVDecAttr();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetVDecAttr failed");
+    }
+
+    ret = SetStreamAttr();
+    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetStreamAttr failed");
+    return HI_SUCCESS;
+}
+
+#if !defined(UNSUPPORT_VIDEO_DECODER) || !defined(UNSUPPORT_AUDIO_DECODER)
+static AvCodecMime TransformCodecFormatToAvCodecMime(CodecFormat format)
+{
+    AvCodecMime mime = MEDIA_MIMETYPE_INVALID;
+    uint32_t size = sizeof(g_avCodecFormatInfo) / sizeof(CodecFormatAndMimePair);
+
+    for (uint32_t i = 0; i < size; i++) {
+        if (g_avCodecFormatInfo[i].format == format) {
+            mime = g_avCodecFormatInfo[i].mime;
+            break;
+        }
+    }
+
+    return mime;
+}
+#endif
+
+#ifndef UNSUPPORT_VIDEO_DECODER
+static void GetCurVideoSolution(const FormatFileInfo &info, uint32_t &width, uint32_t &height)
+{
+    for (int i = 0; i < HI_DEMUXER_RESOLUTION_CNT; i++) {
+        if (info.stSteamResolution[i].s32VideoStreamIndex == info.s32UsedVideoStreamIndex) {
+            width = info.stSteamResolution[i].u32Width;
+            height = info.stSteamResolution[i].u32Height;
+            break;
+        }
+    }
+}
+#endif
+
+#ifndef UNSUPPORT_AUDIO_DECODER
+static std::string GetAudioNameByAvCodecMime(AvCodecMime mime)
+{
+    std::string audioName = "codec.unknow.soft.decoder";
+    switch (mime) {
+        case MEDIA_MIMETYPE_AUDIO_AAC:
+            audioName = "codec.aac.soft.decoder";
+            break;
+        case MEDIA_MIMETYPE_AUDIO_MP3:
+            audioName = "codec.mp3.soft.decoder";
+            break;
+        default:
+            MEDIA_ERR_LOG("not support codec type:%d", mime);
+            break;
+    }
+    return audioName;
+}
+
+int32_t PlayerControl::AudioDecoderStart(void)
+{
+    AvCodecMime mime = TransformCodecFormatToAvCodecMime(fmtFileInfo_.enAudioType);
+    if (mime == MEDIA_MIMETYPE_INVALID) {
+        MEDIA_ERR_LOG("DecoderStart not support codec:%d", fmtFileInfo_.enAudioType);
+        return -1;
+    }
+    audioDecoder_ = std::make_shared<Decoder>();
+    CHECK_NULL_RETURN(audioDecoder_, -1, "new decoder failed");
+    AvAttribute attr;
+    attr.type = AUDIO_DECODER;
+    attr.adecAttr.mime = mime;
+    attr.adecAttr.priv = nullptr;
+    attr.adecAttr.bufSize = 0x400; /* 1024 */
+    attr.adecAttr.channelCnt = (mime == MEDIA_MIMETYPE_AUDIO_PCM) ? fmtFileInfo_.u32AudioChannelCnt : 0;
+    const std::string audioName = GetAudioNameByAvCodecMime(mime);
+    int32_t ret = audioDecoder_->CreateHandle(audioName, attr);
+    CHECK_FAILED_RETURN(ret, 0, -1, "create audio decoder failed");
+    ret = audioDecoder_->StartDec();
+    CHECK_FAILED_RETURN(ret, 0, -1, "start audio decoder failed");
+    MEDIA_INFO_LOG("audio decoder started");
+
+    return 0;
+}
+#endif
+
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+int32_t PlayerControl::VideoDecoderStart(void)
+{
+    AvAttribute attr;
+    uint32_t width = DECODER_DEFAULT_WIDTH;
+    uint32_t height = DECODER_DEFAULT_HEIGHT;
+
+    AvCodecMime mime = TransformCodecFormatToAvCodecMime(fmtFileInfo_.enVideoType);
+    if (mime == MEDIA_MIMETYPE_INVALID) {
+        MEDIA_ERR_LOG("DecoderStart not support codec:%d", fmtFileInfo_.enVideoType);
+        return -1;
+    }
+    GetCurVideoSolution(fmtFileInfo_, width, height);
+
+    videoDecoder_ = std::make_shared<Decoder>();
+    CHECK_NULL_RETURN(videoDecoder_, -1, "new decoder failed");
+    attr.type = VIDEO_DECODER;
+    attr.vdecAttr.mime = mime;
+    attr.vdecAttr.priv = nullptr;
+    attr.vdecAttr.bufSize = 0;
+    attr.vdecAttr.maxWidth = width;
+    attr.vdecAttr.maxHeight = height;
+    const std::string videoName = "codec.avc.soft.decoder";
+    int32_t ret = videoDecoder_->CreateHandle(videoName, attr);
+    CHECK_FAILED_RETURN(ret, 0, -1, "create video decoder failed");
+    ret = videoDecoder_->StartDec();
+    CHECK_FAILED_RETURN(ret, 0, -1, "start video decoder failed");
+    MEDIA_INFO_LOG("video decoder started");
+
+    return 0;
+}
+#endif
+
+int32_t PlayerControl::DecoderStart(void)
+{
+    if (!hasAudio_ && !hasVideo_) {
+        MEDIA_ERR_LOG("not decoder need start");
+        return -1;
+    }
+
+    MEDIA_INFO_LOG("audio stream id: %d, video stream id: %d", fmtFileInfo_.s32UsedAudioStreamIndex,
+        fmtFileInfo_.s32UsedVideoStreamIndex);
+
+    /* if offload audio is false, need audio decoder, not support */
+    if (hasAudio_) {
+        if (!offloadAudio_) {
+            MEDIA_ERR_LOG("not support offload, need audio decoder, return failed");
+            return -1;
+        }
+    }
+
+    if (hasVideo_) {
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+        if (VideoDecoderStart() != 0) {
+            return -1;
+        }
+#endif
+    }
+    return 0;
+}
+
+void PlayerControl::DestroyDecoder() const
+{
+#ifndef UNSUPPORT_AUDIO_DECODER
+    if (audioDecoder_ != nullptr) {
+        audioDecoder_->DestroyHandle();
+    }
+#endif
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+    if (videoDecoder_ != nullptr) {
+        videoDecoder_->DestroyHandle();
+    }
+#endif
+}
+
+void PlayerControl::StopSinkAndDecoder()
+{
+    OutputInfo outInfo = {};
+    EsFrameInfo frameInfo = {};
+    if (sinkManager_ != nullptr) {
+        sinkManager_->Stop();
+#ifdef UNSUPPORT_AUDIO_DECODER
+        while (sinkManager_->DequeReleaseEsFrame(true, frameInfo) == HI_SUCCESS) {
+        }
+#else
+        if (audioDecoder_ != nullptr) {
+            while (sinkManager_->DequeReleaseFrame(true, outInfo) == 0) {
+                audioDecoder_->QueueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);
+            }
+            audioDecoder_->StopDec();
+        }
+#endif
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+        if (videoDecoder_ != nullptr) {
+            while (sinkManager_->DequeReleaseFrame(false, outInfo) == 0) {
+                videoDecoder_->QueueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);
+            }
+            videoDecoder_->StopDec();
+        }
+#endif
+    }
+
+    isVideoStarted_ = false;
+    isAudioStarted_ = false;
+}
+
+int32_t PlayerControl::AddAudioSink(void)
+{
+    CHECK_TRUE_CONDITION_RETURN(isAudioStarted_, HI_SUCCESS, "already started");
+    SinkAttr attr;
+    attr.sinkType = SINK_TYPE_AUDIO;
+    attr.trackId = fmtFileInfo_.s32UsedAudioStreamIndex;
+    attr.audAttr.format = g_fromCodecFormatToAudioManager[fmtFileInfo_.enAudioType];
+    attr.audAttr.sampleRate = adecAttr_.sampleRate;
+    attr.audAttr.channel = fmtFileInfo_.u32AudioChannelCnt;
+    attr.audAttr.sessionID = audioSession_;
+    attr.audAttr.streamType = streamType_;
+    attr.audAttr.bitWidth = adecAttr_.bitWidth;
+    attr.audAttr.sampleFmt = fmtFileInfo_.sampleFmt;
+    MEDIA_INFO_LOG("AddAudioSink, format:%d, sampleRate:%d, channel:%d, session:%d, streamType:%d, bitWidth:%d",
+        attr.audAttr.format, attr.audAttr.sampleRate, attr.audAttr.channel, attr.audAttr.sessionID,
+        attr.audAttr.streamType, attr.audAttr.bitWidth);
+    if (sinkManager_->AddNewSink(attr) != 0) {
+        MEDIA_ERR_LOG("AddNewSink  failed");
+        return -1;
+    }
+    isAudioStarted_ = true;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::GetOffloadSupport(void)
+{
+    if (sinkManager_ == nullptr) {
+        MEDIA_ERR_LOG("sinkManager_ is invalid");
+        return -1;
+    }
+    AudioOffloadParam curOffloadInfo;
+    curOffloadInfo.streamType = streamType_;
+    curOffloadInfo.format = g_fromCodecFormatToAudioManager[fmtFileInfo_.enAudioType];
+    curOffloadInfo.sampleRate = adecAttr_.sampleRate;
+    curOffloadInfo.channel = fmtFileInfo_.u32AudioChannelCnt;
+    curOffloadInfo.bitWidth = 0;
+    MEDIA_INFO_LOG("GetOffloadSupport format:%d, audio:%d", curOffloadInfo.format, fmtFileInfo_.enAudioType);
+    offloadAudio_ = sinkManager_->IsOffloadSupported(curOffloadInfo);
+    MEDIA_INFO_LOG("%s audio offload", offloadAudio_ ? "supported" : "unsupported");
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::AddVideoSink()
+{
+    CHECK_TRUE_CONDITION_RETURN(isVideoStarted_, HI_SUCCESS, "already started");
+    SinkAttr attr;
+    attr.sinkType = SINK_TYPE_VIDEO;
+    attr.trackId = fmtFileInfo_.s32UsedVideoStreamIndex;
+    attr.vidAttr.width = fmtFileInfo_.u32Width;
+    attr.vidAttr.height = fmtFileInfo_.u32Height;
+    attr.vidAttr.frameRate = fmtFileInfo_.fFrameRate;
+    attr.vidAttr.format = fmtFileInfo_.enVideoType;
+    attr.vidAttr.surface = surface_;
+    if (sinkManager_->AddNewSink(attr) != 0) {
+        MEDIA_ERR_LOG("AddNewSink  failed");
+        return -1;
+    }
+    isVideoStarted_ = true;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::SinkStart(void)
+{
+    int32_t ret;
+    sinkManager_ = std::make_shared<SinkManager>();
+    CHECK_NULL_RETURN(sinkManager_, HI_FAILURE, "new sinkManager_ nullptr");
+    if (hasVideo_ && !isVideoStarted_) {
+        ret = AddVideoSink();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "AddVideoSink failed");
+        isVideoStarted_ = true;
+    }
+    if (hasAudio_ && !isAudioStarted_) {
+        ret = AddAudioSink();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "AddAudioSink failed");
+        isAudioStarted_ = true;
+    }
+
+    PlayEventCallback callback;
+    GetPlayElementEventCallBack(callback);
+    ret = sinkManager_->RegisterCallBack(callback);
+    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "RegisterCallBack failed");
+    /* get offload flag */
+    GetOffloadSupport();
+
+    if (metaData_.key == KEY_TYPE_EXTRADATA && hasAudio_) {
+        std::string key("extradata");
+        ret = sinkManager_->SetParam(key, DATA_TYPE_PTR, metaData_.value.pValue, metaData_.size);
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "sinkManager_ SetParam failed");
+    }
+
+    ret = sinkManager_->Start();
+    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "sinkManager_ Start failed");
+
+    if (leftVolume_ >= 0.0f || rightVolume_ >= 0.0f) {
+        sinkManager_->SetVolume(leftVolume_, rightVolume_);
+    }
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::ReadFrameFromSource(FormatFrame &fmtFrame)
+{
+    CHECK_NULL_RETURN(playerSource_, HI_ERR_PLAYERCONTROL_NULL_PTR, "playerSource_ nullptr");
+    int ret = playerSource_->ReadFrame(fmtFrame);
+    // Check consistency of fmtFrame
+    if ((ret == HI_SUCCESS) && (fmtFrame.data != nullptr) && (fmtFrame.len == 0)) {
+        MEDIA_ERR_LOG("ReadFrame ERROR : u32Size is invalid");
+        ret = HI_FAILURE;
+    }
+    return ret;
+}
+
+// message begin
+int32_t PlayerControl::DoRegCallback(const PlayerCtrlCallbackParam &eventCallback)
+{
+    if (eventCallback_.callbackFun != nullptr) {
+        MEDIA_WARNING_LOG("you have reg callback,now the before callback fun pointer will be overwrite");
+    }
+    eventCallback_ = eventCallback;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::DoSetDataSource(const char *filepath)
+{
+    filePath_ = std::string(filepath);
+    sourceType_ = SOURCE_TYPE_URI;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::DoSetDataSource(const SourceFdParam &fdSrc)
+{
+    fd_ = fdSrc.fd;
+    offset_ = fdSrc.offset;
+    sourceType_ = SOURCE_TYPE_FD;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::DoSetDataSource(const StreamSourceParam &streamSource)
+{
+    streamSource_ = streamSource;
+    sourceType_ = SOURCE_TYPE_STREAM;
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::DoPrepare(void)
+{
+    MEDIA_DEBUG_LOG("Process in");
+    CHECK_NULL_RETURN(eventCallback_.callbackFun, HI_ERR_PLAYERCONTROL_CALLBACK_ERROR, "callbackFun nullptr");
+    isPlayEnd_ = false;
+    int32_t ret = SyncPrepare();
+    CHECK_FAILED_RETURN(ret, HI_SUCCESS, HI_ERR_PLAYERCONTROL_OTHER, "SyncPrepare failed");
+    if (playerParam_.u32PlayPosNotifyIntervalMs >= fmtFileInfo_.s64Duration) {
+        MEDIA_WARNING_LOG("play postion notify interval %d ms oversize file duration, user will never receive notify",
+            playerParam_.u32PlayPosNotifyIntervalMs);
+    }
+    MEDIA_DEBUG_LOG("Process out");
+    return HI_SUCCESS;
+}
+
+#if !defined(UNSUPPORT_VIDEO_DECODER) || !defined(UNSUPPORT_AUDIO_DECODER)
+static void InitOutputBuffer(OutputInfo &outInfo, CodecType type)
+{
+    if (outInfo.buffers != nullptr) {
+        free(outInfo.buffers);
+        outInfo.buffers = nullptr;
+    }
+
+    outInfo.bufferCnt = 0;
+    outInfo.buffers = nullptr;
+    outInfo.timeStamp = -1;
+    outInfo.sequence = 0;
+    outInfo.flag = 0;
+    outInfo.type = type;
+    outInfo.vendorPrivate = nullptr;
+}
+#endif
+
+#ifndef UNSUPPORT_AUDIO_DECODER
+void PlayerControl::ReleaseADecoderOutputFrame(void)
+{
+    if (audioDecoder_ == nullptr || sinkManager_ == nullptr) {
+        return;
+    }
+    while (true) {
+        OutputInfo outInfo;
+        if (sinkManager_->DequeReleaseFrame(true, outInfo) != 0) {
+            break;
+        }
+        audioDecoder_->QueueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);
+    }
+}
+#endif
+
+void PlayerControl::ReleaseAudioSinkESFrame(void)
+{
+    CHECK_NULL_RETURN_NONE(sinkManager_, "sink manager is null");
+
+    EsFrameInfo outInfo = {};
+    while (sinkManager_->DequeReleaseEsFrame(true, outInfo) == HI_SUCCESS) {
+    }
+}
+
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+void PlayerControl::ReleaseVDecoderOutputFrame(void) const
+{
+    if (videoDecoder_ == nullptr || sinkManager_ == nullptr) {
+        return;
+    }
+    while (true) {
+        OutputInfo outInfo;
+        if (sinkManager_->DequeReleaseFrame(false, outInfo) != 0) {
+            break;
+        }
+    }
+}
+#endif
+
+void PlayerControl::ReportRenderPosition(void)
+{
+    int64_t position = -1;
+    CHECK_NULL_RETURN_NONE(sinkManager_, "sinkManager_ nullptr");
+    sinkManager_->GetRenderPosition(position);
+    if (position >= 0 && currentPosition_ != position) {
+        if (lastRendPos_ >= 0) {
+            currentPosition_ = position - lastRendPos_ + firstPosAfterSeek_;
+        } else {
+            currentPosition_ = position;
+        }
+        EventCallback(PLAYERCONTROL_EVENT_PROGRESS, &currentPosition_);
+    }
+}
+
+void PlayerControl::GetRenderFullSleepThresholdTime(AudioCodecFormat codecFormat)
+{
+#ifdef DEBUG_LOW_POWER
+    if (codecFormat == PCM) {
+        renderFullSleepThresholdMs_ = RENDER_FULL_SLEEP_THRESHOLD_MS_PCM;
+    } else if (codecFormat == MP3 || codecFormat == AAC_LC || codecFormat == OPUS) {
+        renderFullSleepThresholdMs_ = RENDER_FULL_SLEEP_THRESHOLD_MS_MP3_AACLC_OPUS;
+    } else if (codecFormat == FLAC) {
+        renderFullSleepThresholdMs_ = RENDER_FULL_SLEEP_THRESHOLD_MS_FLAC;
+    }
+#else
+    MEDIA_UNUSED(codecFormat);
+#endif
+}
+
+void PlayerControl::DataSchPreProcess(PlayerControl *play, bool *isContinue)
+{
+    if (play->hasRenderAudioEos_) {
+        int32_t info = PLAYERCONTROL_ERROR_AUD_PLAY_FAIL;
+        play->EventCallback(PLAYERCONTROL_EVENT_ERROR, &info);
+        MEDIA_ERR_LOG("player waiting for the EOS callback timed out.");
+    }
+    play->DoSeekIfNeed();
+
+    play->renderSleepTime_ = 0;
+
+    if (play->paused_) {
+        // blocking wait ensures that the system goes into deep sleep for reducing power consumption
+        MediaThreadCondWait(play->schCond_, play->schMutex_);
+        *isContinue = true;
+    }
+}
+
+void PlayerControl::DataSchPostProcess(PlayerControl *play)
+{
+    play->EventQueueProcess();
+
+    play->ReportRenderPosition();
+
+    play->PrintKpiTime();
+
+    // process pure video eos
+    if (play->hasVideo_ && !play->hasAudio_ && play->hasRenderVideoEos_) {
+        MEDIA_INFO_LOG("Received video play eos flag");
+        play->EventCallback(PLAYERCONTROL_EVENT_EOF, nullptr);
+    }
+
+    if (play->IsPlayEos()) {
+        play->renderSleepTime_ = RENDER_EOS_SLEEP_TIME_US;
+    }
+}
+
+#if !defined(UNSUPPORT_VIDEO_DECODER) || !defined(UNSUPPORT_AUDIO_DECODER)
+inline static bool IsValidPacket(FormatFrame &packet)
+{
+    return (packet.data != nullptr && packet.len != 0) ? true : false;
+}
+#endif
+
+int32_t PlayerControl::DequeueInputDataFromDemuxer(void)
+{
+    if (GetCurState() != PLAY_STATUS_PLAY) {
+        renderSleepTime_ = WAIT_MAIN_THREAD_SWITCH_TO_PLAY_STATUS_TIME_US;
+        return HI_FAILURE;
+    }
+
+    CHECK_TRUE_CONDITION_RETURN(strmReadEnd_, HI_SUCCESS, "read stream end");
+
+#ifdef PLAYER_KPI_ON
+    struct timeval readPacketStartTime;
+    RecordTime(readPacketStartTime);
+#endif
+
+    int32_t ret = ReadPacket();
+    if (ret == HI_RET_NODATA) {
+        renderSleepTime_ = NO_DATA_READ_SLEEP_TIME_US;
+        goto RE_SEND;
+    } else if (ret != HI_SUCCESS) {
+        goto RE_SEND;
+    }
+
+#ifdef PLAYER_KPI_ON
+    ReadPacketAvgCostTime(readPacketStartTime);
+#endif
+
+    if (formatPacket_.data == nullptr && formatPacket_.len == 0) {
+        strmReadEnd_ = true;
+        formatPacket_.timestampUs = -1;
+        gettimeofday(&streamEndTime_, nullptr);
+        if (loop_) {
+            seekToTimeMs_ = 0;
+            return HI_FAILURE;
+        }
+    }
+
+    isAudio_ = (formatPacket_.frameType == FRAME_TYPE_AUDIO) ? true : false;
+    isVideo_ = (formatPacket_.frameType == FRAME_TYPE_VIDEO) ? true : false;
+
+    return HI_SUCCESS;
+
+RE_SEND:
+    ClearCachePacket();
+    return ret;
+}
+
+int32_t PlayerControl::QueueInputDataToAudioSink(void)
+{
+    CHECK_NULL_RETURN(sinkManager_, HI_FAILURE, "sink manager is null");
+    CHECK_TRUE_CONDITION_RETURN(hasRenderAudioEos_, HI_FAILURE, "has render audio eos");
+
+    if (strmReadEnd_) {
+        sinkManager_->RenderEos(true);
+    } else {
+        CHECK_FALSE_CONDITION_RETURN(cachedPacket_, HI_FAILURE, "no cache packet");
+    }
+
+    EsFrameInfo outInfo = {};
+    FillAudioFrameInfo(outInfo);
+    int32_t ret = sinkManager_->RenderEsFrame(outInfo);
+    if (ret == SINK_RENDER_FULL || ret == SINK_RENDER_DELAY) {
+#ifdef DEBUG_LOW_POWER
+        static uint32_t renderSuccessCount = 0;
+        LowPowerProcess(outInfo.pts, renderSuccessCount, false);
+#else
+        if (ret == SINK_RENDER_FULL && fmtFileInfo_.s32UsedVideoStreamIndex < 0) {
+            renderSleepTime_ = WAIT_BUFFER_EMPTY_SLEEP_TIME_US;
+        } else {
+            renderSleepTime_ = RENDER_FULL_SLEEP_TIME_US;
+        }
+#endif
+        return ret;
+    } else {
+#ifdef DEBUG_LOW_POWER
+        LowPowerProcess(outInfo.pts, renderSuccessCount, true);
+#endif
+        renderSleepTime_ = 0;
+    }
+    ReleaseAudioSinkESFrame();
+    if (ret == SINK_RENDER_EOS) {
+        hasRenderAudioEos_ = true;
+        MEDIA_INFO_LOG("have render audio eos");
+        if (IsPlayEos()) {
+            isPlayEnd_ = true;
+        }
+    }
+    if (firstAudioFrameAfterSeek_) {
+        firstAudioFrameAfterSeek_ = false;
+        sinkManager_->GetRenderPosition(lastRendPos_);
+        firstPosAfterSeek_ = formatPacket_.timestampUs;
+        MEDIA_INFO_LOG("push firstAudioFrameAfterSeek_ success, pts:%lld", formatPacket_.timestampUs);
+    }
+    if (formatPacket_.data != nullptr || formatPacket_.len != 0) {
+        lastSendAdecPts_ = formatPacket_.timestampUs;
+    }
+    ClearCachePacket();
+    return ret;
+}
+
+#ifndef UNSUPPORT_AUDIO_DECODER
+void PlayerControl::QueueInputDataToAudioDecoder(void)
+{
+    CHECK_NULL_RETURN_NONE(audioDecoder_, "audio decoder is null");
+    CHECK_TRUE_CONDITION_RETURN_NONE(cachedPacket_, "no cache packet");
+
+    InputInfo inputData = { 0, nullptr, 0, 0 };
+    CodecBufferInfo inBufInfo = {};
+
+    int32_t ret = audioDecoder_->DequeInputBuffer(inputData, GET_BUFFER_TIMEOUT_MS);
+    CHECK_FAILED_RETURN_NONE(ret, HI_SUCCESS, "deque input buffer failed");
+
+    inBufInfo.addr = formatPacket_.data;
+    inBufInfo.length = formatPacket_.len;
+    inputData.bufferCnt = 1;
+    inputData.buffers = &inBufInfo;
+    inputData.pts = formatPacket_.timestampUs;
+    inputData.flag = 0;
+    ret = audioDecoder_->QueueInputBuffer(inputData, GET_BUFFER_TIMEOUT_MS);
+    if (ret == CODEC_ERR_STREAM_BUF_FULL) {
+        renderSleepTime_ = QUEUE_BUFFER_FULL_SLEEP_TIME_US;
+        return;
+    }
+    if (firstAudioFrameAfterSeek_ && IsValidPacket(formatPacket_)) {
+        firstAudioFrameAfterSeek_ = false;
+        MEDIA_INFO_LOG("push firstAudioFrameAfterSeek_ success, pts:%lld", inputData.pts);
+    }
+    if (formatPacket_.data != nullptr || formatPacket_.len != 0) {
+        lastSendAdecPts_ = formatPacket_.timestampUs;
+    }
+    ClearCachePacket();
+}
+
+void PlayerControl::DequeueOutputBufferAndRenderAudioFrame(void)
+{
+    CHECK_NULL_RETURN_NONE(audioDecoder_, "audio decoder is null");
+    CHECK_NULL_RETURN_NONE(sinkManager_, "sink manager is null");
+    CHECK_FAILED_RETURN_NONE(hasRenderAudioEos_, false, "has render audio eos");
+
+    OutputInfo outInfo = {};
+    int32_t ret = audioDecoder_->DequeueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);
+    if (ret != HI_SUCCESS) {
+        InitOutputBuffer(outInfo, AUDIO_DECODER);
+        if (ret == CODEC_RECEIVE_EOS && strmReadEnd_) {
+            // all frame have been send to audio sink
+            sinkManager_->RenderEos(true);
+        }
+    }
+
+    ret = sinkManager_->RenderFrame(outInfo);
+    if (ret == SINK_RENDER_FULL || ret == SINK_RENDER_DELAY) {
+        renderSleepTime_ = RENDER_FULL_SLEEP_TIME_US;
+    } else if (ret == SINK_QUE_EMPTY) {
+        renderSleepTime_ = 0;
+    }
+    ReleaseADecoderOutputFrame();
+    // all frame in frameCacheQue_ is processed
+    if (ret == SINK_RENDER_EOS) {
+        hasRenderAudioEos_ = true;
+        MEDIA_INFO_LOG("have render audio eos");
+        if (IsPlayEos()) {
+            isPlayEnd_ = true;
+        }
+    }
+}
+#endif
+
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+int32_t PlayerControl::QueueOutputBufferToVideoDecoder(void)
+{
+    CHECK_NULL_RETURN(surface_, HI_FAILURE, "surface is null");
+    CHECK_NULL_RETURN(sinkManager_, HI_FAILURE, "sink manager is null");
+    CHECK_NULL_RETURN(videoDecoder_, HI_FAILURE, "video decoder is null");
+
+    // 1. if video sink have cache, means have remain buffer not send to surface, don't need request buffer from surface
+    bool haveCache = sinkManager_->HaveCacheFrame(false);
+    if (haveCache) {
+        MEDIA_DEBUG_LOG("have cache frame skip this");
+        return HI_SUCCESS;
+    }
+
+    // 2. request video output buffer from surface
+#if defined(ENABLE_UIKIT)
+    surfaceBuf_ = surface_->RequestBuffer();
+#elif defined(ENABLE_LVGL)
+    surfaceBuf_ = LvRequestBuffer(reinterpret_cast<lv_obj_t *>(surface_), 0);
+#endif
+    if (surfaceBuf_ == nullptr) {
+        if (continousRequestSurfaceBufferFailCount_ == MAX_CONTINOUS_REQUEST_SURFACE_BUFFER_FAIL_COUNT) {
+            PalayControlEventItem item = { EVNET_VIDEO_RUNNING_ERR };
+            eventQueue_.push_back(item);
+            MEDIA_FATAL_LOG("continous request buffer fail count exceed upper limit");
+            return REQUEST_SURFACE_BUFFER_FATAL;
+        }
+        MEDIA_DEBUG_LOG("no free surface buffer retry");
+        renderSleepTime_ = REQUEST_BUFFER_RETRY_WAIT_TIME_US;
+        continousRequestSurfaceBufferFailCount_++;
+        return HI_FAILURE;
+    }
+    continousRequestSurfaceBufferFailCount_ = 0;
+
+    // 3. queue output buffer to video decoder
+    OutputInfo outInfo = {};
+    outInfo.type = VIDEO_DECODER;
+    outInfo.bufferCnt = 1;
+    outInfo.buffers = (CodecBufferInfo *)malloc(sizeof(CodecBufferInfo));
+    if (outInfo.buffers == nullptr) {
+        MEDIA_ERR_LOG("malloc failed");
+        return HI_FAILURE;
+    }
+    outInfo.buffers[0].type = BUFFER_TYPE_VIRTUAL;
+    outInfo.buffers[0].addr = reinterpret_cast<uint8_t *>(surfaceBuf_->addr);
+    outInfo.buffers[0].length = surfaceBuf_->width * surfaceBuf_->height * YCBCR420SP_BUFFER_SIZE_COEFFICIENT;
+    outInfo.vendorPrivate = surfaceBuf_;
+
+    int32_t ret = videoDecoder_->QueueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);
+    if (ret != HI_SUCCESS) {
+        free(outInfo.buffers);
+        MEDIA_ERR_LOG("queue output buffer to video decoder failed: 0x%x", ret);
+        return HI_FAILURE;
+    }
+
+    free(outInfo.buffers);
+    return HI_SUCCESS;
+}
+
+void PlayerControl::QueueInputDataToVideoDecoder(void)
+{
+    CHECK_NULL_RETURN_NONE(videoDecoder_, "video decoder is null");
+    CHECK_NULL_RETURN_NONE(sinkManager_, "sink manager is null");
+
+    bool haveCache = sinkManager_->HaveCacheFrame(false);
+    if (haveCache) {
+        MEDIA_DEBUG_LOG("have cache frame skip this");
+        return;
+    }
+
+    if (!strmReadEnd_) {
+        CHECK_FALSE_CONDITION_RETURN_NONE(cachedPacket_, "no cache packet");
+    }
+
+    InputInfo inputData = { 0, nullptr, 0, 0 };
+    CodecBufferInfo inBufInfo = {};
+
+    int32_t ret = videoDecoder_->DequeInputBuffer(inputData, GET_BUFFER_TIMEOUT_MS);
+    CHECK_FAILED_RETURN_NONE(ret, HI_SUCCESS, "deque input buffer failed");
+
+    MEDIA_DEBUG_LOG("queue input buffer len: %u, pts: %lld", formatPacket_.len, formatPacket_.timestampUs);
+
+    inBufInfo.addr = formatPacket_.data;
+    inBufInfo.length = formatPacket_.len;
+    inputData.bufferCnt = 1;
+    inputData.buffers = &inBufInfo;
+    inputData.pts = formatPacket_.timestampUs;
+    inputData.flag = (formatPacket_.data == nullptr && formatPacket_.len == 0) ? STREAM_FLAG_EOS : 0;
+    ret = videoDecoder_->QueueInputBuffer(inputData, GET_BUFFER_TIMEOUT_MS);
+    if (ret == CODEC_ERR_STREAM_BUF_FULL) {
+        renderSleepTime_ = QUEUE_BUFFER_FULL_SLEEP_TIME_US;
+        return;
+    }
+    if (firstVideoFrameAfterSeek_ && IsValidPacket(formatPacket_)) {
+        firstVideoFrameAfterSeek_ = false;
+        // MEDIA_INFO_LOG("push firstVideoFrameAfterSeek_ success, pts:%lld", inputData.pts);
+    }
+    if (formatPacket_.data != nullptr && formatPacket_.len != 0) {
+        lastSendVdecPts_ = formatPacket_.timestampUs;
+    }
+    ClearCachePacket();
+}
+
+void PlayerControl::DequeueOutputBufferAndRenderVideoFrame(void)
+{
+    CHECK_NULL_RETURN_NONE(videoDecoder_, "video decoder is null");
+    CHECK_NULL_RETURN_NONE(sinkManager_, "sink manager is null");
+    CHECK_TRUE_CONDITION_RETURN_NONE(hasRenderVideoEos_, "has render video eos");
+
+    OutputInfo outInfo = {};
+    outInfo.buffers = (CodecBufferInfo *)malloc(sizeof(CodecBufferInfo));
+    if (outInfo.buffers == nullptr) {
+        MEDIA_ERR_LOG("malloc failed");
+        return;
+    }
+    int ret = videoDecoder_->DequeueOutputBuffer(outInfo, GET_BUFFER_TIMEOUT_MS);
+    if (ret != 0) {
+        InitOutputBuffer(outInfo, VIDEO_DECODER);
+        if (surface_ != nullptr) {
+#if defined(ENABLE_UIKIT)
+            surface_->CancelBuffer(surfaceBuf_);
+#elif defined(ENABLE_LVGL)
+            LvCancelBuffer(reinterpret_cast<lv_obj_t *>(surface_), surfaceBuf_);
+#endif
+        }
+        if (ret == CODEC_RECEIVE_EOS) {
+            sinkManager_->RenderEos(false); /* all frame have been send to video sink */
+        } else {
+            goto EXIT;
+        }
+    }
+
+    ret = sinkManager_->RenderFrame(outInfo);
+    if (ret == SINK_RENDER_FULL || ret == SINK_RENDER_DELAY) {
+        renderSleepTime_ = RENDER_FULL_SLEEP_TIME_US;
+    } else if (ret == SINK_QUE_EMPTY) {
+        renderSleepTime_ = 0;
+    }
+EXIT:
+    ReleaseVDecoderOutputFrame();
+    /* fuction RenderFrame will return SINK_RENDER_EOS when all frame in queue that have been processed */
+    if (ret == SINK_RENDER_EOS) {
+        hasRenderVideoEos_ = true;
+        MEDIA_INFO_LOG("have render video eos");
+        if (IsPlayEos()) {
+            isPlayEnd_ = true;
+        }
+    }
+
+    if (outInfo.buffers != nullptr) {
+        free(outInfo.buffers);
+    }
+    return;
+}
+#endif
+
+int32_t PlayerControl::DealWithInputEos(bool hasAudio, bool hasVideo)
+{
+    if (hasAudio) {
+#ifdef UNSUPPORT_AUDIO_DECODER
+        QueueInputDataToAudioSink();
+#else
+        QueueInputDataToAudioDecoder();
+        DequeueOutputBufferAndRenderAudioFrame();
+#endif
+    }
+
+    if (hasVideo) {
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+        int32_t ret = QueueOutputBufferToVideoDecoder();
+        if (ret != HI_SUCCESS) {
+            return ret;
+        }
+        QueueInputDataToVideoDecoder();
+        DequeueOutputBufferAndRenderVideoFrame();
+#endif
+    }
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::ProcessInputData(bool isAudio, bool isVideo)
+{
+    if (isAudio) {
+#ifdef UNSUPPORT_AUDIO_DECODER
+        return QueueInputDataToAudioSink();
+#else
+        QueueInputDataToAudioDecoder();
+        DequeueOutputBufferAndRenderAudioFrame();
+#endif
+    } else if (isVideo) {
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+        int32_t retValue = QueueOutputBufferToVideoDecoder();
+        if (retValue != HI_SUCCESS) {
+            return retValue;
+        }
+        QueueInputDataToVideoDecoder();
+        DequeueOutputBufferAndRenderVideoFrame();
+#endif
+    }
+    return HI_SUCCESS;
+}
+
+void *PlayerControl::DataSchProcess(void *priv)
+{
+    CHECK_NULL_RETURN(priv, nullptr, "priv is null");
+
+    PlayerControl *play = (PlayerControl *)priv;
+
+#ifdef SUPPORT_SYS_PRCTL
+    prctl(PR_SET_NAME, "PlaySch", 0, 0, 0);
+#endif
+
+    MEDIA_INFO_LOG("start work");
+
+    // for low power
+    play->GetRenderFullSleepThresholdTime(g_fromCodecFormatToAudioManager[play->fmtFileInfo_.enAudioType]);
+
+    int32_t ret = HI_FAILURE;
+    while (true) {
+        MediaMutexLock(play->schMutex_);
+        if (play->schThreadExit_) {
+            MediaMutexUnLock(play->schMutex_);
+            break;
+        }
+
+        bool isContinue = false;
+        DataSchPreProcess(play, &isContinue);
+        if (isContinue) {
+            goto CONTINUE;
+        }
+
+        if (play->DequeueInputDataFromDemuxer() != HI_SUCCESS) {
+            goto CONTINUE;
+        }
+
+        if (play->strmReadEnd_) {
+            ret = play->DealWithInputEos(play->hasAudio_, play->hasVideo_);
+        } else {
+            ret = play->ProcessInputData(play->isAudio_, play->isVideo_);
+        }
+
+        if (ret == SINK_RENDER_FATEL || ret == REQUEST_SURFACE_BUFFER_FATAL) {
+            play->EventQueueProcess();
+            MediaMutexUnLock(play->schMutex_);
+            break;
+        } else if (ret != HI_SUCCESS) {
+            goto CONTINUE;
+        }
+
+        DataSchPostProcess(play);
+
+    CONTINUE:
+        if (play->renderSleepTime_ > 0) {
+            MediaThreadCondTimeWait(play->schCond_, play->schMutex_, play->renderSleepTime_);
+        }
+        MediaMutexUnLock(play->schMutex_);
+    }
+
+    MediaMutexLock(play->schMutex_);
+    play->schThreadExit_ = true;
+    MediaMutexUnLock(play->schMutex_);
+
+    MEDIA_INFO_LOG("end work");
+    return nullptr;
+}
+
+int32_t PlayerControl::DoPlay()
+{
+    MEDIA_DEBUG_LOG("Process in");
+    CHECK_NULL_RETURN(playerSource_, HI_ERR_PLAYERCONTROL_NULL_PTR, "playerSource_ nullptr");
+
+    int32_t ret = HI_SUCCESS;
+    PlayerStatus playerState = GetCurState();
+    CHECK_STATE_SAME_RETURN(playerState, PLAY_STATUS_PLAY, "state same");
+    if (playerState == PLAY_STATUS_PREPARED) {
+        ret = CheckMediaInfo();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "CheckMediaInfo failed");
+        ret = SetDecoderAndStreamAttr();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetDecoderAndStreamAttr failed");
+        ret = SinkStart();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SinkStart failed");
+        ret = DecoderStart();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "DecoderStart failed");
+        ret = playerSource_->Start();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "playerSource_ Start failed");
+        MediaMutexLock(schMutex_);
+        paused_ = true;
+        MediaThreadattr attr = { "PlaySch", MAX_THREAD_STACK_SIZE, THREAD_SCHED_INVALID, 80, false };
+        schProcess_ = MediaThreadCreate(DataSchProcess, this, &attr);
+        if (schProcess_ == nullptr) {
+            MEDIA_ERR_LOG("thread create failed %d", ret);
+            schThreadExit_ = false;
+            MediaMutexUnLock(schMutex_);
+            return -1;
+        }
+        paused_ = false;
+        MediaMutexUnLock(schMutex_);
+    } else if (playerState == PLAY_STATUS_PAUSE) {
+        ret = PauseResume();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "PauseResume failed");
+    } else {
+        return HI_ERR_PLAYERCONTROL_ILLEGAL_STATE_ACTION;
+    }
+    return ret;
+}
+
+int32_t PlayerControl::DoSetVolume(const VolumeAttr &volumeAttr)
+{
+    leftVolume_ = volumeAttr.leftVolume;
+    rightVolume_ = volumeAttr.rightVolume;
+    CHECK_NULL_RETURN(sinkManager_, HI_SUCCESS, "sinkManager_ nullptr, it will be setted after play");
+    return sinkManager_->SetVolume(volumeAttr.leftVolume, volumeAttr.rightVolume);
+}
+
+int32_t PlayerControl::ReadPacket()
+{
+    int32_t ret = HI_SUCCESS;
+    if (cachedPacket_) {
+        return ret;
+    }
+    ret = ReadFrameFromSource(formatPacket_);
+    if (ret != HI_RET_FILE_EOF && formatPacket_.data == nullptr && formatPacket_.len == 0) {
+        return HI_RET_NODATA;
+    }
+    if (ret == HI_RET_FILE_EOF) {
+        CHECK_FAILED_RETURN(memset_s(&formatPacket_, sizeof(formatPacket_), 0, sizeof(FormatFrame)), EOK, -1,
+            "memset_s failed");
+        ret = HI_SUCCESS;
+    } else if (ret == HI_RET_NODATA) {
+        CHECK_FAILED_RETURN(memset_s(&formatPacket_, sizeof(formatPacket_), 0, sizeof(FormatFrame)), EOK, -1,
+            "memset_s failed");
+        strmReadEnd_ = false;
+        return ret;
+    } else if (ret != HI_SUCCESS) {
+        MEDIA_ERR_LOG("ReadFrameFromSource failed , ret:%d", ret);
+        NotifyError(PLAYERCONTROL_ERROR_DEMUX_FAIL);
+        return HI_FAILURE;
+    }
+    strmReadEnd_ = false;
+    cachedPacket_ = true;
+    return ret;
+}
+
+#ifdef PLAYER_KPI_ON
+void PlayerControl::PrintRenderEsTime(const struct timeval &esFrameStartTime)
+{
+    std::string renderEsFrame("KPI_PlayerRenderEsFrame");
+    struct timeval esFrameEndTime = {};
+    uint64_t renderEsOnceTime = CalcTimeDiffUsPrint(esFrameStartTime, esFrameEndTime, renderEsFrame, false);
+    if (renderEsOnceTime != INVALID_TIME) {
+        renderEsTotalTime_ += renderEsOnceTime;
+        renderEsFrameCnt_++;
+    }
+    if (renderEsFrameCnt_ == 500) { /* 500:Print Interval */
+        MEDIA_INFO_LOG("KPI_PlayerRenderEsFrame avg time: %lld us", renderEsTotalTime_ /= renderEsFrameCnt_);
+        renderEsTotalTime_ = 0;
+        renderEsFrameCnt_ = 0;
+    }
+}
+#endif
+
+void PlayerControl::FillAudioFrameInfo(EsFrameInfo &outInfo)
+{
+    if (memset_s(&outInfo, sizeof(outInfo), 0, sizeof(EsFrameInfo)) != EOK) {
+        return;
+    }
+
+    outInfo.addr = formatPacket_.data;
+    outInfo.size = formatPacket_.len;
+    outInfo.pts = formatPacket_.timestampUs;
+    outInfo.flag = 0;
+    EsFrameType frameType = g_fromDemuxTypeToSinkType[formatPacket_.frameType];
+    outInfo.type = (frameType == ESFRAME_TYPE_NONE) ? ESFRAME_TYPE_AUDIO : frameType;
+}
+
+#ifdef DEBUG_LOW_POWER
+void PlayerControl::LowPowerProcess(int64_t pts, uint32_t &renderSuccessCount, bool renderFrameSuccess)
+{
+    if (renderFrameSuccess) {
+        if (headInSendSuccessInterval_ == -1) {
+            headInSendSuccessInterval_ = pts;
+            tailInSendSuccessInterval_ = -1;
+        }
+        renderSuccessCount++;
+    } else {
+        if (tailInSendSuccessInterval_ == -1) {
+            tailInSendSuccessInterval_ = pts;
+            int64_t diffMs = tailInSendSuccessInterval_ - headInSendSuccessInterval_ - renderFullSleepThresholdMs_;
+            renderSleepTime_ = (diffMs > 0) ? (diffMs * US_2_MS) : RENDER_FULL_SLEEP_TIME_US;
+        }
+
+        /* MEAIA_XXX_LOG have performance problem, use printf instead */
+        printf("render %d audio frames, from %lldms to %lldms, thread wait %ums\n", renderSuccessCount,
+            tailInSendSuccessInterval_, headInSendSuccessInterval_, renderSleepTime_ / US_2_MS);
+
+        headInSendSuccessInterval_ = -1;
+        renderSuccessCount = 0;
+    }
+}
+#endif
+
+#ifdef PLAYER_KPI_ON
+void PlayerControl::ReadPacketAvgCostTime(const struct timeval &readPacketStartTime)
+{
+    struct timeval readPacketEndTime;
+    std::string readPacketCost("KPI_Player_demux_cost_time");
+    uint64_t readPktOnceTime = CalcTimeDiffUsPrint(readPacketStartTime, readPacketEndTime, readPacketCost, false);
+    if (readPktOnceTime != INVALID_TIME) {
+        readPktTotalTime_ += readPktOnceTime;
+        readPacketCnt_++;
+    }
+    if (readPacketCnt_ == 500) { /* 500:Print Interval */
+        MEDIA_INFO_LOG("KPI_Player_demux_cost_time avg time: %lld us", readPktTotalTime_ /= readPacketCnt_);
+        readPktTotalTime_ = 0;
+        readPacketCnt_ = 0;
+    }
+}
+#endif
+
+int32_t PlayerControl::DoStop()
+{
+    int32_t ret = HI_SUCCESS;
+    PlayerStatus playerState = GetCurState();
+    CHECK_STATE_SAME_RETURN(playerState, PLAY_STATUS_IDLE, "state same");
+
+    if (schProcess_ != nullptr) {
+        MediaMutexLock(schMutex_);
+        schThreadExit_ = true;
+        MediaThreadCondSignal(schCond_);
+        MediaMutexUnLock(schMutex_);
+        MediaThreadJoin(&schProcess_);
+    }
+    StopSinkAndDecoder();
+    ClearCachePacket();
+    if (playerSource_ != nullptr) {
+        ret = playerSource_->Stop();
+        CHECK_FAILED_PRINT(ret, HI_SUCCESS, "playerSource_ stop failed");
+    }
+    isPlayEnd_ = false;
+    strmReadEnd_ = false;
+    isPlayErr_ = false;
+    lastRendPos_ = 0;
+    lastReadPktPts_ = 0;
+    lastSendPktPts_ = 0;
+    isAudPlayEos_ = false;
+    hasRenderAudioEos_ = false;
+    hasRenderAudioEos_ = false;
+    lastNotifyTime_ = 0;
+    seekToTimeMs_ = -1;
+    if (memset_s(&(fmtFileInfo_), sizeof(fmtFileInfo_), 0, sizeof(FormatFileInfo)) != EOK) {
+        MEDIA_ERR_LOG("memset_s failed");
+        return HI_ERR_PLAYERCONTROL_MEM_SET;
+    }
+    return ret;
+}
+
+int32_t PlayerControl::DoPause(void)
+{
+    PlayerStatus playerState = GetCurState();
+    CHECK_STATE_SAME_RETURN(playerState, PLAY_STATUS_PAUSE, "state same");
+    CHECK_NULL_RETURN(sinkManager_, HI_FAILURE, "sinkManager_ nullptr");
+
+    if (playerState == PLAY_STATUS_PLAY) {
+        MediaMutexLock(schMutex_);
+        int32_t ret = sinkManager_->Pause();
+        CHECK_FAILED_PRINT(ret, 0, "sinkManager_ pause failed:%d");
+        paused_ = true;
+        MediaMutexUnLock(schMutex_);
+    } else {
+        return HI_ERR_PLAYERCONTROL_ILLEGAL_STATE_ACTION;
+    }
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::DoSeekIfNeed(void)
+{
+    if (seekToTimeMs_ == -1) {
+        return HI_SUCCESS;
+    }
+    MEDIA_INFO_LOG("seek start");
+    
+    // 在 seek 前重置解码器和渲染器,确保状态一致,避免 DPU 超时
+    // 清空解码器中的旧帧,重置渲染器状态,让 DPU 重新同步
+    int32_t ret = DecoderAndSinkReset();
+    if (ret != HI_SUCCESS) {
+        MEDIA_ERR_LOG("DecoderAndSinkReset failed, ret:%d", ret);
+        // 即使 reset 失败,也继续执行 seek,避免阻塞
+    }
+    
+    ret = AyncSeek(seekToTimeMs_);
+    if (ret != HI_SUCCESS) {
+        MEDIA_ERR_LOG(" AyncSeek  failed , ret:%d", ret);
+        NotifyError(PLAYERCONTROL_ERROR_AUD_PLAY_FAIL);
+        return ret;
+    }
+    strmReadEnd_ = false;
+    isAudPlayEos_ = false;
+    isVidPlayEos_ = false;
+    hasRenderVideoEos_ = false;
+    hasRenderAudioEos_ = false;
+    isPlayEnd_ = false;
+    seekToTimeMs_ = -1;
+    firstAudioFrameAfterSeek_ = true;
+    firstVideoFrameAfterSeek_ = true;
+    MEDIA_INFO_LOG("seek end");
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::DoSeek(int64_t timeInMs)
+{
+    seekToTimeMs_ = timeInMs;
+    return DoSeekIfNeed();
+}
+
+int32_t PlayerControl::DoGetFileInfo(FormatFileInfo &fileInfo) const
+{
+    return memcpy_s(&fileInfo, sizeof(FormatFileInfo), &fmtFileInfo_, sizeof(fmtFileInfo_));
+}
+
+int32_t PlayerControl::DoSetMedia(const PlayerControlStreamAttr &mediaAttr)
+{
+    CHECK_NULL_RETURN(playerSource_, HI_ERR_PLAYERCONTROL_NULL_PTR, "playerSource_ nullptr");
+
+    int32_t ret = HI_SUCCESS;
+    if (hasVideo_) {
+        ret = playerSource_->SelectTrack(0, mediaAttr.s32VidStreamId);
+        CHECK_FAILED_RETURN(ret, 0, HI_ERR_PLAYERCONTROL_DEMUX_ERROR, "select video track failed");
+    }
+    if (hasAudio_) {
+        ret = playerSource_->SelectTrack(0, mediaAttr.s32AudStreamId);
+        CHECK_FAILED_RETURN(ret, 0, HI_ERR_PLAYERCONTROL_DEMUX_ERROR, "select audio track failed");
+    }
+
+    fmtFileInfo_.s32UsedVideoStreamIndex = mediaAttr.s32VidStreamId;
+    fmtFileInfo_.s32UsedAudioStreamIndex = mediaAttr.s32AudStreamId;
+
+    hasAudio_ = (fmtFileInfo_.s32UsedAudioStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) ? true : false;
+    hasVideo_ = (fmtFileInfo_.s32UsedVideoStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) ? true : false;
+
+    return ret;
+}
+
+int32_t PlayerControl::DoSetPlaybackSpeed(float speed) const
+{
+    MediaMutexLock(schMutex_);
+    int ret = sinkManager_->SetSpeed(speed);
+    if (ret != HI_SUCCESS) {
+        MEDIA_ERR_LOG("DoSetPlaybackSpeed failed:%d", ret);
+    }
+    MediaMutexUnLock(schMutex_);
+    return HI_SUCCESS;
+}
+
+void PlayerControl::RecordLastPosition()
+{
+    sinkManager_->RecordLastPosition();
+}
+
+// util bigein
+void PlayerControl::EventCallback(PlayerControlEvent event, const void *data) const
+{
+    CHECK_NULL_RETURN_NONE(eventCallback_.callbackFun, "callbackFun nullptr");
+    eventCallback_.callbackFun(eventCallback_.player, event, data);
+}
+
+void PlayerControl::PlayerControlCondSignal(void)
+{
+    if (fmtFileInfo_.s32UsedVideoStreamIndex < 0) {
+        MediaThreadCondSignal(schCond_);
+    }
+}
+
+void PlayerControl::EnableSingleLooping(bool loop)
+{
+    MediaMutexLock(schMutex_);
+    loop_ = loop;
+    MediaMutexUnLock(schMutex_);
+}
+
+int32_t PlayerControl::SetParam(const std::string &key, const void *value, uint32_t len)
+{
+    CHECK_NULL_RETURN(sinkManager_, HI_ERR_PLAYERCONTROL_NULL_PTR, "sinkManager_ nullptr");
+    MediaMutexLock(schMutex_);
+    int32_t ret = sinkManager_->SetParam(key, DATA_TYPE_STRING, value, len);
+    if (ret != HI_SUCCESS) {
+        MediaMutexUnLock(schMutex_);
+        return ret;
+    }
+    MediaMutexUnLock(schMutex_);
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::GetParam(const std::string &key, void *value, uint32_t size)
+{
+    CHECK_NULL_RETURN(sinkManager_, HI_ERR_PLAYERCONTROL_NULL_PTR, "sinkManager_ nullptr");
+    MediaMutexLock(schMutex_);
+    int32_t ret = sinkManager_->GetParam(key, DATA_TYPE_PTR, value, size);
+    if (ret != HI_SUCCESS) {
+        MediaMutexUnLock(schMutex_);
+        return ret;
+    }
+    MediaMutexUnLock(schMutex_);
+    return HI_SUCCESS;
+}
+
+void PlayerControl::NotifyError(PlayerControlError playerError) const
+{
+    EventCallback(PLAYERCONTROL_EVENT_ERROR, static_cast<void *>(&playerError));
+}
+
+void PlayerControl::StateChangeCallback(PlayerStatus state) const
+{
+    EventCallback(PLAYERCONTROL_EVENT_STATE_CHANGED, static_cast<void *>(&state));
+}
+
+void PlayerControl::FlushDecoder(void)
+{
+#ifndef UNSUPPORT_AUDIO_DECODER
+    ReleaseADecoderOutputFrame();
+    if (audioDecoder_ != nullptr) {
+        audioDecoder_->FlushDec();
+    }
+#endif
+
+#if !defined(UNSUPPORT_VIDEO_DECODER)
+    // 取消当前正在使用的 Surface buffer,确保 buffer 可以被重新请求
+    if (surface_ != nullptr && surfaceBuf_ != nullptr) {
+#if defined(ENABLE_UIKIT)
+        surface_->CancelBuffer(surfaceBuf_);
+#elif defined(ENABLE_LVGL)
+        LvCancelBuffer(reinterpret_cast<lv_obj_t *>(surface_), surfaceBuf_);
+#endif
+        surfaceBuf_ = nullptr;
+    }
+    ReleaseVDecoderOutputFrame();
+    if (videoDecoder_ != nullptr) {
+        videoDecoder_->FlushDec();
+    }
+#endif
+}
+
+int32_t PlayerControl::DecoderAndSinkReset(void)
+{
+    if (strmReadEnd_ && loop_) {
+        return HI_SUCCESS;
+    }
+    int32_t ret;
+    bool isNeedResume = false;
+    ret = sinkManager_->Pause();
+    if ((ret == HI_SUCCESS) && (!paused_)) {
+        isNeedResume = true;
+    }
+    ret = sinkManager_->Reset();
+    if (ret != HI_SUCCESS) {
+        MEDIA_ERR_LOG("m_render reset failed");
+        (void)sinkManager_->Resume();
+        return ret;
+    }
+    FlushDecoder();
+    if (isNeedResume) {
+        ret = sinkManager_->Resume();
+        CHECK_FAILED_RETURN(ret, HI_SUCCESS, HI_FAILURE, "sinkManager_ Resume failed");
+    }
+    return HI_SUCCESS;
+}
+
+int32_t PlayerControl::AyncSeek(int64_t seekTime)
+{
+    CHECK_NULL_RETURN(playerSource_, HI_FAILURE, "playerSource_ nullptr");
+    int64_t seekTimeInMs = seekTime;
+    int32_t ret = 0;
+    ClearCachePacket();
+    if (fmtFileInfo_.s32UsedVideoStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) {
+        ret = playerSource_->Seek(fmtFileInfo_.s32UsedVideoStreamIndex, seekTimeInMs, FORMAT_SEEK_MODE_BACKWARD_KEY);
+        if (ret != HI_SUCCESS) {
+            MEDIA_INFO_LOG("exec fmt_seek video stream failed, ret:%d", ret);
+            seekTimeInMs = currentPosition_;
+        }
+    }
+    if (fmtFileInfo_.s32UsedAudioStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) {
+        ret = playerSource_->Seek(fmtFileInfo_.s32UsedAudioStreamIndex, seekTimeInMs, FORMAT_SEEK_MODE_BACKWARD_KEY);
+        if (ret != HI_SUCCESS) {
+            MEDIA_INFO_LOG("exec fmt_seek audio stream failed, ret:%d", ret);
+            seekTimeInMs = currentPosition_;
+        }
+    }
+    currentPosition_ = seekTimeInMs;
+    EventCallback(PLAYERCONTROL_EVENT_PROGRESS, &currentPosition_);
+    EventCallback(PLAYERCONTROL_EVENT_SEEK_END, static_cast<void *>(&seekTimeInMs));
+    return HI_SUCCESS;
+}
+
+void PlayerControl::GetPlayElementEventCallBack(PlayEventCallback &callback)
+{
+    callback.onEventCallback = PlayerControlOnEvent;
+    callback.priv = static_cast<void *>(this);
+}
+int32_t PlayerControl::SyncPrepare()
+{
+    int ret;
+    playerSource_ = std::make_shared<PlayerSource>();
+    CHECK_NULL_RETURN(playerSource_, HI_FAILURE, "new playerSource_ nullptr");
+    playerSource_->Init();
+
+    if (sourceType_ == SOURCE_TYPE_FD) {
+        playerSource_->SetSource(fd_, offset_);
+    } else if (sourceType_ == SOURCE_TYPE_STREAM) {
+        playerSource_->SetSource(streamSource_);
+    } else {
+        playerSource_->SetSource(filePath_.c_str());
+    }
+
+    PlayEventCallback callback;
+    GetPlayElementEventCallBack(callback);
+    ret = playerSource_->SetCallBack(callback);
+    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "SetCallBack failed");
+
+    ret = playerSource_->Prepare();
+    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "Prepare failed");
+    ret = playerSource_->GetFileInfo(fmtFileInfo_);
+    CHECK_FAILED_RETURN(ret, HI_SUCCESS, ret, "GetFileInfo failed");
+    metaData_.key = KEY_TYPE_EXTRADATA;
+    ret = playerSource_->GetParam(0, metaData_);
+    if (ret != HI_SUCCESS) {
+        MEDIA_INFO_LOG("no extradata metadata");
+        metaData_.key = 0;
+    }
+
+    hasAudio_ = (fmtFileInfo_.s32UsedAudioStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) ? true : false;
+    hasVideo_ = (fmtFileInfo_.s32UsedVideoStreamIndex != HI_DEMUXER_NO_MEDIA_STREAM) ? true : false;
+
+    MEDIA_INFO_LOG("used audiostream index %d", fmtFileInfo_.s32UsedAudioStreamIndex);
+    MEDIA_INFO_LOG("used videostream index %d", fmtFileInfo_.s32UsedVideoStreamIndex);
+
+    return HI_SUCCESS;
+}
+
+bool PlayerControl::IsPlayEos() const
+{
+    bool isEos = false;
+    if (hasAudio_) {
+        if (hasVideo_) {
+            return (!isAudioStarted_ || hasRenderAudioEos_) && (!isVideoStarted_ || hasRenderVideoEos_);
+        } else {
+            return (!isAudioStarted_ || hasRenderAudioEos_);
+        }
+    } else {
+        if (hasVideo_) {
+            return (!isVideoStarted_ || hasRenderVideoEos_);
+        } else {
+            MEDIA_ERR_LOG("neither audio nor video");
+            isEos = false;
+        }
+    }
+
+    return isEos;
+}
+
+int32_t PlayerControl::Invoke(PlayerInvoke invokeId, const void *param)
+{
+    MsgInfo msg = {};
+    InvokeParameter invokeParam;
+    invokeParam.id = invokeId;
+    invokeParam.param = param;
+
+    msg.what = PLAYERCONTROL_MSG_INVOKE;
+    msg.msgData = &invokeParam;
+    msg.msgDataLen = sizeof(InvokeParameter);
+    return OnMessageReceived(msg);
+}
+
+int32_t PlayerControl::DoInvoke(const InvokeParameter &invokeParam)
+{
+    switch (invokeParam.id) {
+        case INVOKE_ENABLE_PAUSE_AFTER_PLAYER:
+            if (invokeParam.param == nullptr) {
+                return -1;
+            }
+            break;
+
+        case INVOKE_SET_AUDIO_SESSION:
+            if (invokeParam.param == nullptr) {
+                return -1;
+            }
+            audioSession_ = *(static_cast<const uint32_t *>(invokeParam.param));
+            MEDIA_INFO_LOG("audio sessionId: %d", audioSession_);
+            break;
+
+        case INVOKE_SET_OUTPUT_DEVICE:
+            if (invokeParam.param == nullptr) {
+                return -1;
+            }
+            outDeviceId_ = *(static_cast<const uint32_t *>(invokeParam.param));
+            MEDIA_INFO_LOG("outputDevice: 0x%x", outDeviceId_);
+            if (sinkManager_ != nullptr) {
+                return sinkManager_->SetOutputDevice(outDeviceId_);
+            }
+            break;
+
+        case INVOKE_SET_AUDIOSTREAM_TYPE:
+            if (invokeParam.param == nullptr) {
+                return -1;
+            }
+            streamType_ = *(static_cast<const uint32_t *>(invokeParam.param));
+            MEDIA_INFO_LOG("streamType: 0x%x", streamType_);
+            break;
+        default:
+            MEDIA_ERR_LOG("unsupport invoke: 0x%x", invokeParam.id);
+            return -1;
+    }
+    return 0;
+}
+
+int PlayerControl::HandleMsgWithParam(const MsgInfo &msgInfo)
+{
+    int32_t ret;
+    if (msgInfo.msgData == nullptr) {
+        MEDIA_ERR_LOG("data is null, msg:%d", msgInfo.what);
+        return HI_ERR_PLAYERCONTROL_NULL_PTR;
+    }
+    switch (msgInfo.what) {
+        case PLAYERCONTROL_MSG_REGCALLBACK:
+            ret = DoRegCallback(*static_cast<PlayerCtrlCallbackParam *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_SET_DATASOURCE_URI:
+            ret = DoSetDataSource(static_cast<const char *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_SET_DATASOURCE_FD:
+            ret = DoSetDataSource(*static_cast<SourceFdParam *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_SET_DATASOURCE_STREAM:
+            ret = DoSetDataSource(*static_cast<StreamSourceParam *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_SETATTR:
+            ret = DoSetMedia(*static_cast<PlayerControlStreamAttr *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_SETSPEED:
+            ret = DoSetPlaybackSpeed(*static_cast<const float *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_SET_VOLUME:
+            ret = DoSetVolume(*static_cast<VolumeAttr *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_SEEK:
+            ret = DoSeek(*static_cast<int64_t *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_GETFILEINFO:
+            ret = DoGetFileInfo(*static_cast<FormatFileInfo *>(msgInfo.msgData));
+            break;
+        case PLAYERCONTROL_MSG_INVOKE:
+            ret = DoInvoke(*static_cast<InvokeParameter *>(msgInfo.msgData));
+            break;
+        default:
+            ret = HI_ERR_PLAYERCONTROL_ILLEGAL_PARAM;
+            break;
+    }
+
+    return ret;
+}
+
+int PlayerControl::HandleMsgWithNoParam(const MsgInfo &msgInfo)
+{
+    int32_t ret;
+    switch (msgInfo.what) {
+        case PLAYERCONTROL_MSG_PREPARE:
+            ret = DoPrepare();
+            break;
+        case PLAYERCONTROL_MSG_PLAY:
+            ret = DoPlay();
+            break;
+        case PLAYERCONTROL_MSG_PAUSE:
+            ret = DoPause();
+            break;
+        case PLAYERCONTROL_MSG_STOP:
+            ret = DoStop();
+            break;
+        case PLAYERCONTROL_MSG_HANDLEDATA:
+            ret = HI_SUCCESS;
+            break;
+        default:
+            ret = HI_ERR_PLAYERCONTROL_ILLEGAL_PARAM;
+            break;
+    }
+
+    return ret;
+}
+
+int PlayerControl::HandleMessage(const MsgInfo &msgInfo)
+{
+    int32_t ret = HI_FAILURE;
+    if (!EventValidAtCurState(static_cast<PlayerControlMsgType>(msgInfo.what))) {
+        MEDIA_ERR_LOG("invalid event :%d at current state: %d", msgInfo.what, GetCurState());
+        return HI_ERR_PLAYERCONTROL_ILLEGAL_STATE_ACTION;
+    }
+
+    switch (msgInfo.what) {
+        case PLAYERCONTROL_MSG_REGCALLBACK:
+        case PLAYERCONTROL_MSG_SET_DATASOURCE_URI:
+        case PLAYERCONTROL_MSG_SET_DATASOURCE_FD:
+        case PLAYERCONTROL_MSG_SET_DATASOURCE_STREAM:
+        case PLAYERCONTROL_MSG_SETATTR:
+        case PLAYERCONTROL_MSG_SETSPEED:
+        case PLAYERCONTROL_MSG_SET_VOLUME:
+        case PLAYERCONTROL_MSG_SEEK:
+        case PLAYERCONTROL_MSG_GETFILEINFO:
+        case PLAYERCONTROL_MSG_INVOKE:
+            ret = HandleMsgWithParam(msgInfo);
+            break;
+        case PLAYERCONTROL_MSG_PAUSE:
+        case PLAYERCONTROL_MSG_PREPARE:
+        case PLAYERCONTROL_MSG_PLAY:
+        case PLAYERCONTROL_MSG_HANDLEDATA:
+        case PLAYERCONTROL_MSG_STOP:
+            ret = HandleMsgWithNoParam(msgInfo);
+            break;
+        default:
+            break;
+    }
+    return ret;
+}
+
+void PlayerControl::OnEventHandled(int event, int result) const
+{
+    if ((result == HI_ERR_PLAYERCONTROL_ILLEGAL_STATE_ACTION) && (event == PLAYERCONTROL_MSG_SEEK)) {
+        NotifyError(PLAYERCONTROL_ERROR_ILLEGAL_STATEACTION);
+    }
+}
+
+int32_t PlayerControl::OnMessageReceived(const MsgInfo &msg)
+{
+    int32_t ret = HandleMessage(msg);
+    if (ret == HI_SUCCESS) {
+        PlayerStatus nextState = FindTransition(GetCurState(), msg.what);
+        curState_ = nextState;
+        StateChangeCallback(curState_);
+    }
+    OnEventHandled(msg.what, ret);
+    return ret;
+}
+
+PlayerStatus PlayerControl::GetCurState(void)
+{
+    return curState_;
+}
+
+PlayerStatus PlayerControl::FindTransition(PlayerStatus state, int32_t event) const
+{
+    for (uint32_t i = 0; i < STATE_TRANS_STATE_SIZE; i++) {
+        if (event == STATE_MACHINE[state][i].msgType) {
+            return STATE_MACHINE[state][i].newState;
+        }
+    }
+    return state;
+}
+
+bool PlayerControl::EventValidAtCurState(PlayerControlMsgType type)
+{
+    if (type < PLAYERCONTROL_MSG_SETATTR || type >= PLAYERCONTROL_MSG_BUTT) {
+        MEDIA_ERR_LOG("EventValidAtCurState MSG type not support %d", type);
+        return false;
+    }
+    if (GetCurState() < 0 || GetCurState() >= PLAY_STATUS_BUTT) {
+        MEDIA_ERR_LOG("EventValidAtCurState cur state not support %d", GetCurState());
+        return false;
+    }
+    return LITEPLAY_STATE[type][GetCurState()];
+}
+bool PlayerControl::UIntMulIsOverflow64(uint64_t a, uint64_t b, uint64_t *value) const
+{
+    if (a == 0 || b == 0) {
+        return false;
+    }
+    if (UINT64_MAX / a < b) {
+        return true;
+    }
+
+    uint64_t result = static_cast<uint64_t>((a) * (b));
+    if (value != nullptr) {
+        *value = result;
+    }
+    return false;
+}
+bool PlayerControl::UIntMulIsOverflow32(uint32_t a, uint32_t b, uint32_t *value) const
+{
+    if (a == 0 || b == 0) {
+        return false;
+    }
+    if (UINT32_MAX / a < b) {
+        return true;
+    }
+
+    long long result = static_cast<long long>((a) * (b));
+    if (value != nullptr) {
+        *value = static_cast<uint32_t>(result);
+    }
+    return false;
+}
+}
+}
index acd3c1d..faccc24 100644 (file)
@@ -283,7 +283,7 @@ private:
     static void *DataSchProcess(void *priv);
     void ReportRenderPosition(void);
     int32_t DoSeekIfNeed(void);
-    void FlushDecoder(void) const;
+    void FlushDecoder(void);
     void EventProcess(EventCbType event);
     void EventQueueProcess(void);
     PlayerStatus GetCurState(void);