bool MythDVDPlayer::DoJumpChapter(int chapter) { if (!player_ctx->buffer->IsDVD()) return false; int total = GetNumChapters(); int current = GetCurrentChapter(); if (chapter < 0 || chapter > total) { if (chapter < 0) { chapter = current -1; if (chapter < 0) chapter = 0; } else if (chapter > total) { chapter = current + 1; if (chapter > total) chapter = total; } } bool success = player_ctx->buffer->DVD()->playTrack(chapter); if (success) { if (decoder) { decoder->UpdateFramesPlayed(); if (player_ctx->buffer->DVD()->GetCellStart() == 0) decoder->SeekReset(framesPlayed, 0, true, true); } ClearAfterSeek(!player_ctx->buffer->IsInDiscMenuOrStillFrame()); } jumpchapter = 0; return success; }
bool MythDVDPlayer::VideoLoop(void) { if (!player_ctx->buffer->IsDVD()) { SetErrored("RingBuffer is not a DVD."); return !IsErrored(); } int nbframes = 0; if (videoOutput) nbframes = videoOutput->ValidVideoFrames(); #if 0 LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Validframes %1, FreeFrames %2, VideoPaused %3") .arg(nbframes).arg(videoOutput->FreeVideoFrames()).arg(videoPaused)); #endif // completely drain the video buffers for certain situations bool release_all = player_ctx->buffer->DVD()->DVDWaitingForPlayer() && (nbframes > 0); bool release_one = (nbframes > 1) && videoPaused && !allpaused && (!videoOutput->EnoughFreeFrames() || player_ctx->buffer->DVD()->IsWaiting() || player_ctx->buffer->DVD()->IsInStillFrame()); if (release_all || release_one) { if (nbframes < 5 && videoOutput) videoOutput->UpdatePauseFrame(disp_timecode); // if we go below the pre-buffering limit, the player will pause // so do this 'manually' DisplayNormalFrame(false); dvd_stillframe_showing = false; return !IsErrored(); } // clear the mythtv imposed wait state if (player_ctx->buffer->DVD()->DVDWaitingForPlayer()) { LOG(VB_PLAYBACK, LOG_INFO, LOC + "Clearing MythTV DVD wait state"); bool inStillFrame = player_ctx->buffer->DVD()->IsInStillFrame(); player_ctx->buffer->DVD()->SkipDVDWaitingForPlayer(); ClearAfterSeek(true); if (!inStillFrame && videoPaused && !allpaused) UnpauseVideo(); return !IsErrored(); } // wait for the video buffers to drain if (nbframes < 2) { // clear the DVD wait state if (player_ctx->buffer->DVD()->IsWaiting()) { LOG(VB_PLAYBACK, LOG_INFO, LOC + "Clearing DVD wait state"); bool inStillFrame = player_ctx->buffer->DVD()->IsInStillFrame(); player_ctx->buffer->DVD()->WaitSkip(); if (!inStillFrame && videoPaused && !allpaused) UnpauseVideo(); return !IsErrored(); } // we need a custom presentation method for still frame menus with audio if (player_ctx->buffer->DVD()->IsInMenu() && !player_ctx->buffer->DVD()->IsInStillFrame()) { // ensure we refresh the pause frame if (!dvd_stillframe_showing) needNewPauseFrame = true; RefreshPauseFrame(); dvd_stillframe_showing = true; DisplayLastFrame(); return !IsErrored(); } // the still frame is treated as a pause frame if (player_ctx->buffer->DVD()->IsInStillFrame()) { // ensure we refresh the pause frame if (!dvd_stillframe_showing) needNewPauseFrame = true; // we are in a still frame so pause video output if (!videoPaused) { PauseVideo(); return !IsErrored(); } // see if the pause frame has timed out StillFrameCheck(); // flag if we have no frame if (nbframes == 0) { LOG(VB_PLAYBACK, LOG_WARNING, LOC + "In DVD Menu: No video frames in queue"); usleep(10000); return !IsErrored(); } dvd_stillframe_showing = true; } else { dvd_stillframe_showing = false; } } // unpause the still frame if more frames become available if (dvd_stillframe_showing && nbframes > 1) { UnpauseVideo(); dvd_stillframe_showing = false; return !IsErrored(); } return MythPlayer::VideoLoop(); }
bool MythCommFlagPlayer::RebuildSeekTable( bool showPercentage, StatusCallback cb, void* cbData) { int percentage = 0; uint64_t myFramesPlayed = 0, pmap_first = 0, pmap_last = 0; killdecoder = false; framesPlayed = 0; using_null_videoout = true; // clear out any existing seektables player_ctx->LockPlayingInfo(__FILE__, __LINE__); if (player_ctx->playingInfo) { player_ctx->playingInfo->ClearPositionMap(MARK_KEYFRAME); player_ctx->playingInfo->ClearPositionMap(MARK_GOP_START); player_ctx->playingInfo->ClearPositionMap(MARK_GOP_BYFRAME); } player_ctx->UnlockPlayingInfo(__FILE__, __LINE__); if (OpenFile() < 0) return false; SetPlaying(true); if (!InitVideo()) { VERBOSE(VB_IMPORTANT, LOC_ERR + "RebuildSeekTable unable to initialize video"); SetPlaying(false); return false; } ClearAfterSeek(); int save_timeout = 1001; MythTimer flagTime, ui_timer, inuse_timer, save_timer; flagTime.start(); ui_timer.start(); inuse_timer.start(); save_timer.start(); DecoderGetFrame(kDecodeNothing,true); if (showPercentage) { if (totalFrames) printf(" "); else printf(" "); fflush( stdout ); } int prevperc = -1; while (!GetEof()) { if (inuse_timer.elapsed() > 2534) { inuse_timer.restart(); player_ctx->LockPlayingInfo(__FILE__, __LINE__); if (player_ctx->playingInfo) player_ctx->playingInfo->UpdateInUseMark(); player_ctx->UnlockPlayingInfo(__FILE__, __LINE__); } if (save_timer.elapsed() > save_timeout) { // Give DB some breathing room if it gets far behind.. if (myFramesPlayed - pmap_last > 5000) usleep(200 * 1000); // If we're already saving, just save a larger block next time.. if (RebuildSaver::GetCount(decoder) < 1) { pmap_last = myFramesPlayed; QThreadPool::globalInstance()->start( new RebuildSaver(decoder, pmap_first, pmap_last)); pmap_first = pmap_last + 1; } save_timer.restart(); } if (ui_timer.elapsed() > 98) { ui_timer.restart(); if (totalFrames) { float elapsed = flagTime.elapsed() * 0.001f; int flagFPS = (elapsed > 0.0f) ? (int)(myFramesPlayed / elapsed) : 0; percentage = myFramesPlayed * 100 / totalFrames; if (cb) (*cb)(percentage, cbData); if (showPercentage) { printf( "\b\b\b\b\b\b\b\b\b\b\b\b\b" ); printf( "%3d%%/%5dfps", percentage, flagFPS ); fflush( stdout ); } if (percentage % 10 == 0 && prevperc != percentage) { prevperc = percentage; VERBOSE(VB_GENERAL, QString("%1%/%2""fps") .arg(percentage).arg(flagFPS)); } } else { if (showPercentage) { printf( "\b\b\b\b\b\b" ); printf( "%6lld", (long long)myFramesPlayed ); fflush( stdout ); } if (myFramesPlayed % 1000 == 0) VERBOSE(VB_GENERAL, QString("%1").arg(myFramesPlayed)); } } if (DecoderGetFrame(kDecodeNothing,true)) myFramesPlayed = decoder->GetFramesRead(); } if (showPercentage) { if (totalFrames) printf( "\b\b\b\b\b\b\b" ); printf( "\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b" ); fflush( stdout ); } SaveTotalDuration(); SetPlaying(false); killdecoder = true; QThreadPool::globalInstance()->start( new RebuildSaver(decoder, pmap_first, myFramesPlayed)); RebuildSaver::Wait(decoder); return true; }
void MythDVDPlayer::DoChangeDVDTrack(void) { if (decoder) decoder->ChangeDVDTrack(need_change_dvd_track > 0); ClearAfterSeek(!player_ctx->buffer->IsInDiscMenuOrStillFrame()); }