Przeglądaj źródła

Z991239-1387 #comment other: 优化停止播放功能

陈礼鹏80274480 4 lat temu
rodzic
commit
3ced419e7b

+ 2 - 3
Module/mod_localmediaplay/mod_localmediaplay.cpp

@@ -444,7 +444,7 @@ void CLocalMediaPlayEntity::AudioPlayFinished()
 	AudioPlayRet ret;
 	ret.AudioNames = m_lastPlayAudio.c_str();
 	ret.ret = true;
-	Dbg("stop play audio %s success", ret.AudioNames);
+	Dbg("stop play audio %s success", ret.AudioNames.GetData());
 	SpSendBroadcast(GetFunction(), eMsg_AudioPlayRet, eMsgSig_AudioPlayRet, ret);
 }
 
@@ -521,10 +521,8 @@ ErrorCodeEnum CLocalMediaPlayEntity::__OnStart(ErrorCodeEnum preOperationError)
 		m_pVideoPlayer[i] = new Clibwmpplayer(this);
 		m_pImagePlayer[i] = new Clibimgplayer(this);
 #else
-		Dbg("begin create mediaplayer and pictureplayer");
 		m_pMediaPlayer[i] = new Clibmediaplayer(this);
 		m_pPicturePlayer[i] = new Clibpictureplayer(this);
-		Dbg("create mediaplayer and pictureplayer success.");
 #endif 
 	}
 	
@@ -634,6 +632,7 @@ void* StartAudioPlayingThreadFunc(void* param)
 	}
 	Dbg("Leave StartAudioPlayingThreadFunc");
 
+	return 0;
 }
 
 #endif // RVC_OS_WIN

+ 91 - 75
Other/libmediaplayer/audio.cpp

@@ -55,6 +55,7 @@ static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
             }
         }
 
+		//printf("avcodec_receive_frame ret = %d, begin packet_queue_get\n", ret);
         // 1. 取出一个packet。使用pkt对应的serial赋值给d->pkt_serial
         if (packet_queue_get(p_pkt_queue, &pkt, true) < 0)
         {
@@ -63,10 +64,12 @@ static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
         }
 
         // packet_queue中第一个总是flush_pkt。每次seek操作会插入flush_pkt,更新serial,开启新的播放序列
-        if (pkt.data == NULL)
+		//hostapi->Debug("packet_queue_get pkt.data == 0x%0x, pkt.size == %d.", pkt.data, pkt.size);
+        if (NULL == pkt.data || 0 == pkt.size)
         {
             // 复位解码器内部状态/刷新内部缓冲区。当seek操作或切换流时应调用此函数。
             avcodec_flush_buffers(p_codec_ctx);
+			return -2;
         }
         else
         {
@@ -76,7 +79,6 @@ static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
 			int iresult = avcodec_send_packet(p_codec_ctx, &pkt);
             if (AVERROR(EAGAIN) == iresult)
             {
-                //av_log(NULL, AV_LOG_ERROR, "receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
 				hostapi->Debug("receive_frame and send_packet both returned EAGAIN, which is an API violation.");
             }
 			if (0 == iresult)
@@ -99,6 +101,7 @@ static int audio_decode_thread(void *arg)
     int got_frame = 0;
     AVRational tb;
     int ret = 0;
+	int inullpacket = 0;
 
     if (p_frame == NULL){
         return AVERROR(ENOMEM);
@@ -109,9 +112,19 @@ static int audio_decode_thread(void *arg)
 		//printf("%s:%d is->index = %d, is->p_acodec_ctx[is->index] = 0x%0x\n", __FUNCTION__, __LINE__, is->index, is->p_acodec_ctx[is->index]);
         got_frame = audio_decode_frame(is->p_acodec_ctx[is->index], &is->audio_pkt_queue, p_frame, is->rvc_hostapi);
         if (got_frame < 0){
-			is->rvc_hostapi->Debug("audio_decode_frame < 0, goto end");
-            goto the_end;
-        }
+			if(-2 == got_frame && inullpacket < 2){
+				inullpacket++;
+				continue;
+			}
+			else {
+				is->rvc_hostapi->Debug(" audio_decode_frame < 0, goto end");
+				goto the_end;
+			}
+		}
+		else
+		{
+			inullpacket = 0;
+		}
 
         if (got_frame)
         {
@@ -138,9 +151,11 @@ static int audio_decode_thread(void *arg)
 the_end:
 
     av_frame_free(&p_frame);
+	SDL_Delay(1000);
+	is->abort_request = 1;
 	is->rvc_hostapi->Debug("audio decode thread exit, thread id is %lu, and is->abort_request = %d", SDL_ThreadID(), is->abort_request);
-
-    return ret;
+    
+	return ret;
 }
 
 int open_audio_stream(player_stat_t *is)
@@ -202,11 +217,11 @@ int open_audio_stream(player_stat_t *is)
 
 static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
 {
-    int data_size, resampled_data_size;
-    int64_t dec_channel_layout;
-    av_unused double audio_clock0;
-    int wanted_nb_samples;
-    frame_t *af;
+    int data_size = 0, resampled_data_size = 0;
+    int64_t dec_channel_layout = 0;
+    av_unused double audio_clock0 = 0.0;
+    int wanted_nb_samples = 0;
+    frame_t *af = NULL;
 
 #if defined(_WIN32)
     while (frame_queue_nb_remaining(&is->audio_frm_queue) == 0)
@@ -219,14 +234,15 @@ static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
 
     // 若队列头部可读,则由af指向可读帧
 	if (!(af = frame_queue_peek_readable(&is->audio_frm_queue))) {
-		return -1;
+		is->rvc_hostapi->Debug("%s:%d abort_request flag is true, function return", __FUNCTION__, __LINE__);
+		return -2;
 	}
     frame_queue_next(&is->audio_frm_queue);
 
     // 根据frame中指定的音频参数获取缓冲区的大小
-    data_size = av_samples_get_buffer_size(NULL, af->frame->channels,   // 本行两参数:linesize,声道数
-        af->frame->nb_samples,       // 本行一参数:本帧中包含的单个声道中的样本数
-        (AVSampleFormat)af->frame->format, 1);       // 本行两参数:采样格式,不对齐
+    data_size = av_samples_get_buffer_size(NULL, af->frame->channels,    // 本行两参数:linesize,声道数
+        af->frame->nb_samples,											 // 本行一参数:本帧中包含的单个声道中的样本数
+        (AVSampleFormat)af->frame->format, 1);							 // 本行两参数:采样格式,不对齐
 
 // 获取声道布局
     dec_channel_layout =
@@ -275,28 +291,24 @@ static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
         int out_count = (int64_t)wanted_nb_samples * is->audio_param_tgt.freq / af->frame->sample_rate + 256;
         // 重采样输出参数:输出音频缓冲区尺寸(以字节为单位)
         int out_size = av_samples_get_buffer_size(NULL, is->audio_param_tgt.channels, out_count, is->audio_param_tgt.fmt, 0);
-        int len2;
-        if (out_size < 0)
-        {
-            //av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
-			//is->rvc_log("av_samples_get_buffer_size() failed.");
+        int len2 = 0;
+        if (out_size < 0){
+			is->rvc_hostapi->Debug("av_samples_get_buffer_size() failed.");
             return -1;
         }
         av_fast_malloc(&is->audio_frm_rwr, &is->audio_frm_rwr_size, out_size);
-        if (!is->audio_frm_rwr)
-            return AVERROR(ENOMEM);
+		if (!is->audio_frm_rwr) {
+			return AVERROR(ENOMEM);
+		}
         // 音频重采样:返回值是重采样后得到的音频数据中单个声道的样本数
         len2 = swr_convert(is->audio_swr_ctx, out, out_count, in, af->frame->nb_samples);
-        if (len2 < 0)
-        {
-            //av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
-			//is->rvc_log("swr_convert() failed.");
+        if (len2 < 0){
+			is->rvc_hostapi->Debug("swr_convert() failed.");
             return -1;
         }
-        if (len2 == out_count)
-        {
-            //av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
-			//is->rvc_log("audio buffer is probably too small.");
+
+        if (len2 == out_count){
+			is->rvc_hostapi->Debug("audio buffer is probably too small.");
 			if (swr_init(is->audio_swr_ctx) < 0)
                 swr_free(&is->audio_swr_ctx);
         }
@@ -313,12 +325,10 @@ static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
 
     audio_clock0 = is->audio_clock;
     /* update the audio clock with the pts */
-    if (!isnan(af->pts))
-    {
+    if (!isnan(af->pts)){
         is->audio_clock = af->pts + (double)af->frame->nb_samples / af->frame->sample_rate;
     }
-    else
-    {
+    else{
         is->audio_clock = NAN;
     }
     is->audio_clock_serial = af->serial;
@@ -340,8 +350,8 @@ static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
 static int open_audio_playing(void *arg)
 {
     player_stat_t *is = (player_stat_t *)arg;
-    SDL_AudioSpec wanted_spec;
-    SDL_AudioSpec actual_spec;
+	SDL_AudioSpec wanted_spec = {0};
+	SDL_AudioSpec actual_spec = {0};
 
     // 2. 打开音频设备并创建音频处理线程
     // 2.1 打开音频设备,获取SDL设备支持的音频参数actual_spec(期望的参数是wanted_spec,实际得到actual_spec)
@@ -358,10 +368,14 @@ static int open_audio_playing(void *arg)
     wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
 	wanted_spec.callback = sdl_audio_callback;          // 回调函数,若为NULL,则应使用SDL_QueueAudio()机制
     wanted_spec.userdata = is;                          // 提供给回调函数的参数
-    if (SDL_OpenAudio(&wanted_spec, &actual_spec) < 0)
-    {
-		is->rvc_hostapi->Debug("SDL_OpenAudio() failed: %s.", SDL_GetError());
-		return -1;
+    if (SDL_OpenAudio(&wanted_spec, &actual_spec) < 0){
+		is->rvc_hostapi->Debug("SDL_OpenAudio() failed: %s,try close and retry", SDL_GetError());
+		SDL_CloseAudio();
+		if (SDL_OpenAudio(&wanted_spec, &actual_spec) < 0) {
+			is->rvc_hostapi->Debug("SDL_OpenAudio() failed: %s.", SDL_GetError());
+			return -1;
+		}
+		
     }
 
     // 2.2 根据SDL音频参数构建音频重采样参数
@@ -376,9 +390,7 @@ static int open_audio_playing(void *arg)
     is->audio_param_tgt.channels = actual_spec.channels;
     is->audio_param_tgt.frame_size = av_samples_get_buffer_size(NULL, actual_spec.channels, 1, is->audio_param_tgt.fmt, 1);
     is->audio_param_tgt.bytes_per_sec = av_samples_get_buffer_size(NULL, actual_spec.channels, actual_spec.freq, is->audio_param_tgt.fmt, 1);
-    if (is->audio_param_tgt.bytes_per_sec <= 0 || is->audio_param_tgt.frame_size <= 0)
-    {
-        //av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
+    if (is->audio_param_tgt.bytes_per_sec <= 0 || is->audio_param_tgt.frame_size <= 0){
 		is->rvc_hostapi->Debug("av_samples_get_buffer_size failed.");
 		return -1;
     }
@@ -393,21 +405,30 @@ static int open_audio_playing(void *arg)
     //     在暂停期间,会将静音值往音频设备写。
     SDL_PauseAudio(0);
 
-	SDL_Event event;
-	while (true)
-	{
-		SDL_PumpEvents();
-		while (!SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT))
-		{
-			SDL_Delay(100);
-			SDL_PumpEvents();
-		}
-		is->rvc_hostapi->Debug("open_audio_playing event.type = 0x%0x.", event.type);
-		if (FF_QUIT_EVENT == event.type) {
-			SDL_Delay(2000);
-			return 0;
-		}
+
+	while (is->abort_request == 0){
+		SDL_Delay(100);
 	}
+
+	SDL_CloseAudio();
+
+	return 0;
+
+	//SDL_Event event;
+	//while (true)
+	//{
+	//	SDL_PumpEvents();
+	//	while (!SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT))
+	//	{
+	//		SDL_Delay(100);
+	//		SDL_PumpEvents();
+	//	}
+	//	is->rvc_hostapi->Debug("open_audio_playing event.type = 0x%0x.", event.type);
+	//	if (FF_QUIT_EVENT == event.type) {
+	//		SDL_Delay(2000);
+	//		return 0;
+	//	}
+	//}
 }
 
 // 音频处理回调函数。读队列获取音频包,解码,播放
@@ -420,25 +441,25 @@ static int open_audio_playing(void *arg)
 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
 {
     player_stat_t *is = (player_stat_t *)opaque;
-    int audio_size, len1;
+    int audio_size = 0, len1 = 0;
 
     int64_t audio_callback_time = av_gettime_relative();
-	//is->rvc_hostapi->Debug("sdl_audio_callback audo len is %d.", len);
+	//is->rvc_hostapi->Debug("sdl_audio_callback audo len is %d. and audio_frm_size is %d.", len, (int)is->audio_frm_size);
     while (len > 0 && 0 == is->abort_request) // 输入参数len等于is->audio_hw_buf_size,是audio_open()中申请到的SDL音频缓冲区大小
     {
-        if (is->audio_cp_index >= (int)is->audio_frm_size)
-        {
+        if (is->audio_cp_index >= (int)is->audio_frm_size){
             // 1. 从音频frame队列中取出一个frame,转换为音频设备支持的格式,返回值是重采样音频帧的大小
             audio_size = audio_resample(is, audio_callback_time);
 			//is->rvc_hostapi->Debug("audio_resample audio_size is %d.", audio_size);
-			if (audio_size < 0)
-            {
+			if (audio_size < 0){
+				if (-2 == audio_size) {
+					return;
+				}
                 /* if error, just output silence */
                 is->p_audio_frm = NULL;
                 is->audio_frm_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_param_tgt.frame_size * is->audio_param_tgt.frame_size;
             }
-            else
-            {
+            else{
                 is->audio_frm_size = audio_size;
             }
             is->audio_cp_index = 0;
@@ -446,21 +467,16 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
         // 引入is->audio_cp_index的作用:防止一帧音频数据大小超过SDL音频缓冲区大小,这样一帧数据需要经过多次拷贝
         // 用is->audio_cp_index标识重采样帧中已拷入SDL音频缓冲区的数据位置索引,len1表示本次拷贝的数据量
         len1 = is->audio_frm_size - is->audio_cp_index;
-        if (len1 > len)
-        {
+        if (len1 > len){
             len1 = len;
         }
 		//printf("len1 = %d\n", len1);
         // 2. 将转换后的音频数据拷贝到音频缓冲区stream中,之后的播放就是音频设备驱动程序的工作了
-        if (is->p_audio_frm != NULL)
-        {
-            //memcpy(stream, (uint8_t *)is->p_audio_frm + is->audio_cp_index, len1);
+        if (is->p_audio_frm != NULL){
 			SDL_memset(stream, 0, len1);
 			SDL_MixAudio(stream, (uint8_t*)is->p_audio_frm + is->audio_cp_index, len1, is->uVolume);
         }
-        else
-        {
-            //memset(stream, 0, len1);
+        else{
 			SDL_memset(stream, 0, len1);
         }
 
@@ -470,7 +486,7 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
     }
     // is->audio_write_buf_size是本帧中尚未拷入SDL音频缓冲区的数据量
     is->audio_write_buf_size = is->audio_frm_size - is->audio_cp_index;
-	//is->rvc_log("audio_write_buf_size == %d.", is->audio_write_buf_size);
+	//is->rvc_hostapi->Debug("audio_write_buf_size == %d.", is->audio_write_buf_size);
     /* Let's assume the audio driver that is used by SDL has two periods. */
     // 3. 更新时钟
     if (!isnan(is->audio_clock))

+ 9 - 9
Other/libmediaplayer/demux.cpp

@@ -108,15 +108,15 @@ static int demux_thread(void *arg)
     // 4. 解复用处理
     while (0 == is->abort_request)
     {
-		if (0 != ret)
-		{
-			SDL_Event event;
-			event.type = FF_QUIT_EVENT;
-			event.user.data1 = is;
-			SDL_PushEvent(&event);
-			is->rvc_hostapi->Debug("SDL_PushEvent FF_QUIT_EVENT.");
-			
-		}
+		//if (0 != ret)
+		//{
+		//	//SDL_Event event;
+		//	//event.type = FF_QUIT_EVENT;
+		//	//event.user.data1 = is;
+		//	//SDL_PushEvent(&event);
+		//	//is->rvc_hostapi->Debug("SDL_PushEvent FF_QUIT_EVENT.");
+		//	
+		//}
         
         /* if the queue are full, no need to read more */
         if (is->audio_pkt_queue.size + is->video_pkt_queue.size > MAX_QUEUE_SIZE ||

+ 1 - 1
Other/libmediaplayer/frame.cpp

@@ -88,7 +88,7 @@ frame_t *frame_queue_peek_readable(frame_queue_t *f)
     /* 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 <= 0 && !f->pktq->abort_request, continue wait.\n");
+		//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);
     }
     SDL_UnlockMutex(f->mutex);

+ 1 - 5
Other/libmediaplayer/libmediaplayer.cpp

@@ -14,7 +14,6 @@ public:
 
 	libmediaplayer_impl(CMediaHostApi* pHostApi) {
 		m_pHostApi = pHostApi;
-		pHostApi->Debug("begin new MediaPlayer.");
 
 		m_Player = new CMediaPlayer(pHostApi);
 		if (NULL != m_Player) {
@@ -28,7 +27,6 @@ public:
 
 	~libmediaplayer_impl()
 	{
-		//printf("~libmediaplayer_impl()\n");
 		m_pHostApi = NULL;
 		delete m_Player;
 		m_Player = NULL;
@@ -347,6 +345,7 @@ public:
 	void PlayMediaFinished() 
 	{
 		m_pHostApi->Debug("PlayMediaFinished!");
+		m_pHostApi->AudioPlayFinished();
 	}
 
 	CMediaHostApi* GetHostApi()
@@ -380,15 +379,12 @@ public:
 
 Clibmediaplayer::Clibmediaplayer(CMediaHostApi* pHostApi)
 {
-	pHostApi->Debug("begin new libmediaplayer_impl.");
 	m_pImpl = new libmediaplayer_impl(pHostApi);
-	pHostApi->Debug("after new libmediaplayer_impl.");
 	return;
 }
 
 Clibmediaplayer::~Clibmediaplayer()
 {
-	printf("~Clibmediaplayer()\n");
 	delete m_pImpl;
 	m_pImpl = NULL;
 }

+ 3 - 2
Other/libmediaplayer/packet.cpp

@@ -53,8 +53,9 @@ int packet_queue_put(packet_queue_t *q, AVPacket *pkt, CMediaHostApi* hostapi)
     q->nb_packets++;
     q->size += pkt_list->pkt.size;
     // 发个条件变量的信号:重启等待q->cond条件变量的一个线程
+	//printf("packet queue put new pkt, CondSignal cond.pkt == 0x%0x, pkt_list->pkt.data == 0x%0x,(pkt->data == 0x%0x) pkt_list->pkt.size = %d, (pkt->size == %d)\n\n\n",pkt, pkt_list->pkt.data, pkt->data, pkt_list->pkt.size, pkt->size);
 	//printf("packet queue put new pkt, CondSignal cond.\n");
-    SDL_CondSignal(q->cond);
+	SDL_CondSignal(q->cond);
 
     SDL_UnlockMutex(q->mutex);
     return 0;
@@ -143,7 +144,7 @@ void packet_queue_abort(packet_queue_t *q, CMediaHostApi* m_hostapi)
 {
     SDL_LockMutex(q->mutex);
     q->abort_request = 1;
-	m_hostapi->Debug("packet_queue_abort, CondSignal cond.");
+	//m_hostapi->Debug("packet_queue_abort, CondSignal cond.");
     SDL_CondSignal(q->cond);
     SDL_UnlockMutex(q->mutex);
 }

+ 58 - 44
Other/libmediaplayer/player.cpp

@@ -125,12 +125,15 @@ static int player_deinit(player_stat_t *is)
 
     SDL_DestroyCond(is->continue_read_thread);
 
-	for (int index = 0; index < is->uFilesCount; index++) {
-		is->rvc_hostapi->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]);
+	if (is->eMType == eVideo_Type) {
+		for (int index = 0; index < is->uFilesCount; index++) {
+			is->rvc_hostapi->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]);
+			}
 		}
 	}
+
 	av_free(is->piconpath);
 
     if (NULL != is->sdl_video.texture){
@@ -349,47 +352,53 @@ void CMediaPlayer::StartMediaPlay()
 
 	m_bplaying = true;
 
-	SDL_Event event;
-	while (1)
-	{
-		//printf("************ StartMediaPlay while (1)*************\n");
-		SDL_PumpEvents();
-		// SDL event队列为空,则在while循环中播放视频帧。否则从队列头部取一个event,退出当前函数,在上级函数中处理event
-		while (!SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT))
-		{
-			av_usleep(100000);
-			SDL_PumpEvents();
-		}
+	while (m_player_stat->abort_request == 0){
+		SDL_Delay(1000);
+	}
 
-		m_hostapi->Debug("StartMediaPlay event.type = 0x%0x.", event.type);
-		switch (event.type) {
-		case SDL_KEYDOWN:
-			if (event.key.keysym.sym == SDLK_ESCAPE)
-			{
-				ExitMediaPlayingThread();
-				break;
-			}
+	ExitMediaPlayingThread();
 
-			switch (event.key.keysym.sym) {
-			case SDLK_SPACE:        // 空格键:暂停
-				toggle_pause(m_player_stat);
-				break;
-			case SDL_WINDOWEVENT:
-				toggle_full_screen(m_player_stat);
-				break;
-			default:
-				break;
-			}
-			break;
-
-		case SDL_QUIT:
-		case FF_QUIT_EVENT:
-			ExitMediaPlayingThread();
-			break;
-		default:
-			break;
-		}
-	}
+	//SDL_Event event;
+	//while (1)
+	//{
+	//	//printf("************ StartMediaPlay while (1)*************\n");
+	//	SDL_PumpEvents();
+	//	// SDL event队列为空,则在while循环中播放视频帧。否则从队列头部取一个event,退出当前函数,在上级函数中处理event
+	//	while (!SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT))
+	//	{
+	//		av_usleep(100000);
+	//		SDL_PumpEvents();
+	//	}
+
+	//	m_hostapi->Debug("StartMediaPlay event.type = 0x%0x.", event.type);
+	//	switch (event.type) {
+	//	case SDL_KEYDOWN:
+	//		if (event.key.keysym.sym == SDLK_ESCAPE)
+	//		{
+	//			ExitMediaPlayingThread();
+	//			break;
+	//		}
+
+	//		switch (event.key.keysym.sym) {
+	//		case SDLK_SPACE:        // 空格键:暂停
+	//			toggle_pause(m_player_stat);
+	//			break;
+	//		case SDL_WINDOWEVENT:
+	//			toggle_full_screen(m_player_stat);
+	//			break;
+	//		default:
+	//			break;
+	//		}
+	//		break;
+
+	//	case SDL_QUIT:
+	//	case FF_QUIT_EVENT:
+	//		ExitMediaPlayingThread();
+	//		break;
+	//	default:
+	//		break;
+	//	}
+	//}
 
 }
 
@@ -400,7 +409,12 @@ int CMediaPlayer::StopMediaPlay()
 
 	m_hostapi->Debug("StopMediaPlay called.");
 
-	SDL_QuitRequested();
+	if (NULL == m_player_stat) {
+		return iRet;
+	}
+
+	m_hostapi->Debug("set m_player_stat abort_request flag to true.");
+	m_player_stat->abort_request = 1;
 
 	iRet = 0;