Ticket #6355: frontend.patch

File frontend.patch, 6.4 KB (added by tomimo@…, 15 years ago)

This patch fixes the rewinding hang on mythfrontend

  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    157157      parentWidget(NULL), embedid(0),
    158158      embx(-1), emby(-1), embw(-1), embh(-1),
    159159      // State
     160      playingWaitSignal(false),
     161      decoderThreadPausedSignal(false),
     162      pause_signal(false),          unpause_signal(false),
    160163      eof(false),
    161164      m_double_framerate(false),    m_double_process(false),
    162165      m_can_double(false),          m_deint_possible(true),
     
    473476    next_normal_speed = false;
    474477    decoder_lock.unlock();
    475478
    476     // Qt4 requires a QMutex as a parameter...
    477     // not sure if this is the best solution.
    478     // Mutex Must be locked before wait.
    479     QMutex mutex;
    480     mutex.lock();
    481 
    482     while (!eof && !actuallypaused &&
    483            !decoderThreadPaused.wait(&mutex, 100) &&
    484            !eof && !actuallypaused)
     479    bool status;
     480    while (!eof && !actuallypaused)
    485481    {
     482        status = true;
     483        decoderThreadPausedMutex.lock();
     484        if (decoderThreadPausedSignal == false)
     485            status = decoderThreadPaused.wait(&decoderThreadPausedMutex, 100);
     486        decoderThreadPausedSignal = false;
     487        decoderThreadPausedMutex.unlock();
     488        if (status == false)
    486489        VERBOSE(VB_IMPORTANT, LOC_WARN +
    487490                "Waited too long for decoder to pause");
    488491    }
     
    547550
    548551bool NuppelVideoPlayer::IsPaused(bool *is_pause_still_possible) const
    549552{
     553    QMutexLocker locker(&internalPauseLock);
     554
    550555    bool rbf_playing = player_ctx->buffer && !player_ctx->buffer->isPaused();
    551556    bool aud_playing = audioOutput && !audioOutput->IsPaused();
    552557    if (is_pause_still_possible)
     
    565570void NuppelVideoPlayer::PauseVideo(bool wait)
    566571{
    567572    QMutexLocker locker(&pauseUnpauseLock);
     573
     574    // Has the wakeup signall already been delivered beforehand ?
     575    if (pause_signal)
     576    {
     577        pause_signal = false;
     578        return;
     579    }
     580
    568581    video_actually_paused = false;
    569582    pausevideo = true;
    570583
    571584    for (uint i = 0; wait && !video_actually_paused; i++)
    572585    {
     586        if (pause_signal == false)
    573587        videoThreadPaused.wait(&pauseUnpauseLock, 250);
     588        pause_signal = false;
    574589
    575590        if (video_actually_paused || eof)
    576591            break;
     
    585600    QMutexLocker locker(&pauseUnpauseLock);
    586601    pausevideo = false;
    587602
     603    // Has the wakeup signall already been delivered beforehand ?
     604    if (unpause_signal && !video_actually_paused)
     605    {
     606        unpause_signal = false;
     607        return;
     608    }
     609
    588610    for (uint i = 0; wait && video_actually_paused; i++)
    589611    {
     612        if (unpause_signal == false)
    590613        videoThreadUnpaused.wait(&pauseUnpauseLock, 250);
     614        unpause_signal = false;
    591615
    592616        if (!video_actually_paused || eof)
    593617            break;
     
    600624void NuppelVideoPlayer::SetVideoActuallyPaused(bool val)
    601625{
    602626    QMutexLocker locker(&pauseUnpauseLock);
     627
    603628    video_actually_paused = val;
    604629
    605630    if (val)
     631    {
     632        pause_signal = true;
    606633        videoThreadPaused.wakeAll();
    607     else
     634    } else {
     635        unpause_signal = true;
    608636        videoThreadUnpaused.wakeAll();
    609637}
     638}
    610639
    611640bool NuppelVideoPlayer::IsVideoActuallyPaused(void) const
    612641{
     
    659688
    660689    playing = is_playing;
    661690
     691    playingWaitSignal = true;
    662692    playingWaitCond.wakeAll();
    663693}
    664694
     
    674704
    675705    while ((wait_for != playing) && ((uint)t.elapsed() < wait_in_msec))
    676706    {
     707        if (playingWaitSignal == false)
    677708        playingWaitCond.wait(
    678709            &playingLock, max(0,(int)wait_in_msec - t.elapsed()));
     710        playingWaitSignal = false;
    679711    }
    680712
    681713    return playing;
     
    26212653
    26222654void NuppelVideoPlayer::DisplayPauseFrame(void)
    26232655{
     2656    pauseUnpauseLock.lock();
    26242657    if (!video_actually_paused)
    26252658        videoOutput->UpdatePauseFrame();
     2659    pauseUnpauseLock.unlock();
    26262660
    26272661    if (resetvideo)
    26282662    {
     
    36503684
    36513685        if (isDummy)
    36523686        {
     3687            decoderThreadPausedMutex.lock();
     3688            decoderThreadPausedSignal = true;
    36533689            decoderThreadPaused.wakeAll();
     3690            decoderThreadPausedMutex.unlock();
    36543691            usleep(500);
    36553692            continue;
    36563693        }
     
    36623699
    36633700        if (paused)
    36643701        {
     3702            decoderThreadPausedMutex.lock();
     3703            decoderThreadPausedSignal = true;
    36653704            decoderThreadPaused.wakeAll();
     3705            decoderThreadPausedMutex.unlock();
    36663706
    36673707            if (rewindtime > 0)
    36683708            {
     
    38173857
    38183858    VERBOSE(VB_PLAYBACK, LOC + "Exited decoder loop.");
    38193859
     3860    decoderThreadPausedMutex.lock();
     3861    decoderThreadPausedSignal = true;
    38203862    decoderThreadPaused.wakeAll();
     3863    decoderThreadPausedMutex.unlock();
    38213864
    38223865    SetPlaying(false);
    38233866    killvideo = true;
     
    43654408        videosync->SetFrameInterval(frame_interval, m_double_framerate);
    43664409
    43674410    VERBOSE(VB_PLAYBACK, LOC + "DoPause() -- setting paused");
     4411
     4412    pauseUnpauseLock.lock();
    43684413    paused = actuallypaused = true;
     4414    pauseUnpauseLock.unlock();
     4415
     4416    decoderThreadPausedMutex.lock();
     4417    decoderThreadPausedSignal = true;
    43694418    decoderThreadPaused.wakeAll();
     4419    decoderThreadPausedMutex.unlock();
    43704420}
    43714421
    43724422void NuppelVideoPlayer::DoPlay(void)
     
    44904540    }
    44914541
    44924542    VERBOSE(VB_PLAYBACK, LOC + "DoPlay() -- setting unpaused");
     4543    QMutexLocker locker(&internalPauseLock);
     4544
     4545    pauseUnpauseLock.lock();
    44934546    paused = actuallypaused = false;
     4547    unpause_signal = true;
     4548    videoThreadUnpaused.wakeAll();
     4549    pauseUnpauseLock.unlock();
    44944550}
    44954551
    44964552bool NuppelVideoPlayer::DoRewind(void)
  • libs/libmythtv/NuppelVideoPlayer.h

     
    556556    QWaitCondition videoThreadPaused;
    557557    QWaitCondition videoThreadUnpaused;
    558558    mutable QWaitCondition playingWaitCond;
     559    mutable bool     playingWaitSignal;
    559560    mutable QMutex vidExitLock;
    560561    mutable QMutex pauseUnpauseLock;
    561562    mutable QMutex internalPauseLock;
     563    QMutex   decoderThreadPausedMutex;
     564    bool     decoderThreadPausedSignal;
     565    QMutex   pauseLock;
     566    bool     pause_signal;
     567    bool     unpause_signal;
    562568    mutable QMutex playingLock;
    563569    bool     eof;             ///< At end of file/ringbuffer
    564570    bool     m_double_framerate;///< Output fps is double Video (input) rate