Skip to content

Commit 89b5ed6

Browse files
committed
优化播放音视频不同步问题
1 parent f29996a commit 89b5ed6

File tree

11 files changed

+116
-42
lines changed

11 files changed

+116
-42
lines changed

ArLiveLite/ArLive2Engine.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ ArLive2Engine::ArLive2Engine(void)
5757
: rtc::Thread(rtc::CreateDefaultSocketServer())
5858
, observer_(NULL)
5959
, b_running_(false)
60+
, b_app_background_(false)
6061
, b_aud_cap_exception_(false)
6162
, b_aud_ply_exception_(false)
6263
, b_video_preview_(false)
@@ -208,6 +209,7 @@ void ArLive2Engine::releaseArLivePlayer(AR::IArLivePlayer* player)
208209

209210
void ArLive2Engine::setAppInBackground(bool bBackground)
210211
{
212+
b_app_background_ = bBackground;
211213
rtc::CritScope l(&cs_arlive2_player_);
212214
MapArLive2Player::iterator itpr = map_arlive2_player_.begin();
213215
while (itpr != map_arlive2_player_.end()) {
@@ -307,12 +309,11 @@ void ArLive2Engine::Run()
307309
}
308310
}
309311

310-
311-
rtc::Thread::SleepMs(1);
312312
rtc::Thread::ProcessMessages(1);
313313
#ifdef WIN32
314314
w32_thread.ProcessMessages(1);
315315
#endif
316+
rtc::Thread::SleepMs(1);
316317
}
317318
}
318319

ArLiveLite/ArLive2Engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class ArLive2Engine : public AR::IArLive2Engine, public rtc::Thread, public MThr
122122

123123
// Control or logic
124124
bool b_running_;
125+
bool b_app_background_;
125126
bool b_aud_cap_exception_;
126127
bool b_aud_ply_exception_;
127128
bool b_video_preview_;

ArLiveLite/ArLive2Player.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include "rtc_base/bind.h"
55
#include "rtc_base/time_utils.h"
66

7-
87
static const size_t kMaxDataSizeSamples = 3840;
98

109

@@ -302,6 +301,7 @@ void ArLive2Player::OnTick()
302301
if (ar_player_ != NULL) {
303302
ar_player_->RunOnce();
304303
}
304+
305305
PlayBuffer::DoVidRender(b_video_paused_);
306306
}
307307
void ArLive2Player::OnTickUnAttach()
@@ -488,6 +488,10 @@ bool ArLive2Player::OnArPlyNeedMoreVideoData(void*player)
488488
{
489489
return PlayBuffer::NeedMoreVideoPlyData();
490490
}
491+
bool ArLive2Player::OnArPlyAppIsBackground(void* player)
492+
{
493+
return PlayBuffer::AppIsBackground();
494+
}
491495
void ArLive2Player::OnArPlyAudio(void*player, const char*pData, int nSampleHz, int nChannels, int64_t pts)
492496
{
493497
PcmData *audioData = new PcmData((char*)pData, (nSampleHz / 100)*nChannels * sizeof(short), nSampleHz, nChannels);

ArLiveLite/ArLive2Player.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class ArLive2Player : public AR::IArLivePlayer, public RtcTick, public PlayBuffe
7474

7575
virtual bool OnArPlyNeedMoreAudioData(void*player);
7676
virtual bool OnArPlyNeedMoreVideoData(void*player);
77+
virtual bool OnArPlyAppIsBackground(void* player);
7778
virtual void OnArPlyAudio(void*player, const char*pData, int nSampleHz, int nChannels, int64_t pts);
7879
virtual void OnArPlyVideo(void*player, int fmt, int ww, int hh, uint8_t**pData, int*linesize, int64_t pts);
7980
virtual void OnArPlySeiData(void* player, const char* pData, int nLen, int64_t pts);

ArLiveLite/PlayBuffer.cpp

Lines changed: 67 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ static int MixAudio(int iChannelNum, short* sourceData1, short* sourceData2, flo
9191

9292
#ifdef WEBRTC_ANDROID
9393
//android 的某些机型,音频播放的线程实时性不高,所以一次性需要更多的数据
94-
const int kMaxAudioPlaySize = 15;
94+
const int kMaxAudioPlaySize = 30;
9595
#else
96-
const int kMaxAudioPlaySize = 5;
96+
const int kMaxAudioPlaySize = 20;
9797
#endif
98-
const int kMaxVedeoPlaySize = 3;
98+
const int kMaxVedeoPlaySize = kMaxAudioPlaySize / 2;
9999

100100

101101
PlayBuffer::PlayBuffer(void)
@@ -104,6 +104,8 @@ PlayBuffer::PlayBuffer(void)
104104
, b_video_decoded_(false)
105105
, b_audio_decoded_(false)
106106
, b_app_in_background_(false)
107+
, n_last_render_video_time_(0)
108+
, n_last_render_video_pts_(0)
107109
{
108110
aud_data_resamp_ = new char[kMaxDataSizeSamples];
109111
memset(aud_data_resamp_, 0, kMaxDataSizeSamples);
@@ -120,22 +122,40 @@ PlayBuffer::~PlayBuffer(void)
120122

121123
int PlayBuffer::DoVidRender(bool bVideoPaused)
122124
{
123-
VideoData* vidPkt = NULL;
124-
{
125-
rtc::CritScope cs(&cs_video_play_);
126-
if (lst_video_play_.size() > 0) {
127-
vidPkt = lst_video_play_.front();
128-
lst_video_play_.pop_front();
125+
bool bRender = false;
126+
while (1) {
127+
VideoData* vidPkt = NULL;
128+
{
129+
rtc::CritScope cs(&cs_video_play_);
130+
if (lst_video_play_.size() > 0) {
131+
vidPkt = lst_video_play_.front();
132+
if (n_last_render_video_pts_ == 0 || n_last_render_video_pts_ > vidPkt->pts_) {
133+
n_last_render_video_time_ = rtc::TimeUTCMillis();
134+
n_last_render_video_pts_ = vidPkt->pts_;
135+
}
136+
if (vidPkt->pts_ <= (rtc::TimeUTCMillis() - n_last_render_video_time_) + n_last_render_video_pts_) {
137+
lst_video_play_.pop_front();
138+
}
139+
else {
140+
vidPkt = NULL;
141+
}
142+
}
129143
}
130-
}
131144

132-
if (vidPkt != NULL) {
133-
//RTC_LOG(LS_INFO) << "DoRender video pts: " << vidPkt->pts_ << " plytime: " << play_pts_time_;
134-
if (!bVideoPaused && !b_app_in_background_) {
135-
OnBufferVideoRender(vidPkt, vidPkt->pts_);
145+
if (vidPkt != NULL) {
146+
//RTC_LOG(LS_INFO) << "DoRender video pts: " << vidPkt->pts_ << " plytime: " << play_pts_time_;
147+
if (!bVideoPaused && !b_app_in_background_) {
148+
if (!bRender) {//@Eric - 跳帧处理,防止一次性输出过多
149+
OnBufferVideoRender(vidPkt, vidPkt->pts_);
150+
}
151+
bRender = true;
152+
}
153+
delete vidPkt;
154+
vidPkt = NULL;
155+
}
156+
else {
157+
break;
136158
}
137-
delete vidPkt;
138-
vidPkt = NULL;
139159
}
140160

141161
return 0;
@@ -148,9 +168,11 @@ int PlayBuffer::DoAudRender(bool mix, void* audioSamples, uint32_t samplesPerSec
148168
{//*
149169
rtc::CritScope cs(&cs_audio_play_);
150170
//RTC_LOG(LS_INFO) << "Audio list size: " << lst_audio_play_.size();
171+
151172
if (lst_audio_play_.size() > 0) {
152173
audPkt = lst_audio_play_.front();
153174
lst_audio_play_.pop_front();
175+
154176
}
155177

156178
}
@@ -182,6 +204,10 @@ int PlayBuffer::DoAudRender(bool mix, void* audioSamples, uint32_t samplesPerSec
182204
memcpy(audioSamples, pOutputPcm, a_frame_size);
183205
}
184206
}
207+
{
208+
n_last_render_video_time_ = rtc::TimeUTCMillis();
209+
n_last_render_video_pts_ = audPkt->pts_;
210+
}
185211
delete audPkt;
186212
audPkt = NULL;
187213
}
@@ -298,6 +324,10 @@ bool PlayBuffer::NeedMoreVideoPlyData()
298324
rtc::CritScope cs(&cs_video_play_);
299325
return lst_video_play_.size() <= kMaxVedeoPlaySize;
300326
}
327+
bool PlayBuffer::AppIsBackground()
328+
{
329+
return b_app_in_background_;
330+
}
301331
void PlayBuffer::PlayVideoData(VideoData* videoData)
302332
{
303333
//RTC_LOG(LS_INFO) << "PlayVideoData pts: " << videoData->pts_;
@@ -341,7 +371,7 @@ void PlayBuffer::PlayVideoData(VideoData* videoData)
341371
//@Eric - 跳帧处理 - 防止缓存太多:内存报警,渲染延时增大
342372
while (lst_video_play_.size() > 1) {
343373
int64_t timeGap = lst_video_play_.back()->pts_ - lst_video_play_.front()->pts_;
344-
if (timeGap < (kMaxAudioPlaySize << 1) * 10) {
374+
if (timeGap < (kMaxVideoPlaySize << 1) * 10) {
345375
break;
346376
}
347377
VideoData* pkt = lst_video_play_.front();
@@ -363,27 +393,39 @@ void PlayBuffer::PlayAudioData(PcmData*pcmData)
363393
int64_t dropPts = -1;
364394
{
365395
rtc::CritScope cs(&cs_audio_play_);
396+
lst_audio_play_.push_back(pcmData);
397+
366398
//@Eric - 跳帧处理 - 防止缓存太多:延时增大
367-
while (lst_audio_play_.size() > (kMaxAudioPlaySize << 1)) {
399+
if (lst_audio_play_.size() >= kMaxAudioPlaySize) {//清一半缓存
400+
while (lst_audio_play_.size() > kMaxAudioPlaySize/2) {
401+
PcmData* pkt = lst_audio_play_.front();
402+
dropPts = pkt->pts_;
403+
lst_audio_play_.pop_front();
404+
delete pkt;
405+
406+
OnBufferAudioDropped();
407+
}
408+
}
409+
}
410+
411+
#if 0
412+
if (b_app_in_background_) {
413+
if (lst_audio_play_.size() > 0) {
368414
PcmData* pkt = lst_audio_play_.front();
369415
dropPts = pkt->pts_;
370-
lst_audio_play_.pop_front();
371-
delete pkt;
372-
373-
OnBufferAudioDropped();
374416
}
375-
lst_audio_play_.push_back(pcmData);
376417
}
418+
#endif
377419

378420
if (dropPts != -1) {
379421
//@Eric - 跳帧处理 - 防止缓存太多:内存报警,渲染延时增大
380422
while (lst_video_play_.size() > 1) {
381423
if (lst_video_play_.front()->pts_ > dropPts) {
382424
break;
383425
}
384-
VideoData* pkt = lst_video_play_.front();
426+
VideoData* vidPkt = lst_video_play_.front();
385427
lst_video_play_.pop_front();
386-
delete pkt;
428+
delete vidPkt;
387429

388430
OnBufferVideoDropped();
389431
}

ArLiveLite/PlayBuffer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class PlayBuffer
7777

7878
bool NeedMoreAudioPlyData();
7979
bool NeedMoreVideoPlyData();
80+
bool AppIsBackground();
8081
void PlayVideoData(VideoData *videoData);
8182
void PlayAudioData(PcmData*pcmData);
8283

@@ -91,6 +92,8 @@ class PlayBuffer
9192
bool b_video_decoded_;
9293
bool b_audio_decoded_;
9394
bool b_app_in_background_; // app 是否进入后台
95+
int64_t n_last_render_video_time_;
96+
int64_t n_last_render_video_pts_;
9497

9598
//* 显示缓存
9699
rtc::RecursiveCriticalSection cs_audio_play_;

ArLiveLite/player/ARFFPlayer.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ static const AVRational TIMEBASE_MS = { 1, 1000 };
1313
#define fftime_to_milliseconds(ts) (av_rescale(ts, 1000, AV_TIME_BASE))
1414
#define milliseconds_to_fftime(ms) (av_rescale(ms, AV_TIME_BASE, 1000))
1515

16-
17-
18-
19-
2016
int16_t WebRtcSpl_MaxAbsValueW16_I(const int16_t* vector, size_t length) {
2117
size_t i = 0;
2218
int absolute = 0, maximum = 0;
@@ -451,7 +447,7 @@ void ARFFPlayer::RunOnce()
451447
}
452448
}
453449
while (callback_.OnArPlyNeedMoreVideoData(this)) {
454-
if (!FFBuffer::DoDecodeVideo()) {
450+
if (!FFBuffer::DoDecodeVideo(callback_.OnArPlyAppIsBackground(this))) {
455451
break;
456452
}
457453
}
@@ -745,6 +741,13 @@ void ARFFPlayer::OnBufferStatusChanged(PlayStatus playStatus)
745741
callback_.OnArPlyPlaying(this, user_set_.b_audio_enabled_, user_set_.b_video_enabled_);
746742
}
747743
}
744+
bool ARFFPlayer::OnBufferIsKeyFrame(AVPacket* pkt)
745+
{
746+
if (pkt->flags & AV_PKT_FLAG_KEY) {
747+
return true;
748+
}
749+
return false;
750+
}
748751
bool ARFFPlayer::OnBufferGetPuased()
749752
{
750753
return !user_set_.b_audio_enabled_ && !user_set_.b_video_enabled_;

ArLiveLite/player/ARFFPlayer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class ARFFPlayer : public ARPlayer, public FFBuffer, public rtc::Thread
7777
virtual void OnBufferDecodeAudioData(AVPacket* pkt);
7878
virtual void OnBufferDecodeVideoData(AVPacket* pkt);
7979
virtual void OnBufferStatusChanged(PlayStatus playStatus);
80+
virtual bool OnBufferIsKeyFrame(AVPacket* pkt);
8081
virtual bool OnBufferGetPuased();
8182
virtual float OnBufferGetSpeed();
8283

ArLiveLite/player/ARPlayer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class ARPlayerEvent
6262

6363
virtual bool OnArPlyNeedMoreAudioData(void*player) { return true; };
6464
virtual bool OnArPlyNeedMoreVideoData(void*player) { return true; };
65+
virtual bool OnArPlyAppIsBackground(void* player) { return false; };
6566
virtual void OnArPlyAudio(void*player, const char*pData, int nSampleHz, int nChannels, int64_t pts) {};
6667
virtual void OnArPlyVideo(void*player, int fmt, int ww, int hh, uint8_t**pData, int*linesize, int64_t pts) {};
6768
virtual void OnArPlyRawVideo(void* player, const char* pData, int nLen, bool bKeyframe, int64_t pts) {};

ArLiveLite/player/FFBuffer.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ FFBuffer::FFBuffer()
99
: play_status_(PS_Init)
1010
, play_mode_(PM_Fluent)
1111
, b_reset_time_(false)
12+
, b_need_keyframe_(true)
1213
, n_cacheing_time_(DFT_CACHEING_TIME)
1314
, n_cache_to_play_max_(1000)
1415
, n_cache_to_play_time_(1000)
@@ -283,32 +284,46 @@ void FFBuffer::DoTick()
283284

284285
bool FFBuffer::DoDecodeAudio()
285286
{
287+
bool bRet = false;
286288
rtc::CritScope l(&cs_audio_decode_);
287-
while (lst_audio_decode_.size() > 0) {
289+
if (lst_audio_decode_.size() > 0) {
288290
RecvPacket* audPkt = lst_audio_decode_.front();
289291
lst_audio_decode_.pop_front();
290292

291293
OnBufferDecodeAudioData(audPkt->pkt_);
292294
delete audPkt;
293295
audPkt = NULL;
294-
return true;
296+
bRet = true;
295297
}
296298

297-
return false;
299+
return bRet;
298300
}
299-
bool FFBuffer::DoDecodeVideo()
301+
bool FFBuffer::DoDecodeVideo(bool bBackground)
300302
{
303+
bool bRet = false;
301304
rtc::CritScope l(&cs_video_decode_);
302-
while (lst_video_decode_.size() > 0) {
305+
if (lst_video_decode_.size() > 0) {
303306
RecvPacket* vidPkt = lst_video_decode_.front();
304307
lst_video_decode_.pop_front();
305-
OnBufferDecodeVideoData(vidPkt->pkt_);
308+
309+
if (bBackground) {
310+
b_need_keyframe_ = true;
311+
}
312+
else {
313+
if (b_need_keyframe_ && OnBufferIsKeyFrame(vidPkt->pkt_)) {
314+
b_need_keyframe_ = false;
315+
}
316+
}
317+
318+
if (!b_need_keyframe_ && !bBackground) {
319+
OnBufferDecodeVideoData(vidPkt->pkt_);
320+
}
306321
delete vidPkt;
307322
vidPkt = NULL;
308-
return true;
323+
bRet = true;
309324
}
310325

311-
return false;
326+
return bRet;
312327
}
313328

314329
void FFBuffer::SetPlaySetting(bool bAuto, int nCacheTime, int nMinCacheTime, int nMaxCacheTime, int nVideoBlockThreshold)

0 commit comments

Comments
 (0)