|
@@ -29,6 +29,7 @@ static int queue_picture(player_stat_t *is, AVFrame *src_frame, double pts, doub
|
|
|
av_frame_move_ref(vp->frame, src_frame);
|
|
|
// 更新队列计数及写索引
|
|
|
frame_queue_push(&is->video_frm_queue);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -48,6 +49,7 @@ static int video_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
|
|
|
// 解码器缓存一定数量的packet后,才有解码后的frame输出
|
|
|
// frame输出顺序是按pts的顺序,如IBBPBBP
|
|
|
// frame->pkt_pos变量是此frame对应的packet在视频文件中的偏移地址,值同pkt.pos
|
|
|
+
|
|
|
ret = avcodec_receive_frame(p_codec_ctx, frame);
|
|
|
if (ret < 0)
|
|
|
{
|
|
@@ -59,7 +61,8 @@ static int video_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
|
|
|
}
|
|
|
else if (ret == AVERROR(EAGAIN))
|
|
|
{
|
|
|
- //hostapi->Debug("video avcodec_receive_frame(): output is not available in this state - " "user must try to send new input");
|
|
|
+ //hostapi->Debug(MEDIA_LOG_DEBUG,"video avcodec_receive_frame(): output is not available in this state - " "user must try to send new input");
|
|
|
+ av_usleep(RVC_DEFAULT_SLEEP_TIME);
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
@@ -74,6 +77,7 @@ static int video_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
|
|
|
//frame->pts = frame->pkt_dts;
|
|
|
return 1; // 成功解码得到一个视频帧,则返回
|
|
|
}
|
|
|
+ av_usleep(RVC_DEFAULT_SLEEP_TIME);
|
|
|
}
|
|
|
|
|
|
// 1. 取出一个packet。使用pkt对应的serial赋值给d->pkt_serial
|
|
@@ -81,13 +85,11 @@ static int video_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- if (pkt.data == NULL)
|
|
|
- {
|
|
|
+ if (pkt.data == NULL){
|
|
|
// 复位解码器内部状态/刷新内部缓冲区。
|
|
|
avcodec_flush_buffers(p_codec_ctx);
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
+ else{
|
|
|
// 2. 将packet发送给解码器
|
|
|
// 发送packet的顺序是按dts递增的顺序,如IPBBPBB
|
|
|
// pkt.pos变量可以标识当前packet在视频文件中的地址偏移
|
|
@@ -96,6 +98,7 @@ static int video_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
|
|
|
}
|
|
|
av_packet_unref(&pkt);
|
|
|
}
|
|
|
+ av_usleep(RVC_DEFAULT_SLEEP_TIME);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -138,12 +141,11 @@ static int video_decode_thread(void *arg)
|
|
|
is->abort_request = 1;
|
|
|
goto exit;
|
|
|
}
|
|
|
+ av_usleep(RVC_DEFAULT_SLEEP_TIME);
|
|
|
}
|
|
|
|
|
|
exit:
|
|
|
av_frame_free(&p_frame);
|
|
|
- //SDL_Delay(100);
|
|
|
- //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;
|
|
@@ -267,18 +269,15 @@ retry:
|
|
|
|
|
|
double last_duration, duration, delay;
|
|
|
frame_t *vp, *lastvp;
|
|
|
-
|
|
|
/* dequeue the picture */
|
|
|
lastvp = frame_queue_peek_last(&is->video_frm_queue); // 上一帧:上次已显示的帧
|
|
|
vp = frame_queue_peek(&is->video_frm_queue); // 当前帧:当前待显示的帧
|
|
|
-
|
|
|
// lastvp和vp不是同一播放序列(一个seek会开始一个新播放序列),将frame_timer更新为当前时间
|
|
|
if (first_frame)
|
|
|
{
|
|
|
is->frame_timer = av_gettime_relative() / 1000000.0;
|
|
|
first_frame = false;
|
|
|
}
|
|
|
-
|
|
|
// 暂停处理:不停播放上一帧图像
|
|
|
if (is->paused)
|
|
|
goto display;
|
|
@@ -295,7 +294,6 @@ retry:
|
|
|
// 播放时刻未到,则不播放,直接返回
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
// 更新frame_timer值
|
|
|
is->frame_timer += delay;
|
|
|
// 校正frame_timer值:若frame_timer落后于当前系统时间太久(超过最大同步域值),则更新为当前系统时间
|
|
@@ -326,7 +324,6 @@ retry:
|
|
|
|
|
|
// 删除当前读指针元素,读指针+1。若未丢帧,读指针从lastvp更新到vp;若有丢帧,读指针从vp更新到nextvp
|
|
|
frame_queue_next(&is->video_frm_queue);
|
|
|
-
|
|
|
display:
|
|
|
video_display(is); // 取出当前帧vp(若有丢帧是nextvp)进行播放
|
|
|
}
|
|
@@ -343,6 +340,7 @@ static int video_playing_thread(void *arg)
|
|
|
remaining_time = REFRESH_RATE;
|
|
|
// 立即显示当前帧,或延时remaining_time后再显示
|
|
|
video_refresh(is, &remaining_time);
|
|
|
+ remaining_time += 0.040;
|
|
|
}
|
|
|
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "video playing thread exit, thread id is %u, and is->abort_request = %d", SDL_ThreadID(), is->abort_request);
|