Skip to content

Commit

Permalink
Fix seek bugs that was blocking the player.
Browse files Browse the repository at this point in the history
  • Loading branch information
desjare committed Sep 28, 2019
1 parent d3451a1 commit c2eb7b2
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 13 deletions.
14 changes: 14 additions & 0 deletions mediadecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ namespace {
}

videoFrame->timeUs = timeUs;
logger::Trace("Decode frame %f", chrono::Seconds(timeUs));

// Convert the video frame to output format using sws_scale
if(videoStream->swsContext)
Expand Down Expand Up @@ -549,6 +550,7 @@ namespace {

void Seek(mediadecoder::Producer* producer )
{
logger::Info("Seek %f", chrono::Seconds(producer->seekTime));
for( auto it = producer->streams.begin(); it != producer->streams.end(); ++it)
{
mediadecoder::Stream* stream = *it;
Expand Down Expand Up @@ -1343,6 +1345,11 @@ namespace mediadecoder

void Release(Producer* producer, VideoFrame* frame)
{
if(!frame)
{
return;
}

const bool outcome
= producer->videoFramePool->push(frame);

Expand All @@ -1354,6 +1361,11 @@ namespace mediadecoder

void Release(Producer* producer, AudioFrame* frame)
{
if(!frame)
{
return;
}

const bool outcome
= producer->audioFramePool->push(frame);
if(!outcome)
Expand Down Expand Up @@ -1427,6 +1439,8 @@ namespace mediadecoder
std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_PLAYBACK_SLEEP_TIME_MS));
haveVideo = producer->videoQueueSize > nbBufferForPlayback;
}

logger::Info("Playback ready %d buffers", producer->videoQueueSize.load());
}
}

Expand Down
69 changes: 58 additions & 11 deletions player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@ namespace {
const int64_t queueFullSleepTimeMs = 100;
const int64_t pauseSleepTimeMs = 500;
const int64_t doneSleepTimeMs = 2000;

const int64_t sleepThresholdUs = 10000;
const int64_t sleepThresholdLogUs = 1000000;
const int64_t millisecondUs = 1000;
const int64_t logDeltaThresholdUs = 1000;

const double seekFrameSkipThresholdSec = 30.0;

player::SwapBufferCallback swapBufferCallback;
}

namespace {
bool WaitForPlayback(const char* name, uint64_t startTimeUs, uint64_t timeUs, int64_t waitThresholdUs)
{
const int64_t sleepThresholdUs = 10000;
const int64_t millisecondUs = 1000;
const int64_t logDeltaThresholdUs = 100;

int64_t waitTime = chrono::Wait(startTimeUs, timeUs);

if( waitTime <= 0 )
Expand All @@ -33,6 +36,11 @@ namespace {
{
if( waitTime >= sleepThresholdUs )
{
if(waitTime >= sleepThresholdLogUs)
{
logger::Warn("WaitForPlayback. %s Got frame to soon %f seconds. Sleeping.", name, chrono::Seconds(waitTime));
}

std::this_thread::sleep_for(std::chrono::microseconds(waitTime-millisecondUs));
waitTime = chrono::Wait(startTimeUs, timeUs);

Expand Down Expand Up @@ -436,6 +444,42 @@ namespace player
assert(!player->buffering);
scopeguard::SetValue bufferingGuard(player->buffering, true, false);

mediadecoder::Release(player->producer, player->videoFrame);
mediadecoder::WaitForPlayback(player->producer);

int64_t sleepTime = 0;

// skip old frames from decoder
do
{
if(!player->videoFrame)
{
mediadecoder::Consume(player->producer, player->videoFrame);
}

if(!player->videoFrame)
{
break;
}

int64_t deltaUs = player->videoFrame->timeUs - timeUs;
double deltaSec = chrono::Seconds(deltaUs);
if(deltaSec < seekFrameSkipThresholdSec && deltaSec > 0.0)
{
logger::Warn("Seek sleeping for %f", chrono::Seconds(deltaUs));
sleepTime = deltaUs;
break;
}

logger::Warn("Player: Seek skipping frame %f frame %ld time %ld", chrono::Seconds(deltaUs), player->videoFrame->timeUs, timeUs);

mediadecoder::Release(player->producer, player->videoFrame);
player->videoFrame = nullptr;


} while(true);


Result result = StartAudioPlayback(player);
if(!result)
{
Expand All @@ -445,6 +489,12 @@ namespace player

// reset playback start time
player->playbackStartTimeUs = static_cast<int64_t>(chrono::Now()) - static_cast<int64_t>(timeUs);

// we got video frame in the future, sleep until we can play them
if(sleepTime != 0)
{
std::this_thread::sleep_for(std::chrono::microseconds(sleepTime));
}

logger::Info("Seek end");
}
Expand Down Expand Up @@ -513,7 +563,7 @@ namespace player
const bool drawFrame
= WaitForPlayback("video", player->playbackStartTimeUs, player->videoFrame->timeUs, waitThresholdUs);

if( drawFrame )
if( drawFrame && player->videoFrame )
{
profiler::ScopeProfiler profiler(profiler::PROFILER_VIDEO_DRAW);

Expand All @@ -539,19 +589,16 @@ namespace player
mediadecoder::Release(player->producer, player->videoFrame);
player->videoFrame = nullptr;
}
else
else if(player->videoFrame)
{
logger::Warn( "Player: No draw frame" );
mediadecoder::Release(player->producer, player->videoFrame);
player->videoFrame = nullptr;
}
}
else if(player->producer->done)
{
std::this_thread::sleep_for(std::chrono::milliseconds(doneSleepTimeMs));
}
else
{
logger::Warn( "Player: No video frame" );
}
}

void Close(Player* player)
Expand Down
2 changes: 0 additions & 2 deletions subtitle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,6 @@ namespace
{
field = true;
}

}
else
{
Expand Down Expand Up @@ -462,7 +461,6 @@ namespace
return Result(false, "ParseSubRipTime invalid format %s", t.c_str());
}


return result;
}

Expand Down

0 comments on commit c2eb7b2

Please sign in to comment.