Ver código fonte

Z991239-1387 #comment other:解决localmediaplay release版存在音频播放失败问题

陈礼鹏80274480 4 anos atrás
pai
commit
16b20506d8

+ 2 - 2
Other/libmediaplayer/CMakeLists.txt

@@ -27,8 +27,8 @@ SDL2/2.0.9@LR04.02_ThirdParty/testing
 BASIC_SETUP CMAKE_TARGETS
 BUILD missing)
 else(WIN32)
-conan_cmake_run(REQUIRES ffmpeg/4.1@LR04.02_ThirdParty/dynamic
-SDL2/2.0.12@LR04.02_ThirdParty/dynamic
+conan_cmake_run(REQUIRES ffmpeg/4.1.6@LR04.02_ThirdParty/dynamic
+SDL2/2.0.12@LR04.02_ThirdParty/testing
 BASIC_SETUP CMAKE_TARGETS
 BUILD missing)
 endif(WIN32)

+ 35 - 16
Other/libmediaplayer/audio.cpp

@@ -7,11 +7,11 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len);
 // 从packet_queue中取一个packet,解码生成frame
 static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt_queue, AVFrame *frame, CMediaHostApi* hostapi)
 {
-    int ret;
+    int ret = -1;
 
     while (1)
     {
-        AVPacket pkt;
+		AVPacket pkt = {0};
 
         while (1)
         {
@@ -32,29 +32,25 @@ static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
                 }
                 else
                 {
-                    //av_log(NULL, AV_LOG_WARNING, "frame->pts no.\n");
-					//rvclog("frame->pts no.");
+					hostapi->Debug("frame->pts no.");
                 }
 
                 return 1;
             }
             else if (ret == AVERROR_EOF)
             {
-                //av_log(NULL, AV_LOG_INFO, "audio avcodec_receive_frame(): the decoder has been flushed.\n");
-				//rvclog("audio avcodec_receive_frame(): the decoder has been flushed.");
+				hostapi->Debug("audio avcodec_receive_frame(): the decoder has been flushed.");
                 avcodec_flush_buffers(p_codec_ctx);
-                return 0;
+                return -1;
             }
             else if (ret == AVERROR(EAGAIN))
             {
-                //av_log(NULL, AV_LOG_INFO, "audio avcodec_receive_frame(): input is not accepted in the current state.\n");
-				//rvclog("audio avcodec_receive_frame(): input is not accepted in the current state.");
+				hostapi->Debug("audio avcodec_receive_frame(): input is not accepted in the current state.");
 				break;
             }
             else
             {
-                //av_log(NULL, AV_LOG_ERROR, "audio avcodec_receive_frame(): other errors.\n");
-				//rvclog( "audio avcodec_receive_frame(): other errors.");
+				hostapi->Debug( "audio avcodec_receive_frame(): other errors.");
 				continue;
             }
         }
@@ -76,15 +72,23 @@ static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
             // 2. 将packet发送给解码器
             //    发送packet的顺序是按dts递增的顺序,如IPBBPBB
             //    pkt.pos变量可以标识当前packet在视频文件中的地址偏移
-            if (avcodec_send_packet(p_codec_ctx, &pkt) == AVERROR(EAGAIN))
+			int iresult = avcodec_send_packet(p_codec_ctx, &pkt);
+			hostapi->Debug("avcodec_send_packet result is %d", iresult);
+            if (AVERROR(EAGAIN) == iresult)
             {
                 //av_log(NULL, AV_LOG_ERROR, "receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
-				//rvclog("receive_frame and send_packet both returned EAGAIN, which is an API violation.");
+				hostapi->Debug("receive_frame and send_packet both returned EAGAIN, which is an API violation.");
             }
-
-            av_packet_unref(&pkt);
+			if (0 == iresult)
+			{
+				av_packet_unref(&pkt);
+			}
         }
     }
+
+	printf("audio_decode_frame exit\n"); 
+
+	return ret;
 }
 
 // 音频解码线程:从音频packet_queue中取数据,解码后放入音频frame_queue
@@ -103,7 +107,6 @@ static int audio_decode_thread(void *arg)
         return AVERROR(ENOMEM);
     }
 
-	//is->rvc_log("audio_decode_thread is->abort_request == %d.", is->abort_request);
     while (0 == is->abort_request)
     {
         got_frame = audio_decode_frame(is->p_acodec_ctx, &is->audio_pkt_queue, p_frame, is->rvc_hostapi);
@@ -132,6 +135,7 @@ static int audio_decode_thread(void *arg)
             frame_queue_push(&is->audio_frm_queue);
         }
     }
+	is->rvc_hostapi->Debug("audio_decode_thread exit, and is->abort_request == %d.", is->abort_request);
 
 the_end:
     av_frame_free(&p_frame);
@@ -389,6 +393,21 @@ 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("event.type = 0x%0x.\n", event.type);
+		if (FF_QUIT_EVENT == event.type) {
+			return 0;
+		}
+	}
 }
 
 // 音频处理回调函数。读队列获取音频包,解码,播放

+ 6 - 10
Other/libmediaplayer/demux.cpp

@@ -112,23 +112,16 @@ static int demux_thread(void *arg)
 
     SDL_mutex *wait_mutex = SDL_CreateMutex();
 
-	//is->rvc_log("demux_thread running, is->abort_request == %d.", is->abort_request);
-
     // 4. 解复用处理
     while (0 == is->abort_request)
     {
-		//is->rvc_log("demux_thread is->abort_request is %d.", is->abort_request);
-  //      if (is->abort_request)
-  //      {
-  //          break;
-  //      }
-
 		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 */
@@ -183,6 +176,9 @@ static int demux_thread(void *arg)
     }
 
     SDL_DestroyMutex(wait_mutex);
+
+	is->rvc_hostapi->Debug("demux_thread exit, and is->abort_request = %d", is->abort_request);
+
     return 0;
 }
 
@@ -190,14 +186,14 @@ int open_demux(player_stat_t *is)
 {
     if (demux_init(is) != 0)
     {
-		//is->rvc_log("demux_init() failed.");
+		is->rvc_hostapi->Debug("demux_init() failed.");
         return -1;
     }
 
     is->read_tid = SDL_CreateThread(demux_thread, "demux_thread", is);
     if (is->read_tid == NULL)
     {
-		//is->rvc_log("SDL_CreateThread() failed: %s.", SDL_GetError());
+		is->rvc_hostapi->Debug("SDL_CreateThread() failed: %s.", SDL_GetError());
         return -1;
     }
 

+ 19 - 16
Other/libmediaplayer/packet.cpp

@@ -23,8 +23,8 @@ int packet_queue_init(packet_queue_t *q, CMediaHostApi* hostapi)
 // 写队列尾部。pkt是一包还未解码的音频数据
 int packet_queue_put(packet_queue_t *q, AVPacket *pkt, CMediaHostApi* hostapi)
 {
-    AVPacketList *pkt_list;
-    
+	AVPacketList* pkt_list = NULL;
+
     if (av_packet_make_refcounted(pkt) < 0)
     {
 		hostapi->Debug("[pkt] is not refrence counted.");
@@ -53,6 +53,7 @@ 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.\n");
     SDL_CondSignal(q->cond);
 
     SDL_UnlockMutex(q->mutex);
@@ -62,17 +63,18 @@ int packet_queue_put(packet_queue_t *q, AVPacket *pkt, CMediaHostApi* hostapi)
 // 读队列头部。
 int packet_queue_get(packet_queue_t *q, AVPacket *pkt, int block)
 {
-    AVPacketList *p_pkt_node;
-    int ret;
+    AVPacketList *p_pkt_node = NULL;
+    int ret = -1;
 
     SDL_LockMutex(q->mutex);
 
     while (1)
     {
         p_pkt_node = q->first_pkt;
+		printf("packet queue length is %d.\n", q->nb_packets);
         if (p_pkt_node)             // 队列非空,取一个出来
         {
-			//printf("packet queue is not empty, get one.");
+			printf("packet queue is not empty, get one.\n");
             q->first_pkt = p_pkt_node->next;
             if (!q->first_pkt)
             {
@@ -85,19 +87,20 @@ int packet_queue_get(packet_queue_t *q, AVPacket *pkt, int block)
             ret = 1;
             break;
         }
-        else if (!block)            // 队列空且阻塞标志无效,则立即退出
-        {
-			//printf("packet queue is empty, and block flag is invalid, break.");
-            ret = 0;
-            break;
-        }
-        else                        // 队列空且阻塞标志有效,则等待
-        {
-			//printf("packet queue is empty, and block flag is valid, continue wait.");
-            SDL_CondWait(q->cond, q->mutex);
-        }
+		else if (!block)            // 队列空且阻塞标志无效,则立即退出
+		{
+			printf("packet queue is empty, and block flag is invalid, break.\n");
+			ret = 0;
+			break;
+		}
+		else                        // 队列空且阻塞标志有效,则等待
+		{
+			printf("packet queue is empty, and block flag is valid, continue wait.\n");
+			SDL_CondWait(q->cond, q->mutex);
+		}
     }
     SDL_UnlockMutex(q->mutex);
+
     return ret;
 }
 

+ 1 - 0
Other/libmediaplayer/player.cpp

@@ -364,6 +364,7 @@ void CMediaPlayer::StartMediaPlay()
 			SDL_PumpEvents();
 		}
 
+		m_hostapi->Debug("event.type = 0x%0x.", event.type);
 		switch (event.type) {
 		case SDL_KEYDOWN:
 			if (event.key.keysym.sym == SDLK_ESCAPE)

+ 1 - 1
Other/libpictureplayer/CMakeLists.txt

@@ -16,7 +16,7 @@ conan_cmake_run(REQUIRES SDL2/2.0.9@LR04.02_ThirdParty/testing
 BASIC_SETUP CMAKE_TARGETS
 BUILD missing)
 else(WIN32)
-conan_cmake_run(REQUIRES SDL2/2.0.12@LR04.02_ThirdParty/dynamic
+conan_cmake_run(REQUIRES SDL2/2.0.12@LR04.02_ThirdParty/testing
 BASIC_SETUP CMAKE_TARGETS
 BUILD missing)
 endif(WIN32)