Example #1
0
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;
}
Example #2
0
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();
}
Example #3
0
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;
}
Example #4
0
void MythDVDPlayer::DoChangeDVDTrack(void)
{
    if (decoder)
        decoder->ChangeDVDTrack(need_change_dvd_track > 0);
    ClearAfterSeek(!player_ctx->buffer->IsInDiscMenuOrStillFrame());
}