Ticket #9824: 0040-MythPlayer-Improvements-to-DVB-S-radio-playback.patch

File 0040-MythPlayer-Improvements-to-DVB-S-radio-playback.patch, 13.6 KB (added by Lawrence Rust <lvr@…>, 8 years ago)
  • mythtv/libs/libmythtv/RingBuffer.cpp

    From ea5e75df4e52efc5e03cc2bf2ce4893097c7375b Mon Sep 17 00:00:00 2001
    From: Lawrence Rust <lvr@softsystem.co.uk>
    Date: Thu, 2 Jun 2011 12:55:13 +0200
    Subject: [PATCH 40/42] MythPlayer: Improvements to DVB-S radio playback
    
    This fixes a number of issues to do with changing program to DVB-S radio and
    the lack of video stream causing garbage video display.
    
    Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
    ---
     mythtv/libs/libmythtv/RingBuffer.cpp      |    3 +-
     mythtv/libs/libmythtv/avformatdecoder.cpp |   13 +++
     mythtv/libs/libmythtv/mythplayer.cpp      |  123 +++++++++++++++++++----------
     mythtv/libs/libmythtv/mythplayer.h        |    2 +-
     mythtv/libs/libmythtv/tv_play.cpp         |    4 +-
     5 files changed, 99 insertions(+), 46 deletions(-)
    
    diff --git a/mythtv/libs/libmythtv/RingBuffer.cpp b/mythtv/libs/libmythtv/RingBuffer.cpp
    index 1e40c43..95fb96b 100644
    a b int RingBuffer::safe_read(RemoteFile *rf, void *data, uint sz) 
    761761void RingBuffer::UpdateRawBitrate(uint raw_bitrate)
    762762{
    763763    VERBOSE(VB_FILE, LOC + QString("UpdateRawBitrate(%1Kb)").arg(raw_bitrate));
    764     if (raw_bitrate < 2500)
     764    // NB DVB-S radio can be 64kbps
     765    if (raw_bitrate < 64)
    765766    {
    766767        VERBOSE(VB_FILE, LOC +
    767768                QString("UpdateRawBitrate(%1Kb) - ignoring bitrate,")
  • mythtv/libs/libmythtv/avformatdecoder.cpp

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
    index 548de7b..fed322a 100644
    a b bool AvFormatDecoder::GetFrame(DecodeType decodetype) 
    42724272                av_init_packet(pkt);
    42734273            }
    42744274
     4275            // NB av_read_frame will block until
     4276            // either a frame is read or an error occurs
     4277            // so MythPlayer::DecoderLoop will be unable to pause or stop
    42754278            int retval;
    42764279            if (!ic || ((retval = av_read_frame(ic, pkt)) < 0))
    42774280            {
    bool AvFormatDecoder::GetFrame(DecodeType decodetype) 
    44214424            case CODEC_TYPE_AUDIO:
    44224425            {
    44234426                if (!ProcessAudioPacket(curstream, pkt, decodetype))
     4427                {
    44244428                    have_err = true;
     4429                    if (!has_video)
     4430                    {
     4431                        VERBOSE(VB_PLAYBACK, LOC +
     4432                            "GetFrame: exiting due to audio decode error");
     4433                        av_free_packet(pkt);
     4434                        delete pkt;
     4435                        return false;
     4436                    }
     4437                }
    44254438                break;
    44264439            }
    44274440
  • mythtv/libs/libmythtv/mythplayer.cpp

    diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
    index 3233b96..1155a7b 100644
    a b bool MythPlayer::Pause(void) 
    353353
    354354bool MythPlayer::Play(float speed, bool normal, bool unpauseaudio)
    355355{
    356     pauseLock.lock();
     356    QMutexLocker locker(&pauseLock);
    357357    VERBOSE(VB_PLAYBACK, LOC +
    358358            QString("Play(%1, normal %2, unpause audio %3)")
    359359            .arg(speed,5,'f',1).arg(normal).arg(unpauseaudio));
    bool MythPlayer::Play(float speed, bool normal, bool unpauseaudio) 
    361361    if (deleteMap.IsEditing())
    362362    {
    363363        VERBOSE(VB_IMPORTANT, LOC + "Ignoring Play(), in edit mode.");
    364         pauseLock.unlock();
    365364        return false;
    366365    }
    367366
    bool MythPlayer::Play(float speed, bool normal, bool unpauseaudio) 
    373372    allpaused = false;
    374373    next_play_speed   = speed;
    375374    next_normal_speed = normal;
    376     pauseLock.unlock();
    377375    return true;
    378376}
    379377
    void MythPlayer::ReinitOSD(void) 
    548546    if (videoOutput && !using_null_videoout)
    549547    {
    550548        osdLock.lock();
    551         if (QThread::currentThread() != (QThread*)playerThread)
     549        if (QThread::currentThread() != playerThread)
    552550        {
    553551            reinit_osd = true;
    554552            osdLock.unlock();
    void MythPlayer::DisplayNormalFrame(bool check_prebuffer) 
    19321930    // clear the buffering state
    19331931    SetBuffering(false);
    19341932
    1935     videoOutput->StartDisplayingFrame();
     1933    bool const bDisplayFrame = videoOutput->ValidVideoFrames() > 0;
     1934    if (bDisplayFrame)
     1935        videoOutput->StartDisplayingFrame();
     1936
    19361937    VideoFrame *frame = videoOutput->GetLastShownFrame();
    19371938    PreProcessNormalFrame();
    19381939
    1939     // handle scan type changes
    1940     AutoDeint(frame);
    1941     detect_letter_box->SwitchTo(frame);
     1940    if (!noVideoTracks)
     1941    {
     1942        // handle scan type changes
     1943        AutoDeint(frame);
     1944        detect_letter_box->SwitchTo(frame);
     1945    }
    19421946
    19431947    FrameScanType ps = m_scan;
    19441948    if (kScan_Detect == m_scan || kScan_Ignore == m_scan)
    void MythPlayer::DisplayNormalFrame(bool check_prebuffer) 
    19511955    osdLock.unlock();
    19521956
    19531957    AVSync(frame, 0);
    1954     videoOutput->DoneDisplayingFrame(frame);
     1958    if (bDisplayFrame)
     1959        videoOutput->DoneDisplayingFrame(frame);
    19551960}
    19561961
    19571962void MythPlayer::PreProcessNormalFrame(void)
    void MythPlayer::PreProcessNormalFrame(void) 
    19601965    // handle Interactive TV
    19611966    if (GetInteractiveTV())
    19621967    {
    1963         osdLock.lock();
    1964         itvLock.lock();
     1968        QMutexLocker lk1(&osdLock);
     1969
    19651970        if (osd && videoOutput->GetOSDPainter())
    19661971        {
     1972            QMutexLocker lk2(&itvLock);
     1973
    19671974            InteractiveScreen *window =
    19681975                (InteractiveScreen*)osd->GetWindow(OSD_WIN_INTERACT);
    19691976            if ((interactiveTV->ImageHasChanged() || !itvVisible) && window)
    void MythPlayer::PreProcessNormalFrame(void) 
    19711978                interactiveTV->UpdateOSD(window, videoOutput->GetOSDPainter());
    19721979                itvVisible = true;
    19731980            }
     1981            // Hide the iTV window if OSD is active otherwise OSD messages
     1982            // can be hidden
     1983            if (window && itvVisible && noVideoTracks)
     1984                window->SetVisible(!osd->IsVisible());
    19741985        }
    1975         itvLock.unlock();
    1976         osdLock.unlock();
    19771986    }
    19781987#endif // USING_MHEG
    19791988}
    bool MythPlayer::VideoLoop(void) 
    20882097        DisplayPauseFrame();
    20892098    }
    20902099    else
    2091         DisplayNormalFrame();
     2100        DisplayNormalFrame(!noVideoTracks);
    20922101
    20932102    if (using_null_videoout && decoder)
    20942103        decoder->UpdateFramesPlayed();
    void MythPlayer::SwitchToProgram(void) 
    21892198    QSharedPointer<ProgramInfo> pginfo(player_ctx->tvchain->GetSwitchProgram(
    21902199        discontinuity, newtype, newid));
    21912200    if (!pginfo)
     2201    {
     2202        VERBOSE(VB_IMPORTANT, LOC_ERR + "SwitchToProgram - No ProgramInfo");
    21922203        return;
     2204    }
    21932205
    21942206    bool newIsDummy = player_ctx->tvchain->GetCardType(newid) == "DUMMY";
    21952207
    void MythPlayer::JumpToProgram(void) 
    23042316    QSharedPointer<ProgramInfo> pginfo(player_ctx->tvchain->GetSwitchProgram(
    23052317        discontinuity, newtype, newid));
    23062318    if (!pginfo)
     2319    {
     2320        VERBOSE(VB_IMPORTANT, LOC_ERR + "JumpToProgram - No ProgramInfo");
    23072321        return;
     2322    }
    23082323    newtype = true; // force reloading of context and stream properties
    23092324
    23102325    bool newIsDummy = player_ctx->tvchain->GetCardType(newid) == "DUMMY";
    23112326    SetPlayingInfo(*pginfo);
    23122327
    23132328    Pause();
    2314     ChangeSpeed();
    23152329    ResetCaptions();
    23162330    player_ctx->tvchain->SetProgram(*pginfo);
    23172331    player_ctx->buffer->Reset(true);
    void MythPlayer::EventLoop(void) 
    25002514        player_ctx->tvchain->JumpToNext(true, 1);
    25012515        JumpToProgram();
    25022516    }
    2503     else if ((!allpaused || GetEof()) && player_ctx->tvchain &&
    2504              (decoder && !decoder->GetWaitForChange()))
     2517    else if ((!allpaused || GetEof()) &&
     2518             decoder && !decoder->GetWaitForChange() &&
     2519             player_ctx->tvchain && player_ctx->tvchain->NeedsToSwitch())
    25052520    {
    25062521        // Switch to the next program in livetv
    2507         if (player_ctx->tvchain->NeedsToSwitch())
    2508             SwitchToProgram();
     2522        SwitchToProgram();
    25092523    }
    25102524
    25112525    // Jump to the next program in livetv
    void MythPlayer::AudioEnd(void) 
    26632677
    26642678bool MythPlayer::PauseDecoder(void)
    26652679{
    2666     decoderPauseLock.lock();
    2667     if (QThread::currentThread() == (QThread*)decoderThread)
     2680    VERBOSE(VB_PLAYBACK+VB_EXTRA, LOC + "Pause decoder.");
     2681
     2682    QMutexLocker locker(&decoderPauseLock);
     2683
     2684    if (QThread::currentThread() == static_cast<QThread*>(decoderThread))
    26682685    {
     2686        pauseDecoder = false;
    26692687        decoderPaused = true;
    26702688        decoderThreadPause.wakeAll();
    2671         decoderPauseLock.unlock();
    2672         return decoderPaused;
     2689        return true;
    26732690    }
    26742691
    2675     int tries = 0;
    26762692    pauseDecoder = true;
    2677     while (decoderThread && !killdecoder && (tries++ < 100) &&
    2678           !decoderThreadPause.wait(&decoderPauseLock, 100))
     2693    int tries = 0;
     2694    while (!decoderPaused && decoderThread && !killdecoder && (tries++ < 1) &&
     2695          !decoderThreadPause.wait(locker.mutex(), 100))
    26792696    {
    26802697        VERBOSE(VB_IMPORTANT, LOC_WARN + "Waited 100ms for decoder to pause");
    26812698    }
    26822699    pauseDecoder = false;
    2683     decoderPauseLock.unlock();
    26842700    return decoderPaused;
    2685 }
     2701 }
    26862702
    26872703void MythPlayer::UnpauseDecoder(void)
    26882704{
    2689     decoderPauseLock.lock();
     2705    VERBOSE(VB_PLAYBACK+VB_EXTRA, LOC + "Unpause decoder.");
     2706
     2707    QMutexLocker locker(&decoderPauseLock);
    26902708
    2691     if (QThread::currentThread() == (QThread*)decoderThread)
     2709    if (QThread::currentThread() == static_cast<QThread*>(decoderThread))
    26922710    {
     2711        unpauseDecoder = false;
    26932712        decoderPaused = false;
    26942713        decoderThreadUnpause.wakeAll();
    2695         decoderPauseLock.unlock();
    26962714        return;
    26972715    }
    26982716
    2699     int tries = 0;
    27002717    unpauseDecoder = true;
    2701     while (decoderThread && !killdecoder && (tries++ < 100) &&
    2702           !decoderThreadUnpause.wait(&decoderPauseLock, 100))
     2718    int tries = 0;
     2719    while (decoderPaused && decoderThread && !killdecoder && (tries++ < 1) &&
     2720          !decoderThreadUnpause.wait(locker.mutex(), 100))
    27032721    {
    27042722        VERBOSE(VB_IMPORTANT, LOC_WARN + "Waited 100ms for decoder to unpause");
    27052723    }
    27062724    unpauseDecoder = false;
    2707     decoderPauseLock.unlock();
    27082725}
    27092726
    27102727void MythPlayer::DecoderStart(bool start_paused)
    void MythPlayer::DecoderEnd(void) 
    27302747    SetPlaying(false);
    27312748    killdecoder = true;
    27322749    int tries = 0;
    2733     while (decoderThread && !decoderThread->wait(100) && (tries++ < 50))
     2750    while (decoderThread && !decoderThread->wait(100) && (tries++ < 2))
    27342751        VERBOSE(VB_PLAYBACK, LOC + "Waited 100ms for decoder loop to stop");
    27352752
    27362753    if (decoderThread && decoderThread->isRunning())
    void MythPlayer::DecoderEnd(void) 
    27412758
    27422759void MythPlayer::DecoderPauseCheck(void)
    27432760{
    2744     if (QThread::currentThread() != (QThread*)decoderThread)
     2761    if (QThread::currentThread() != static_cast<QThread*>(decoderThread))
    27452762        return;
     2763
     2764    QMutexLocker locker(&decoderPauseLock);
     2765
    27462766    if (pauseDecoder)
    2747         PauseDecoder();
     2767    {
     2768        pauseDecoder = false;
     2769        decoderPaused = true;
     2770        VERBOSE(VB_PLAYBACK+VB_EXTRA, LOC + "Decoder paused.");
     2771        decoderThreadPause.wakeAll();
     2772    }
     2773
    27482774    if (unpauseDecoder)
    2749         UnpauseDecoder();
     2775    {
     2776        unpauseDecoder = false;
     2777        decoderPaused = false;
     2778        VERBOSE(VB_PLAYBACK+VB_EXTRA, LOC + "Decoder unpaused.");
     2779        decoderThreadUnpause.wakeAll();
     2780    }
    27502781}
    27512782
    27522783//// FIXME - move the eof ownership back into MythPlayer
    27532784bool MythPlayer::GetEof(void)
    27542785{
    2755     if (QThread::currentThread() == (QThread*)playerThread)
     2786    if (QThread::currentThread() == playerThread)
    27562787        return decoder ? decoder->GetEof() : true;
    27572788
    2758     decoder_change_lock.lock();
     2789    // This must be a tryLock for the case of an audio only stream
     2790    // when the decoder thread never exits decoder->GetFrame
     2791    if (!decoder_change_lock.tryLock(10))
     2792        return false;
    27592793    bool eof = decoder ? decoder->GetEof() : true;
    27602794    decoder_change_lock.unlock();
    27612795    return eof;
    bool MythPlayer::GetEof(void) 
    27632797
    27642798void MythPlayer::SetEof(bool eof)
    27652799{
    2766     if (QThread::currentThread() == (QThread*)playerThread)
     2800    if (QThread::currentThread() == playerThread)
    27672801    {
    27682802        if (decoder)
    27692803            decoder->SetEof(eof);
    27702804        return;
    27712805    }
    27722806
    2773     decoder_change_lock.lock();
     2807    // This must be a tryLock for the case of an audio only stream
     2808    // when the decoder thread never exits decoder->GetFrame
     2809    if (!decoder_change_lock.tryLock(10))
     2810        return;
    27742811    if (decoder)
    27752812        decoder->SetEof(eof);
    27762813    decoder_change_lock.unlock();
  • mythtv/libs/libmythtv/mythplayer.h

    diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h
    index 5aba7de..57213c8 100644
    a b class MPUBLIC MythPlayer 
    537537    bool           decoderPaused;
    538538    bool           pauseDecoder;
    539539    bool           unpauseDecoder;
    540     bool           killdecoder;
     540    bool volatile  killdecoder;
    541541    int64_t        decoderSeek;
    542542    bool           decodeOneFrame;
    543543    bool           needNewPauseFrame;
  • mythtv/libs/libmythtv/tv_play.cpp

    diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp
    index e8d0c2d..004db3e 100644
    a b void TV::ChangeChannel(PlayerContext *ctx, uint chanid, const QString &chan) 
    68946894    if (ctx->prevChan.empty())
    68956895        ctx->PushPreviousChannel();
    68966896
    6897     PauseAudioUntilBuffered(ctx);
     6897    if (ctx->player)
     6898        ctx->player->GetAudio()->Pause(true);
    68986899    PauseLiveTV(ctx);
    68996900
    69006901    ctx->LockDeletePlayer(__FILE__, __LINE__);
    void TV::ChangeChannel(PlayerContext *ctx, uint chanid, const QString &chan) 
    69116912        ctx->player->GetAudio()->Reset();
    69126913
    69136914    UnpauseLiveTV(ctx);
     6915    PauseAudioUntilBuffered(ctx);
    69146916
    69156917    if (oldinputname != ctx->recorder->GetInput())
    69166918        UpdateOSDInput(ctx);