Browse Source

Z991239-2055 #comment fix: 解决本地媒体播放存在稳定性问题和音频少一个字问题

陈礼鹏80274480 4 years ago
parent
commit
d2f7d357de

+ 15 - 3
Module/mod_localmediaplay/mod_localmediaplay.cpp

@@ -52,6 +52,15 @@ void* queryMedia(void* param)
 
 	return 0;
 }
+
+void sig_handler(int signum)
+{
+	if (SIGTERM == signum){
+		int ipid = getpid();
+		kill(ipid, SIGKILL);
+	}
+}
+
 #endif // RVC_OS_WIN
 
 
@@ -95,6 +104,7 @@ CLocalMediaPlayEntity::~CLocalMediaPlayEntity()
 	if (0 == pthread_join(m_scanThreadId, NULL)) {
 		Dbg("pthread join scanThreadId success.");
 	}
+	
 #endif // RVC_OS_WIN
 }
 
@@ -432,7 +442,7 @@ int CLocalMediaPlayEntity::LoadPlayConfig(CPicPlayConfig& config, int CfgInx)
 
 void CLocalMediaPlayEntity::Debug(media_loglevel log_level, const char* fmt, ...)
 {
-	if (log_level >= MEDIA_LOG_ERROR){
+	if (log_level >= MEDIA_LOG_DEBUG){
 		va_list arg;
 		va_start(arg, fmt);
 		vDbg(fmt, arg);
@@ -531,7 +541,6 @@ void CLocalMediaPlayEntity::OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmar
 
 ErrorCodeEnum CLocalMediaPlayEntity::__OnStart(ErrorCodeEnum preOperationError)
 {
-	LOG_FUNCTION();
 #ifdef RVC_OS_WIN
 	//toolkit_setenv("SDL_AUDIODRIVER", "winmm");
 #endif // RVC_OS_WIN
@@ -552,6 +561,8 @@ ErrorCodeEnum CLocalMediaPlayEntity::__OnStart(ErrorCodeEnum preOperationError)
 	m_pAudioPlayer = new Clibwmpplayer(this);
 #else
 	m_pMediaAudioPlayer = new Clibmediaplayer(this);
+	signal(SIGTERM, sig_handler);
+
 #endif // RVC_OS_WIN
 
 	if (!IsRunConfigExist())
@@ -583,15 +594,16 @@ ErrorCodeEnum CLocalMediaPlayEntity::__OnStart(ErrorCodeEnum preOperationError)
 	return Error_Succeed;
 }
 
+
 void CLocalMediaPlayEntity::OnPreClose(EntityCloseCauseEnum eCloseCause, CSmartPointer<ITransactionContext> pTransactionContext)
 {
+	LOG_FUNCTION();
 	ErrorCodeEnum Error = __OnClose(Error_Succeed);
 	pTransactionContext->SendAnswer(Error);
 }
 
 ErrorCodeEnum CLocalMediaPlayEntity::__OnClose(ErrorCodeEnum preOperationError)
 {
-	LOG_FUNCTION();
 	for (int i = 0; i != MAX_PLAY_CHANNELS; ++i)
 	{
 #ifdef RVC_OS_WIN

+ 11 - 9
Other/libmediaplayer/audio.cpp

@@ -9,11 +9,11 @@ static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
 {
     int ret = -1;
 
-    while (0 == p_pkt_queue->abort_request)
+    while (0 == p_pkt_queue->abort_flag)
     {
 		AVPacket pkt = {0};
 
-        while (0 == p_pkt_queue->abort_request)
+        while (0 == p_pkt_queue->abort_flag)
         {
             //if (d->queue->abort_request)
             //    return -1;
@@ -131,7 +131,7 @@ static int audio_decode_thread(void *arg)
             tb = { 1, p_frame->sample_rate };
 
 			//从frame队列找到一个可写的空间,若未停止则一直等待,已停止时返回NULL
-			if (!(af = frame_queue_peek_writable(&is->audio_frm_queue))) {
+			if (!(af = frame_queue_peek_writable(&is->audio_frm_queue, !is->bread_finished))) {
 				is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "frame_queue_peek_writable return NULL, goto end.");
 				goto the_end;
 			}
@@ -151,8 +151,8 @@ static int audio_decode_thread(void *arg)
 the_end:
 
     av_frame_free(&p_frame);
-	SDL_Delay(100);
-	is->abort_request = 1;
+	//SDL_Delay(100);
+	//is->abort_request = 1;
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio decode thread exit, thread id is %u, and is->abort_request = %d", SDL_ThreadID(), is->abort_request);
     
 	return ret;
@@ -234,7 +234,8 @@ static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
 #endif
 
     // 若队列头部可读,则由af指向可读帧
-	if (!(af = frame_queue_peek_readable(&is->audio_frm_queue))) {
+	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "%s:%d is->bread_finished=%d", __FUNCTION__, __LINE__, is->bread_finished);
+	if (!(af = frame_queue_peek_readable(&is->audio_frm_queue, !is->bread_finished))) {
 		is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "%s:%d abort_request flag is true, function return", __FUNCTION__, __LINE__);
 		return -2;
 	}
@@ -372,8 +373,8 @@ static int open_audio_playing(void *arg)
 	
 	int iaudioapeaker = SDL_GetNumAudioDevices(0);
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio output device number is %d.", iaudioapeaker);
-	for (int i = 0; i < iaudioapeaker; i++){
-		is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "device id %d audio device name is %s.",i, SDL_GetAudioDeviceName(i, 0));
+	for (int i = 0; i < iaudioapeaker; i++) {
+		is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "device id %d audio device name is %s.", i, SDL_GetAudioDeviceName(i, 0));
 	}
 
 	if (SDL_OpenAudio(&wanted_spec, &actual_spec) < 0){
@@ -425,7 +426,7 @@ static int open_audio_playing(void *arg)
 	//SDL_PauseAudioDevice(idev, 0);
 
 	while (is->abort_request == 0){
-		SDL_Delay(1);
+		SDL_Delay(10);
 	}
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "----------%s:%d before SDL Close Audio", __FUNCTION__, __LINE__);
 	SDL_CloseAudio();
@@ -460,6 +461,7 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
 			if (audio_size < 0){
 				if (-2 == audio_size) {
 					is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio_size is -2 sdl_audio_callback return.");
+					is->on_audio_play_finished(is->user_data);
 					return;
 				}
                 /* if error, just output silence */

+ 4 - 3
Other/libmediaplayer/demux.cpp

@@ -94,7 +94,7 @@ int demux_deinit()
 static int stream_has_enough_packets(AVStream *st, int stream_id, packet_queue_t *queue)
 {
     return stream_id < 0 ||
-           queue->abort_request ||
+           queue->abort_flag ||
            (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
            queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
 }
@@ -183,8 +183,9 @@ static int demux_thread(void *arg)
     }
 
     SDL_DestroyMutex(wait_mutex);
-	SDL_Delay(100);
-	is->abort_request = 1;
+	//SDL_Delay(100);
+	//is->abort_request = 1;
+	is->bread_finished = true;
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "%s exit, thread id is %u, and is->abort_request = %d",SDL_GetThreadName(is->read_tid), SDL_ThreadID(), is->abort_request);
 
     return 0;

+ 43 - 30
Other/libmediaplayer/frame.cpp

@@ -9,17 +9,14 @@ void frame_queue_unref_item(frame_t *vp)
 int frame_queue_init(frame_queue_t *f, packet_queue_t *pktq, int max_size, int keep_last)
 {
     memset(f, 0, sizeof(frame_queue_t));
-    if (!(f->mutex = SDL_CreateMutex())) {
-        //printf("SDL_CreateMutex(): %s\n", SDL_GetError());
+    if (!(f->frame_mutex = SDL_CreateMutex())) {
         return AVERROR(ENOMEM);
     }
-    if (!(f->cond = SDL_CreateCond())) {
-		//printf("SDL_CreateCond(): %s\n", SDL_GetError());
+    if (!(f->frame_cond = SDL_CreateCond())) {
         return AVERROR(ENOMEM);
     }
     f->pktq = pktq;
     f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
-	//printf("frame_queue_t max_size is %d.\n", f->max_size);
     f->keep_last = !!keep_last;
 
 	for (int i = 0; i < f->max_size; i++) {
@@ -37,15 +34,15 @@ void frame_queue_destory(frame_queue_t *f)
         frame_queue_unref_item(vp);
         av_frame_free(&vp->frame);
     }
-    SDL_DestroyMutex(f->mutex);
-    SDL_DestroyCond(f->cond);
+    SDL_DestroyMutex(f->frame_mutex);
+    SDL_DestroyCond(f->frame_cond);
 }
 
 void frame_queue_signal(frame_queue_t *f)
 {
-    SDL_LockMutex(f->mutex);
-    SDL_CondSignal(f->cond);
-    SDL_UnlockMutex(f->mutex);
+    SDL_LockMutex(f->frame_mutex);
+    SDL_CondSignal(f->frame_cond);
+    SDL_UnlockMutex(f->frame_mutex);
 }
 
 frame_t *frame_queue_peek(frame_queue_t *f)
@@ -65,17 +62,26 @@ frame_t *frame_queue_peek_last(frame_queue_t *f)
 }
 
 // 向队列尾部申请一个可写的帧空间,若无空间可写,则等待
-frame_t *frame_queue_peek_writable(frame_queue_t *f)
+frame_t *frame_queue_peek_writable(frame_queue_t *f, bool bwait)
 {
+	bool bexit = false;
     /* wait until we have space to put a new frame */
-    SDL_LockMutex(f->mutex);
-    while (f->size >= f->max_size && !f->pktq->abort_request) {
-		//printf("f->size >= f->max_size && !f->pktq->abort_request, continue wait.\n");
-        SDL_CondWait(f->cond, f->mutex);
+    SDL_LockMutex(f->frame_mutex);
+    while (f->size >= f->max_size && !f->pktq->abort_flag) {
+		if (bwait){
+			//printf("f->size >= f->max_size && !f->pktq->abort_flag, continue wait.\n");
+			SDL_CondWait(f->frame_cond, f->frame_mutex);
+		}
+		else
+		{
+			bexit = true;
+			break;
+		}
+
     }
-    SDL_UnlockMutex(f->mutex);
+    SDL_UnlockMutex(f->frame_mutex);
 
-	if (f->pktq->abort_request) {
+	if (f->pktq->abort_flag || bexit) {
 		return NULL;
 	}
 
@@ -83,17 +89,24 @@ frame_t *frame_queue_peek_writable(frame_queue_t *f)
 }
 
 // 从队列头部读取一帧,只读取不删除,若无帧可读则等待
-frame_t *frame_queue_peek_readable(frame_queue_t *f)
+frame_t *frame_queue_peek_readable(frame_queue_t *f, bool bwait)
 {
     /* wait until we have a readable a new frame */
-    SDL_LockMutex(f->mutex);
-    while (f->size - f->rindex_shown <= 0 && !f->pktq->abort_request) {
-		//printf("f->size - f->rindex_shown = %d,  f->pktq->abort_request = %d, continue wait.\n", f->size - f->rindex_shown , f->pktq->abort_request);
-        SDL_CondWait(f->cond, f->mutex);
+	bool bexit = false;
+    SDL_LockMutex(f->frame_mutex);
+    while (f->size - f->rindex_shown <= 0 && !f->pktq->abort_flag) {
+		if (bwait){
+			//printf("f->size-f->rindex_shown=%d,f->pktq->abort_flag=%d,wait flag is %d.\n", f->size - f->rindex_shown, f->pktq->abort_flag, bwait);
+			SDL_CondWait(f->frame_cond, f->frame_mutex);
+		}
+		else {
+			bexit = true;
+			break;
+		}
     }
-    SDL_UnlockMutex(f->mutex);
+    SDL_UnlockMutex(f->frame_mutex);
 
-	if (f->pktq->abort_request) {
+	if (f->pktq->abort_flag || bexit) {
 		return NULL;
 	}
 
@@ -106,11 +119,11 @@ void frame_queue_push(frame_queue_t *f)
 	if (++f->windex == f->max_size) {
 		f->windex = 0;
 	}
-    SDL_LockMutex(f->mutex);
+    SDL_LockMutex(f->frame_mutex);
     f->size++;
 	//printf("frame_queue_push, CondSignal cond.\n");
-    SDL_CondSignal(f->cond);
-    SDL_UnlockMutex(f->mutex);
+    SDL_CondSignal(f->frame_cond);
+    SDL_UnlockMutex(f->frame_mutex);
 }
 
 // 读指针(rindex)指向的帧已显示,删除此帧,注意不读取直接删除。读指针加1
@@ -124,11 +137,11 @@ void frame_queue_next(frame_queue_t *f)
 	if (++f->rindex == f->max_size) {
 		f->rindex = 0;
 	}
-    SDL_LockMutex(f->mutex);
+    SDL_LockMutex(f->frame_mutex);
     f->size--;
 	//printf("frame_queue_next, CondSignal cond.\n");
-	SDL_CondSignal(f->cond);
-    SDL_UnlockMutex(f->mutex);
+	SDL_CondSignal(f->frame_cond);
+    SDL_UnlockMutex(f->frame_mutex);
 }
 
 // frame_queue中未显示的帧数

+ 2 - 2
Other/libmediaplayer/frame.h

@@ -9,8 +9,8 @@ void frame_queue_signal(frame_queue_t *f);
 frame_t *frame_queue_peek(frame_queue_t *f);
 frame_t *frame_queue_peek_next(frame_queue_t *f);
 frame_t *frame_queue_peek_last(frame_queue_t *f);
-frame_t *frame_queue_peek_writable(frame_queue_t *f);
-frame_t *frame_queue_peek_readable(frame_queue_t *f);
+frame_t *frame_queue_peek_writable(frame_queue_t *f, bool bwait);
+frame_t *frame_queue_peek_readable(frame_queue_t *f, bool bwait);
 void frame_queue_push(frame_queue_t *f);
 void frame_queue_next(frame_queue_t *f);
 int frame_queue_nb_remaining(frame_queue_t *f);

+ 2 - 2
Other/libmediaplayer/libmediaplayer.cpp

@@ -246,8 +246,8 @@ public:
 			return iRet;
 		}
 
-		t_param.udisplaycx = SDL_WINDOWPOS_UNDEFINED;
-		t_param.udisplaycy = SDL_WINDOWPOS_UNDEFINED;
+		t_param.idisplaycx = SDL_WINDOWPOS_UNDEFINED;
+		t_param.idisplaycy = SDL_WINDOWPOS_UNDEFINED;
 		t_param.bvicemonitor = true;
 
 		play_media_callback_t cb;

+ 1 - 1
Other/libmediaplayer/libmediaplayer.h

@@ -43,4 +43,4 @@ public:
 
 private:
 	libmediaplayer_impl* m_pImpl;
-};
+};

+ 3 - 3
Other/libmediaplayer/packet.cpp

@@ -15,7 +15,7 @@ int packet_queue_init(packet_queue_t *q, CMediaHostApi* hostapi)
 		hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_CreateCond(): %s.", SDL_GetError());
         return AVERROR(ENOMEM);
     }
-    q->abort_request = 0;
+    q->abort_flag = 0;
     return 0;
 }
 
@@ -69,7 +69,7 @@ int packet_queue_get(packet_queue_t *q, AVPacket *pkt, int block)
 
     SDL_LockMutex(q->mutex);
 
-    while (0 == q->abort_request)
+    while (0 == q->abort_flag)
     {
         p_pkt_node = q->first_pkt;
         if (p_pkt_node)             // 队列非空,取一个出来
@@ -143,7 +143,7 @@ void packet_queue_destroy(packet_queue_t *q, CMediaHostApi* m_hostapi)
 void packet_queue_abort(packet_queue_t *q, CMediaHostApi* m_hostapi)
 {
     SDL_LockMutex(q->mutex);
-    q->abort_request = 1;
+    q->abort_flag = 1;
 	//m_hostapi->Debug("packet_queue_abort, CondSignal cond.");
     SDL_CondSignal(q->cond);
     SDL_UnlockMutex(q->mutex);

+ 49 - 23
Other/libmediaplayer/player.cpp

@@ -133,6 +133,7 @@ static int player_deinit(player_stat_t *is)
 			is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "%s:%d is->img_convert_ctx[%d] = 0x%0x", __FUNCTION__, __LINE__, index, is->img_convert_ctx[index]);
 			if (NULL != is->img_convert_ctx[index]) {
 				sws_freeContext(is->img_convert_ctx[index]);
+				is->img_convert_ctx[index] = NULL;
 			}
 		}
 	}
@@ -145,6 +146,7 @@ static int player_deinit(player_stat_t *is)
     }
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "av_free player_stat_t.");
     av_free(is);
+
     return 0;
 }
 
@@ -191,18 +193,37 @@ CMediaPlayer::CMediaPlayer(CMediaHostApi* pHostApi)
 	else {
 		m_hostapi->Debug(MEDIA_LOG_DEBUG, "new CMediaPlayer failed!");
 	}
+
+	Uint32 uRet = SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
+
+	if (0 == uRet){
+		if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
+		{
+			m_hostapi->Debug(MEDIA_LOG_ERROR, "Could not initialize SDL - %s", SDL_GetError());
+			m_hostapi->Debug(MEDIA_LOG_ERROR, "(Did you set the DISPLAY variable?)");
+		}
+		else {
+			uRet = SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
+			m_hostapi->Debug(MEDIA_LOG_DEBUG, "initialize SDL success, and init ret = %d.", uRet);
+		}
+	}
 }
 
 CMediaPlayer::~CMediaPlayer()
 {
-	if (NULL != m_player_stat){
+	if (NULL != m_player_stat) {
 		player_deinit(m_player_stat);
 		m_player_stat = NULL;
 	}
 
-	if(NULL != m_piconpath){
+	if (NULL != m_piconpath) {
 		av_free(m_piconpath);
 	}
+
+	Uint32 uRet = SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
+	if (0 != uRet) {
+		SDL_Quit();
+	}
 }
 
 
@@ -214,6 +235,20 @@ static int audio_volume_callback(int* audiovolume, void* userdata)
 }
 
 
+static int audio_play_finished_callback(void* userdata)
+{
+	CMediaPlayer* player = (CMediaPlayer*)userdata;
+	player->SetFinishedFlag();
+	
+	return 0;
+}
+
+bool CMediaPlayer::SetFinishedFlag()
+{
+	m_player_stat->abort_request = 1;
+	return true;
+}
+
 uint8_t CMediaPlayer::GetVolume()
 {
 	return m_uvolume;
@@ -237,14 +272,18 @@ int CMediaPlayer::Initialize_Player_Stat(rvc_media_player_param_t* pMedia_Player
 		return iRet;
 	}
 
+	m_player_stat->bread_finished = false;
 	m_player_stat->rvc_hostapi = m_hostapi;
 	m_player_stat->prvc_cb = pMedia_Player->cb;
 	m_player_stat->eMType = pMedia_Player->eType;
 	m_player_stat->eWindType = pMedia_Player->eWindType;
 	m_player_stat->bvice_monitor = pMedia_Player->bvicemonitor;
-	m_player_stat->iDisplayCx = pMedia_Player->udisplaycx;
-	m_player_stat->iDisplayCy = pMedia_Player->udisplaycy;
+	m_player_stat->iDisplayCx = pMedia_Player->idisplaycx;
+	m_player_stat->iDisplayCy = pMedia_Player->idisplaycy;
+	m_player_stat->iDisplayWidth = pMedia_Player->idisplaywidth;
+	m_player_stat->iDisplayHeight = pMedia_Player->idisplayheight;
 	m_player_stat->on_audio_volume = &audio_volume_callback;
+	m_player_stat->on_audio_play_finished = &audio_play_finished_callback;
 	m_player_stat->user_data = this;
 	if (NULL != m_piconpath){
 		m_player_stat->piconpath = av_strdup(m_piconpath);
@@ -272,7 +311,7 @@ int CMediaPlayer::GetViceVideoDisplayInfo(int* icx, int* icy, int* iwidth, int*
 	int iRet = -1;
 	size_t uCount = SDL_GetNumVideoDisplays();
 	m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays Number is %d.", uCount);
-	SDL_DisplayMode dispalymode[RVC_MAX_DISPLAYNUM] = {0};
+	SDL_DisplayMode dispalymode[RVC_MAX_DISPLAYNUM] = { 0 };
 	for (size_t i = 0; i < uCount && i < RVC_MAX_DISPLAYNUM; i++) {
 		SDL_GetDesktopDisplayMode(i, &dispalymode[i]);
 		m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} format = %d", i, dispalymode[i].format);
@@ -280,7 +319,7 @@ int CMediaPlayer::GetViceVideoDisplayInfo(int* icx, int* icy, int* iwidth, int*
 		m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} h = %d", i, dispalymode[i].h);
 		m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} refresh_rate = %d", i, dispalymode[i].refresh_rate);
 	}
-	if (uCount > 1){
+	if (uCount > 1) {
 		*icx = dispalymode[0].w;
 		*icy = 0;
 		*iwidth = dispalymode[1].w;
@@ -345,24 +384,11 @@ int CMediaPlayer::Init(rvc_media_player_param_t* pMedia_Player)
 
 	m_player_stat->abort_request = 0;
 
-	uint32_t usdl_flag = SDL_INIT_AUDIO | SDL_INIT_TIMER;
-	if (eVideo_Type == m_player_stat->eMType){
-		usdl_flag |= SDL_INIT_VIDEO;
-	}
-
-	if (SDL_Init(usdl_flag))
-	{
-		m_hostapi->Debug(MEDIA_LOG_DEBUG, "Could not initialize SDL - %s", SDL_GetError());
-		m_hostapi->Debug(MEDIA_LOG_DEBUG, "(Did you set the DISPLAY variable?)");
-	}
-	else {
-		iRet = 0;
-	}
-
-	if (eVideo_Type == m_player_stat->eMType && m_player_stat->bvice_monitor){
+	if (m_player_stat->bvice_monitor){
 		if (0 == GetViceVideoDisplayInfo(&m_player_stat->iDisplayCx, &m_player_stat->iDisplayCy, &m_player_stat->iDisplayWidth, &m_player_stat->iDisplayHeight)){
-			m_hostapi->Debug(MEDIA_LOG_DEBUG, "display cx is %d, cy is %d, width is %d, height is %d.", m_player_stat->iDisplayCx, m_player_stat->iDisplayCy, m_player_stat->iDisplayWidth, m_player_stat->iDisplayHeight);
+			m_hostapi->Debug(MEDIA_LOG_DEBUG,"display cx is %d, cy is %d, width is %d, height is %d.", m_player_stat->iDisplayCx, m_player_stat->iDisplayCy, m_player_stat->iDisplayWidth, m_player_stat->iDisplayHeight);
 		}
+
 	}
 	
 	iRet = 0;
@@ -476,7 +502,7 @@ int CMediaPlayer::ExitMediaPlayingThread()
 
 	avformat_network_deinit();
 
-	SDL_Quit();
+	//SDL_Quit();
 
 	iRet = 0;
 

+ 11 - 5
Other/libmediaplayer/player.h

@@ -104,7 +104,7 @@ typedef struct packet_queue_s{
     int nb_packets;                 // 队列中packet的数量
     int size;                       // 队列所占内存空间大小
     int64_t duration;               // 队列中所有packet总的播放时长
-    int abort_request;
+    int abort_flag;
     int serial;                     // 播放序列,所谓播放序列就是一段连续的播放动作,一个seek操作会启动一段新的播放序列
     SDL_mutex *mutex;
     SDL_cond *cond;
@@ -133,8 +133,8 @@ typedef struct frame_queue_s{
     int max_size;                   // 队列可存储最大帧数
     int keep_last;
     int rindex_shown;               // 当前是否有帧在显示
-    SDL_mutex *mutex;
-    SDL_cond *cond;
+    SDL_mutex *frame_mutex;
+    SDL_cond *frame_cond;
     packet_queue_t *pktq;           // 指向对应的packet_queue
 }frame_queue_t;
 
@@ -199,6 +199,8 @@ typedef struct player_stat_s{
     int paused;
     int step;
 
+	bool bread_finished;
+
     SDL_cond *continue_read_thread;
     SDL_Thread *read_tid;           // demux解复用线程
 	
@@ -219,6 +221,7 @@ typedef struct player_stat_s{
 	int iDisplayWidth;
 	int iDisplayHeight;
 	int (*on_audio_volume)(int* audiodata, void* user_data);
+	int (*on_audio_play_finished)(void* user_data);
 	void* user_data;
 }player_stat_t;
 
@@ -227,8 +230,10 @@ typedef struct rvc_media_player_param_s{
 	char* p_input_file;
 	eMediaType_t eType;
 	eWindType_t eWindType;
-	int udisplaycx;
-	int udisplaycy;
+	int idisplaycx;
+	int idisplaycy;
+	int idisplaywidth;
+	int idisplayheight;
 	bool bvicemonitor;
 	char strPlayLists[MAX_FILECOUNT][MAX_PATH];		//播放列表,全路径
 	uint uFilesCount;								//播放文件数
@@ -257,6 +262,7 @@ public:
 	int64_t GetMediaPlayingThreadId();
 	int GetViceVideoDisplayInfo(int* icx, int* icy, int* iwidth, int* iheight);
 	uint8_t GetVolume();
+	bool SetFinishedFlag();
 
 private:
 	player_stat_t* m_player_stat;

+ 7 - 6
Other/libmediaplayer/video.cpp

@@ -7,7 +7,7 @@ static int queue_picture(player_stat_t *is, AVFrame *src_frame, double pts, doub
 {
     frame_t *vp = NULL;
 
-	if (!(vp = frame_queue_peek_writable(&is->video_frm_queue))) {
+	if (!(vp = frame_queue_peek_writable(&is->video_frm_queue, !is->bread_finished))) {
 		return -1;
 	}
 
@@ -38,10 +38,10 @@ static int video_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
 {
     int ret;
     
-    while (0 == p_pkt_queue->abort_request)
+    while (0 == p_pkt_queue->abort_flag)
     {
 		AVPacket pkt = {0};
-        while (0 == p_pkt_queue->abort_request)
+        while (0 == p_pkt_queue->abort_flag)
         {
             // 3. 从解码器接收frame
             // 3.1 一个视频packet含一个视频frame
@@ -135,6 +135,7 @@ static int video_decode_thread(void *arg)
 
         if (ret < 0){
 			is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "queue_picture return -1, goto end.");
+			is->abort_request = 1;
             goto exit;
         }
     }
@@ -142,7 +143,7 @@ static int video_decode_thread(void *arg)
 exit:
     av_frame_free(&p_frame);
 	//SDL_Delay(100);
-	is->abort_request = 1;
+	//is->abort_request = 1;
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "video decode thread exit, thread id is %u, and is->abort_request = %d", SDL_ThreadID(), is->abort_request);
 
     return 0;
@@ -303,12 +304,12 @@ retry:
         is->frame_timer = time;
     }
 
-    SDL_LockMutex(is->video_frm_queue.mutex);
+    SDL_LockMutex(is->video_frm_queue.frame_mutex);
     if (!isnan(vp->pts))
     {
         update_video_pts(is, vp->pts, vp->pos, vp->serial); // 更新视频时钟:时间戳、时钟时间
     }
-    SDL_UnlockMutex(is->video_frm_queue.mutex);
+    SDL_UnlockMutex(is->video_frm_queue.frame_mutex);
 
     // 是否要丢弃未能及时播放的视频帧
     if (frame_queue_nb_remaining(&is->video_frm_queue) > 1)  // 队列中未显示帧数>1(只有一帧则不考虑丢帧)