音視頻有三種同步方式
- 標準時間同步
- 音頻時間同步
- 視頻時間同步
介紹第一種也是相對簡單的一種方式
- 解碼獲取已播放時間
- 根據記錄的開始時間和當前時間差值獲取實際播放的時間
- 已播放的時間-實際播放的時間=延遲時間
視頻計算
//計算延遲
int64_t pts = av_frame_get_best_effort_timestamp(yuv_frame);
//轉換(不同時間基時間轉換)
int64_t time = av_rescale_q(pts,stream->time_base,AV_TIME_BASE_Q);
player_wait_for_frame(player,time,player->video_stream_index);
音頻計算
int64_t pts = packet->pts;
if (pts != AV_NOPTS_VALUE) {
player->audio_clock = av_rescale_q(pts, stream->time_base, AV_TIME_BASE_Q);
// av_q2d(stream->time_base) * pts;
LOGI("player_write_audio - read from pts");
player_wait_for_frame(player,player->audio_clock + AUDIO_TIME_ADJUST_US,
player->audio_stream_index);
}
延遲計算
/**
* 獲取視頻當前播放時間
*/
int64_t player_get_current_video_time(Player *player) {
int64_t current_time = av_gettime();
return current_time - player->start_time;
}
/**
* 延遲
*/
void player_wait_for_frame(Player *player, int64_t stream_time,
int stream_no) {
pthread_mutex_lock(&player->mutex);
for(;;){
int64_t current_video_time = player_get_current_video_time(player);
int64_t sleep_time = stream_time - current_video_time;
if (sleep_time < -300000ll) {
// 300 ms late
//這段代碼對于300毫秒的處理我也不知道什么意思拭荤,拿過來用盅蝗,有大佬知道什么意思的可以回復一下,不勝感激剔蹋。
int64_t new_value = player->start_time - sleep_time;
LOGI("player_wait_for_frame[%d] correcting %f to %f because late",
stream_no, (av_gettime() - player->start_time) / 1000000.0,
(av_gettime() - new_value) / 1000000.0);
player->start_time = new_value;
pthread_cond_broadcast(&player->cond);
}
if (sleep_time <= MIN_SLEEP_TIME_US) {
// We do not need to wait if time is slower then minimal sleep time
break;
}
if (sleep_time > 500000ll) {
// if sleep time is bigger then 500ms just sleep this 500ms
// and check everything again
sleep_time = 500000ll;
}
//等待指定時長
int timeout_ret = pthread_cond_timeout_np(&player->cond,
&player->mutex, sleep_time/1000ll);
// just go further
LOGI("player_wait_for_frame[%d] finish", stream_no);
}
pthread_mutex_unlock(&player->mutex);
}