567 lines
17 KiB
C++
567 lines
17 KiB
C++
/*----------------------------------------------------------------------------
|
|
* Copyright (c) TJD Technologies Co., Ltd. 2024. All rights reserved.
|
|
*
|
|
* Description:
|
|
*
|
|
* Author: huangshuyi
|
|
*
|
|
* Create: 2024-8
|
|
*--------------------------------------------------------------------------*/
|
|
//brandy-native-tjd -nhso -release
|
|
|
|
#include "TjdUiAppOnlineWfVideoPage.h"
|
|
#include "wearable_log.h"
|
|
#include "common/image_cache_manager.h"
|
|
#include <time.h>
|
|
#include <unordered_map>
|
|
#include "gfx_utils/image_info.h"
|
|
#include "gfx_utils/heap_base.h"
|
|
#include "TjdUiImageIds.h"
|
|
#include "power_display_service.h"
|
|
#include "TjdUiMemManage.h"
|
|
#include "sys_config.h"
|
|
#include "rtc_api.h"
|
|
#include "product_evb4_standard.h"
|
|
#include "common/key_code.h"
|
|
#include "common/image_cache_manager.h"
|
|
#include "sql_setting.h"
|
|
|
|
|
|
using namespace OHOS;
|
|
using namespace OHOS::Media;
|
|
using OHOS::Media::Player;
|
|
|
|
namespace TJD {
|
|
|
|
|
|
#define ENABLE_PRINT_INFO 1
|
|
#if ENABLE_PRINT_INFO
|
|
#define static_print_info(...) sys_ui_log_i(__VA_ARGS__) //一般信息打印宏控制
|
|
#define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) //警告信息打印一般常开
|
|
#define static_print_error(...) sys_ui_log_e(__VA_ARGS__) //错误信息打印一般常开
|
|
#define static_print_debug(...) sys_ui_log_d(__VA_ARGS__)
|
|
#else
|
|
#define static_print_info(...)
|
|
#define static_print_warn(...)
|
|
#define static_print_error(...)
|
|
#define static_print_debug(...)
|
|
#endif
|
|
static constexpr int16_t VIDEO_WIDTH = HORIZONTAL_RESOLUTION;
|
|
static constexpr int16_t VIDEO_HEIGHT = VERTICAL_RESOLUTION;
|
|
static constexpr int16_t STRIDE_ALIGNMENT_VALUE = 128;
|
|
static constexpr int16_t BUFFER_QUEUE_SIZE = 3;
|
|
static constexpr int16_t JPEG_HEIGHT_DIVISOR = 2;
|
|
static constexpr int16_t JPEG_WIDTH_BYTE_ALIGNMENT = 128;
|
|
static constexpr int16_t JPEG_HEIGHT_BYTE_ALIGNMENT = 16;
|
|
static const int32_t WAIT_VIDEO_EXIT_SUCCESS_MS = 10;
|
|
static const int32_t REQUEST_BUFFER_REPET_COUNT = 10;
|
|
static const uint32_t WAIT_VIDEO_EXIT_MAX_RETRY_COUNT = 100;
|
|
static AudioManager &g_amInstance = AudioManager::GetInstance();
|
|
|
|
#define MEDIA_OK 0
|
|
#define MEDIA_INVALID_PARAM (-1)
|
|
#define MEDIA_INIT_FAIL (-2)
|
|
#define MEDIA_ERR (-3)
|
|
#define MEDIA_PERMISSION_DENIED (-4)
|
|
|
|
|
|
TjdUiAppOnlineWfVideoPage::TjdUiAppOnlineWfVideoPage(UIView* parent, std::string uri, std::string previewPath) : Parent_(parent),uri_(uri),previewPath_(previewPath)
|
|
{
|
|
InitView();
|
|
}
|
|
|
|
TjdUiAppOnlineWfVideoPage::~TjdUiAppOnlineWfVideoPage()
|
|
{
|
|
if (videoPlay_ != nullptr) {
|
|
delete videoPlay_;
|
|
videoPlay_ = nullptr;
|
|
static_print_debug("delete videoPlay\n");
|
|
}
|
|
ImageCacheManager::GetInstance().UnloadSingleRes(previewPath_.c_str());
|
|
}
|
|
|
|
UIView *TjdUiAppOnlineWfVideoPage::GetView(void)
|
|
{
|
|
return surfaceView_;
|
|
}
|
|
|
|
bool TjdUiAppOnlineWfVideoPage::InitView(void)
|
|
{
|
|
surfaceView_ = new UILiteSurfaceView();
|
|
if (surfaceView_ == nullptr) {
|
|
GRAPHIC_LOGE("surfaceView is nullptr\n");
|
|
return false;
|
|
}
|
|
UIViewGroup *p = (UIViewGroup *)Parent_;
|
|
p->Add(surfaceView_);
|
|
ImageInfo* imgInfo;
|
|
imgInfo = ImageCacheManager::GetInstance().LoadSingleRes(previewPath_.c_str());
|
|
surfaceView_->SetPreview(imgInfo);
|
|
colorKey_.full = 0xff202020;
|
|
surfaceView_->SetViewId("sur");
|
|
surfaceView_->SetPosition(0, 0, VIDEO_WIDTH, VIDEO_HEIGHT);
|
|
surfaceView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);
|
|
surfaceView_->SetSurfaceColorkey(colorKey_);
|
|
|
|
Surface *surface = surfaceView_->GetSurface();
|
|
surface->SetStrideAlignment(STRIDE_ALIGNMENT_VALUE);
|
|
surface->SetWidthAndHeight(VIDEO_WIDTH, VIDEO_HEIGHT);
|
|
surface->SetQueueSize(BUFFER_QUEUE_SIZE);
|
|
surface->SetFormat(PIXEL_FMT_YCBCR_420_SP);
|
|
|
|
// jpeg decoder output buffer size calculation formula
|
|
int32_t ySize = ALIGN_BYTE(VIDEO_WIDTH, JPEG_WIDTH_BYTE_ALIGNMENT) * VIDEO_HEIGHT;
|
|
int32_t uvSize = ALIGN_BYTE(VIDEO_WIDTH, JPEG_WIDTH_BYTE_ALIGNMENT) *
|
|
ALIGN_BYTE(VIDEO_HEIGHT, JPEG_HEIGHT_BYTE_ALIGNMENT) / JPEG_HEIGHT_DIVISOR;
|
|
int32_t bufferSize = ySize + uvSize;
|
|
surface->SetSize(bufferSize);
|
|
if (videoPlay_ == nullptr) {
|
|
videoPlay_ = new TjdUiVideoCommon(surface, uri_, false);
|
|
videoPlay_->SetSyncExitMode(true);
|
|
}
|
|
//videoPlay_->StartVideoPlay();
|
|
return true;
|
|
}
|
|
|
|
static bool InitPlayerResources(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
videoPlay->mutex_ = MediaMutexCreate(nullptr);
|
|
if (videoPlay->mutex_ == nullptr) {
|
|
static_print_error("create mutex failed\n");
|
|
return false;
|
|
}
|
|
videoPlay->cond_ = MediaThreadCondCreate();
|
|
if (videoPlay->cond_ == nullptr) {
|
|
static_print_error("create thread cond failed\n");
|
|
MediaMutexDestroy(&videoPlay->mutex_);
|
|
return false;
|
|
}
|
|
shared_ptr<Player> player = std::make_shared<Player>();
|
|
if (player == nullptr || player.get() == nullptr) {
|
|
static_print_error("player is nullptr\n");
|
|
MediaMutexDestroy(&videoPlay->mutex_);
|
|
MediaThreadCondDestroy(&videoPlay->cond_);
|
|
return false;
|
|
}
|
|
|
|
videoPlay->player_ = player;
|
|
|
|
videoPlay->isPlaybackCompleted_ = false;
|
|
videoPlay->playError_ = false;
|
|
videoPlay->interruptHintStop_ = false;
|
|
return true;
|
|
}
|
|
|
|
static void DeinitPlayerResources(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
(void)videoPlay->player_.reset();
|
|
videoPlay->isExited_ = true;
|
|
videoPlay->isEntered_ = false;
|
|
(void)MediaThreadCondDestroy(&videoPlay->cond_);
|
|
(void)MediaMutexDestroy(&videoPlay->mutex_);
|
|
}
|
|
|
|
static int32_t VideoPlay(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
std::shared_ptr<PlayerCallback> callback = std::make_shared<TjdUiAppOnlineWfVideoPage::VideoPlayCallback>(videoPlay);
|
|
if (callback == nullptr || callback.get() == nullptr) {
|
|
static_print_error("AlbumVideoPlayer::%s: callback is nullptr", __func__);
|
|
return MEDIA_ERR;
|
|
}
|
|
videoPlay->player_->SetPlayerCallback(callback);
|
|
int32_t ret = videoPlay->player_->Play();
|
|
if (ret != 0) {
|
|
static_print_error("play failed\n");
|
|
(void)videoPlay->player_->Reset();
|
|
(void)videoPlay->player_->Release();
|
|
return MEDIA_ERR;
|
|
}
|
|
videoPlay->player_->EnableSingleLooping(videoPlay->isLoop_);
|
|
MediaMutexLock(videoPlay->mutex_);
|
|
videoPlay->isPlayed_ = true;
|
|
/*若有自定义组件在开始时需要改变,在这里修改*/
|
|
//videoPlay->button_->SetText("Pause");
|
|
while (!videoPlay->isPlaybackCompleted_ && !videoPlay->isPlaybackStopped_ && !videoPlay->interruptHintStop_ &&
|
|
!videoPlay->playError_) {
|
|
MediaThreadCondWait(videoPlay->cond_, videoPlay->mutex_);
|
|
}
|
|
MediaMutexUnLock(videoPlay->mutex_);
|
|
return 0;
|
|
}
|
|
|
|
static void VideoStopAndExit(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
MediaMutexLock(videoPlay->mutex_);
|
|
int32_t ret = videoPlay->player_->Stop();
|
|
if (ret != 0) {
|
|
static_print_error("stop failed");
|
|
}
|
|
ret = videoPlay->player_->Reset();
|
|
if (ret != 0) {
|
|
static_print_error("reset failed");
|
|
}
|
|
videoPlay->isPlaybackCompleted_ = false;
|
|
videoPlay->isPlayed_ = false;
|
|
videoPlay->isPause_ = false;
|
|
/*若有自定义组件需要结束时改变,在这里在修改*/
|
|
//videoPlay->button_->SetText("Play");
|
|
MediaMutexUnLock(videoPlay->mutex_);
|
|
}
|
|
|
|
static int32_t ReleasePlayer(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
(void)videoPlay->player_->Reset();
|
|
(void)videoPlay->player_->Release();
|
|
(void)DeinitPlayerResources(videoPlay);
|
|
return MEDIA_ERR;
|
|
}
|
|
|
|
static void SendBackgroundFrame(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
int32_t ret = videoPlay->player_->Release();
|
|
if (ret != 0) {
|
|
static_print_error("release failed");
|
|
}
|
|
if (!videoPlay->needSendBackgroundFrame_) {
|
|
(void)DeinitPlayerResources(videoPlay);
|
|
return;
|
|
}
|
|
SurfaceBuffer *buf = nullptr;
|
|
int32_t requestCount = 0;
|
|
while ((buf = videoPlay->surface_->RequestBuffer()) == nullptr) {
|
|
if (requestCount++ > REQUEST_BUFFER_REPET_COUNT) {
|
|
static_print_error("request the last buffer failed");
|
|
break;
|
|
}
|
|
LiteSurface *liteSurface = dynamic_cast<LiteSurface *>(videoPlay->surface_);
|
|
if (liteSurface == nullptr) {
|
|
static_print_error("liteSurface is null!");
|
|
break;
|
|
}
|
|
videoPlay->surface_->CancelBuffer(liteSurface->GetBackBuf());
|
|
}
|
|
if (buf != nullptr) {
|
|
buf->format = PIXEL_FMT_BUTT;
|
|
videoPlay->surface_->FlushBuffer(buf);
|
|
}
|
|
(void)DeinitPlayerResources(videoPlay);
|
|
}
|
|
|
|
static Source GetVideoPlaySource(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
Source source;
|
|
if (!videoPlay->uri_.empty()) {
|
|
std::map<std::string, std::string> header;
|
|
source = Source(videoPlay->uri_, header);
|
|
} else if (videoPlay->fd_ > 0) {
|
|
if (videoPlay->isLoop_) {
|
|
int32_t ret = lseek(videoPlay->fd_, 0, SEEK_SET);
|
|
if (ret == -1) {
|
|
static_print_error("lseek[fd = %d] file fail, error[%d]\n", videoPlay->fd_, errno);
|
|
return source;
|
|
}
|
|
}
|
|
source = Source(videoPlay->fd_, videoPlay->offset_, 0);
|
|
}
|
|
return source;
|
|
}
|
|
|
|
static int32_t SetAudioSessionIdAndStreamType(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
int32_t ret = MEDIA_OK;
|
|
if (!videoPlay->isPureVideo_) {
|
|
ret = videoPlay->player_->SetAudioSessionId(videoPlay->sessionId_);
|
|
if (ret != MEDIA_OK) {
|
|
static_print_error("AlbumVideoPlayer::%s: set audio sessionId failed", __func__);
|
|
return ret;
|
|
}
|
|
ret = videoPlay->player_->SetAudioStreamType(AUDIO_STREAM_FITNESS_VIDEO);
|
|
if (ret != MEDIA_OK) {
|
|
static_print_error("AlbumVideoPlayer::%s: set audio stream type failed", __func__);
|
|
return ret;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static int32_t RunVideoPlay(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
bool success = InitPlayerResources(videoPlay);
|
|
if (!success) {
|
|
static_print_error("init player resources failed\n");
|
|
return MEDIA_ERR;
|
|
}
|
|
int32_t ret = 0;
|
|
char filePath[PATH_MAX];
|
|
if (realpath(videoPlay->uri_.c_str(), filePath) == nullptr) {
|
|
static_print_error("no %s resource", videoPlay->uri_.c_str());
|
|
return MEDIA_ERR;
|
|
}
|
|
Source source = GetVideoPlaySource(videoPlay);
|
|
ret = videoPlay->player_->SetSource(source);
|
|
if (ret != 0) {
|
|
static_print_error("set source failed\n");
|
|
(void)DeinitPlayerResources(videoPlay);
|
|
return MEDIA_ERR;
|
|
}
|
|
ret = videoPlay->player_->Prepare();
|
|
if (ret != 0) {
|
|
static_print_error("prepare failed\n");
|
|
return ReleasePlayer(videoPlay);
|
|
}
|
|
ret = SetAudioSessionIdAndStreamType(videoPlay);
|
|
if (ret != 0) {
|
|
return ReleasePlayer(videoPlay);
|
|
}
|
|
|
|
ret = videoPlay->player_->SetVideoSurface(videoPlay->surface_);
|
|
if (ret != 0) {
|
|
static_print_error("set video surface failed\n");
|
|
return ReleasePlayer(videoPlay);
|
|
}
|
|
ret = VideoPlay(videoPlay);
|
|
if (ret != 0) {
|
|
return ReleasePlayer(videoPlay);
|
|
}
|
|
VideoStopAndExit(videoPlay);
|
|
SendBackgroundFrame(videoPlay);
|
|
return 0;
|
|
}
|
|
|
|
static bool RequsetAudioFocus(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
if (videoPlay->isPureVideo_) {
|
|
return true;
|
|
}
|
|
bool success = g_amInstance.Initialize();
|
|
if (!success) {
|
|
static_print_error("AlbumVideoPlayer::%s: audiomanager init failed", __func__);
|
|
return false;
|
|
}
|
|
|
|
AudioSession sessionId = g_amInstance.MakeSessionId();
|
|
if (sessionId == AUDIO_SESSION_ID_NONE) {
|
|
static_print_error("AlbumVideoPlayer::%s: audio session id invalid", __func__);
|
|
return false;
|
|
}
|
|
|
|
std::shared_ptr<TjdUiAppOnlineWfVideoPage::VideoPlayerInterruptListener> interruptListener =
|
|
std::make_shared<TjdUiAppOnlineWfVideoPage::VideoPlayerInterruptListener>(videoPlay);
|
|
if (interruptListener == nullptr || interruptListener.get() == nullptr) {
|
|
static_print_error("AlbumVideoPlayer::%s: video player interrupt listener is nullptr", __func__);
|
|
return false;
|
|
}
|
|
|
|
AudioInterrupt interrupt = {AUDIO_STREAM_FITNESS_VIDEO, sessionId, interruptListener};
|
|
if (g_amInstance.ActivateAudioInterrupt(interrupt) == INTERRUPT_FAILED) {
|
|
static_print_error("AlbumVideoPlayer::%s: activate audio interrupt failed", __func__);
|
|
return false;
|
|
}
|
|
|
|
videoPlay->sessionId_ = sessionId;
|
|
videoPlay->interrupt_ = interrupt;
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool ReleaseAudioFocus(TjdUiVideoCommon *videoPlay)
|
|
{
|
|
if (videoPlay->isPureVideo_) {
|
|
return true;
|
|
}
|
|
if (g_amInstance.DeactivateAudioInterrupt(videoPlay->interrupt_) != 0) {
|
|
static_print_error("AlbumVideoPlayer::%s: deactivate audio interrupt failed", __func__);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
int32_t TjdUiVideoCommon::StartVideoPlay(void)
|
|
{
|
|
if (isEntered_) {
|
|
static_print_info("video play is not stop, can not start!");
|
|
return MEDIA_OK;
|
|
}
|
|
isExited_ = false;
|
|
isEntered_ = true;
|
|
MediaThreadattr attr = {"VideoPlayThread", 0x2000, THREAD_SCHED_INVALID, 0, true};
|
|
if (isSyncExitMode_) {
|
|
attr.detached = false;
|
|
}
|
|
|
|
threadHandle_ = MediaThreadCreate(VideoPlayThread, this, &attr);
|
|
if (threadHandle_ == NULL) {
|
|
static_print_error("create thread failed\n");
|
|
return MEDIA_ERR;
|
|
}
|
|
//play = this;
|
|
return MEDIA_OK;
|
|
}
|
|
|
|
int32_t TjdUiVideoCommon::PauseVideoPlay(void)
|
|
{
|
|
MediaMutexLock(mutex_);
|
|
if (player_ == NULL) {
|
|
static_print_error("can not pause play");
|
|
MediaMutexUnLock(mutex_);
|
|
return MEDIA_ERR;
|
|
}
|
|
if (isPlaybackStopped_ || isPlaybackCompleted_ || interruptHintStop_) {
|
|
static_print_error("current state is stop, can not pause play");
|
|
MediaMutexUnLock(mutex_);
|
|
return MEDIA_ERR;
|
|
}
|
|
int32_t ret = player_->Pause();
|
|
if (ret != MEDIA_OK) {
|
|
static_print_error("pause failed");
|
|
MediaMutexUnLock(mutex_);
|
|
return MEDIA_ERR;
|
|
}
|
|
isPause_ = true;
|
|
MediaMutexUnLock(mutex_);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int32_t TjdUiVideoCommon::ResumeVideoPlay(void)
|
|
{
|
|
MediaMutexLock(mutex_);
|
|
if (player_ == NULL) {
|
|
static_print_error("can not resume play");
|
|
MediaMutexUnLock(mutex_);
|
|
return MEDIA_ERR;
|
|
}
|
|
if (isPlaybackStopped_ || isPlaybackCompleted_ || interruptHintStop_) {
|
|
static_print_error("current state is stop, can not resume play");
|
|
MediaMutexUnLock(mutex_);
|
|
return MEDIA_ERR;
|
|
}
|
|
int32_t ret = player_->Play();
|
|
if (ret != MEDIA_OK) {
|
|
static_print_error("resume failed");
|
|
MediaMutexUnLock(mutex_);
|
|
return ret;
|
|
}
|
|
isPause_ = false;
|
|
MediaMutexUnLock(mutex_);
|
|
return ret;
|
|
}
|
|
|
|
int32_t TjdUiVideoCommon::StopVideoPlay(void)
|
|
{
|
|
|
|
MediaMutexLock(mutex_);
|
|
|
|
if (isPlaybackStopped_ || isPlaybackCompleted_ || interruptHintStop_) {
|
|
if (isLoop_) {
|
|
if (!isPlaybackCompleted_) {
|
|
static_print_info("video play already stopped");
|
|
MediaMutexUnLock(mutex_);
|
|
return MEDIA_OK;
|
|
}
|
|
} else {
|
|
static_print_info("video play already stopped");
|
|
MediaMutexUnLock(mutex_);
|
|
return MEDIA_OK;
|
|
}
|
|
}
|
|
isPlaybackStopped_ = true;
|
|
MediaThreadCondSignal(cond_);
|
|
MediaMutexUnLock(mutex_);
|
|
if (isSyncExitMode_) {
|
|
MediaThreadJoin(&threadHandle_);
|
|
isPlaybackStopped_ = false;
|
|
dynamic_cast<LiteSurface *>(surface_)
|
|
->ClearBuffers(); // clear buffers safely in sync mode to reduce peak memory
|
|
}
|
|
//play = nullptr;
|
|
return MEDIA_OK;
|
|
}
|
|
|
|
void TjdUiVideoCommon::DestroyVideoPlaySource(void)
|
|
{
|
|
needSendBackgroundFrame_ = false;
|
|
StopVideoPlay();
|
|
uint32_t count = 0;
|
|
while (!IsExitCompletely()) {
|
|
count++;
|
|
if (count == WAIT_VIDEO_EXIT_MAX_RETRY_COUNT) {
|
|
static_print_error("media video play exit timeout\n");
|
|
break;
|
|
}
|
|
usleep(WAIT_VIDEO_EXIT_SUCCESS_MS);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void *TjdUiVideoCommon::VideoPlayThread(void *arg)
|
|
{
|
|
TjdUiVideoCommon *videoPlay = (TjdUiVideoCommon *)arg;
|
|
if (videoPlay->isPlayed_) {
|
|
static_print_error("the video is playing.\n");
|
|
return nullptr;
|
|
}
|
|
|
|
bool success = RequsetAudioFocus(videoPlay);
|
|
if (!success) {
|
|
static_print_error("AlbumVideoPlayer::%s: requset audio focus failed", __func__);
|
|
return nullptr;
|
|
}
|
|
|
|
int32_t ret = RunVideoPlay(videoPlay);
|
|
if (ret != 0) {
|
|
static_print_error("run video play failed\n");
|
|
(void)ReleaseAudioFocus(videoPlay);
|
|
return nullptr;
|
|
}
|
|
|
|
success = ReleaseAudioFocus(videoPlay);
|
|
if (!success) {
|
|
static_print_error("AlbumVideoPlayer::%s: release audio focus failed", __func__);
|
|
return nullptr;
|
|
}
|
|
static_print_error("exit all!\n");
|
|
return nullptr;
|
|
}
|
|
|
|
int32_t TjdUiVideoCommon::GetDumpInfo(PlayerDebugInfo *playerInfo)
|
|
{
|
|
MediaMutexLock(mutex_);
|
|
if (player_ == NULL) {
|
|
static_print_error("can not get dump info!");
|
|
MediaMutexUnLock(mutex_);
|
|
return MEDIA_ERR;
|
|
}
|
|
int32_t ret = player_->DumpInfo(playerInfo);
|
|
if (ret != MEDIA_OK) {
|
|
static_print_error("get dump info failed");
|
|
MediaMutexUnLock(mutex_);
|
|
return ret;
|
|
}
|
|
MediaMutexUnLock(mutex_);
|
|
return ret;
|
|
}
|
|
|
|
void TjdUiVideoCommon::SetVideoPlayLoop(bool isLoop)
|
|
{
|
|
MediaMutexLock(mutex_);
|
|
isLoop_ = isLoop;
|
|
MediaMutexUnLock(mutex_);
|
|
}
|
|
|
|
void TjdUiVideoCommon::SetSyncExitMode(bool isSyncExitMode)
|
|
{
|
|
MediaMutexLock(mutex_);
|
|
if (!isEntered_) {
|
|
isSyncExitMode_ = isSyncExitMode;
|
|
}
|
|
MediaMutexUnLock(mutex_);
|
|
}
|
|
|
|
bool TjdUiVideoCommon::IsExitCompletely(void) { return isExited_; }
|
|
}
|