@@ -3659,6 +3659,21 @@ static int read_thread(void *arg)
36593659 }
36603660 }
36613661
3662+
3663+ // 如果正在切换流,检查是否是关键帧
3664+ if (is -> switching_streams ) {
3665+ if (pkt -> stream_index == is -> video_stream ) { // 确保是视频流
3666+ if (pkt -> flags & AV_PKT_FLAG_KEY ) {
3667+ // 是关键帧,重置切换状态
3668+ is -> switching_streams = 0 ;
3669+ // 继续正常处理流程
3670+ } else {
3671+ // 不是关键帧,丢弃
3672+ av_packet_unref (pkt );
3673+ continue ; // 或继续读取下一帧
3674+ }
3675+ }
3676+ }
36623677 //parse SEI message
36633678// if (ic->iformat->name != NULL && strcmp(ic->iformat->name, "flv") == 0) {
36643679// printf("\nThe stream is FLV format,%s\n",ic->iformat->name);
@@ -3790,6 +3805,8 @@ static VideoState *stream_open(FFPlayer *ffp, const char *filename, AVInputForma
37903805 is -> iformat = iformat ;
37913806 is -> ytop = 0 ;
37923807 is -> xleft = 0 ;
3808+ // 初始化新增的成员变量
3809+ is -> switching_streams = 0 ;
37933810#if defined(__ANDROID__ )
37943811 if (ffp -> soundtouch_enable ) {
37953812 is -> handle = ijk_soundtouch_create ();
@@ -5389,19 +5406,27 @@ void ffp_set_player_maxpacket(FFPlayer *ffp, int num) {
53895406}
53905407
53915408void ffp_flush_player_cache (FFPlayer * ffp ) {
5392-
5393- VideoState * is = ffp -> is ;
5394- if (is -> audio_stream >= 0 ) {
5395- packet_queue_flush (& is -> audioq );
5396- packet_queue_put (& is -> audioq , & flush_pkt );
5397- // TODO: clear invaild audio data
5398- // SDL_AoutFlushAudio(ffp->aout);
5399- }
5400-
5401- if (is -> video_stream >= 0 ) {
5402- packet_queue_flush_videocache (& is -> videoq );
5403- packet_queue_put (& is -> videoq , & flush_pkt );
5404- }
5409+ VideoState * is = ffp -> is ;
5410+
5411+ // 设置切换标志,用于控制平滑切换
5412+ is -> switching_streams = 1 ;
5413+
5414+ // 清理音频,保持音频连续性
5415+ if (is -> audio_stream >= 0 ) {
5416+ packet_queue_flush (& is -> audioq );
5417+ packet_queue_put (& is -> audioq , & flush_pkt );
5418+ }
5419+
5420+ // 清理视频,但保持当前帧显示
5421+ if (is -> video_stream >= 0 ) {
5422+ // 保留最后一帧,清空其他帧
5423+ packet_queue_flush (& is -> videoq );
5424+ packet_queue_put (& is -> videoq , & flush_pkt );
5425+
5426+ // 不重置显示时间戳,保持当前帧显示
5427+ // 新的时间戳将在收到新的关键帧时更新
5428+ is -> frame_timer = av_gettime_relative () / 1000000.0 ;
5429+ }
54055430}
54065431
54075432void ffp_set_mediacodec_flags (FFPlayer * ffp , int flags ) {
0 commit comments