Ticket #11579: 0004-Handle-seeking-within-slideshows.patch

File 0004-Handle-seeking-within-slideshows.patch, 21.5 KB (added by peper03@…, 8 years ago)
  • mythtv/libs/libmythdvdnav/dvdnav/searching.c

    From efbc2941ed4ccc6f033c93426628ec2d2c6a0b35 Mon Sep 17 00:00:00 2001
    From: Richard <peper03@yahoo.com>
    Date: Sat, 8 Jun 2013 23:37:48 +0200
    Subject: [PATCH 4/4] Handle seeking within slideshows.
    
    As slideshows only contain a single video frame to be displayed for an arbitary amount of time along with audio, seeking can cause issues as you may jump over the frame to be displayed.
    
    Using an audio DVD of classical music as an example:
    
    1. Each movement contains a single video frame at the beginning.
    2. The second movement has just begun and the user skips back several seconds to the end of the first movement.
    3. This change detects that a different video frame should be displayed and jumps back further to retrieve the video frame and, once retrieved, returns to the original position to continue playback.
    ---
     mythtv/libs/libmythdvdnav/dvdnav/searching.c     |    4 +-
     mythtv/libs/libmythtv/DVD/avformatdecoderdvd.cpp |  234 ++++++++++++++++------
     mythtv/libs/libmythtv/DVD/avformatdecoderdvd.h   |    5 +
     mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp      |   62 +++++-
     mythtv/libs/libmythtv/DVD/dvdringbuffer.h        |   23 ++-
     mythtv/libs/libmythtv/avformatdecoder.h          |    2 +-
     6 files changed, 261 insertions(+), 69 deletions(-)
    
    diff --git a/mythtv/libs/libmythdvdnav/dvdnav/searching.c b/mythtv/libs/libmythdvdnav/dvdnav/searching.c
    index beb2b37..8a6f403 100644
    a b dvdnav_status_t dvdnav_relative_time_search(dvdnav_t *this, 
    696696      for (i = 0; i < 19; i++) {
    697697        if (stime[i]/2.0 <= length/2.0) {
    698698          offset = dsi->vobu_sri.fwda[i];
    699           if (offset >> 31) {
     699          if (offset != 0x3fffffff) {
    700700            new_vobu = cur_vobu + (offset & 0xffff);
    701701          } else {
    702702            if (cell_nr == last_cell_nr) {
    dvdnav_status_t dvdnav_relative_time_search(dvdnav_t *this, 
    715715        if (stime[18 - i]/2.0 >= abs(length)/2.0)
    716716        {
    717717          offset = dsi->vobu_sri.bwda[i];
    718           if (offset >> 31) {
     718          if (offset != 0x3fffffff) {
    719719            new_vobu = cur_vobu - (offset & 0xffff);
    720720          } else {
    721721            if (cell_nr == first_cell_nr) {
  • mythtv/libs/libmythtv/DVD/avformatdecoderdvd.cpp

    diff --git a/mythtv/libs/libmythtv/DVD/avformatdecoderdvd.cpp b/mythtv/libs/libmythtv/DVD/avformatdecoderdvd.cpp
    index f4a63c0..d038cfc 100644
    a b extern "C" { 
    77}
    88
    99#define LOC QString("AFD_DVD: ")
     10#define INVALID_LBA 0xbfffffff
    1011
    1112AvFormatDecoderDVD::AvFormatDecoderDVD(
    1213    MythPlayer *parent, const ProgramInfo &pginfo, PlayerFlags flags)
    1314  : AvFormatDecoder(parent, pginfo, flags)
    1415  , m_curContext(NULL)
    1516  , m_lastVideoPkt(NULL)
     17  , m_lbaLastVideoPkt(INVALID_LBA)
    1618  , m_framesReq(0)
     19  , m_returnContext(NULL)
    1720{
    1821}
    1922
    2023AvFormatDecoderDVD::~AvFormatDecoderDVD()
    2124{
    22     if (m_curContext)
    23         m_curContext->DecrRef();
     25    ReleaseContext(m_curContext);
     26    ReleaseContext(m_returnContext);
    2427
    2528    while (m_contextList.size() > 0)
    2629        m_contextList.takeFirst()->DecrRef();
    2730
     31    ReleaseLastVideoPkt();
     32}
     33
     34void AvFormatDecoderDVD::ReleaseLastVideoPkt()
     35{
    2836    if (m_lastVideoPkt)
    2937    {
    3038        av_free_packet(m_lastVideoPkt);
    3139        delete m_lastVideoPkt;
     40        m_lastVideoPkt = NULL;
     41        m_lbaLastVideoPkt = INVALID_LBA;
     42    }
     43}
     44
     45void AvFormatDecoderDVD::ReleaseContext(MythDVDContext *&context)
     46{
     47    if (context)
     48    {
     49        context->DecrRef();
     50        context = NULL;
    3251    }
    3352}
    3453
    int AvFormatDecoderDVD::ReadPacket(AVFormatContext *ctx, AVPacket* pkt) 
    6180    if (m_framesReq > 0)
    6281    {
    6382        m_framesReq--;
    64         av_copy_packet(pkt, m_lastVideoPkt);
    6583
    66         if (m_lastVideoPkt->pts != AV_NOPTS_VALUE)
    67             m_lastVideoPkt->pts += pkt->duration;
     84        if (m_lastVideoPkt)
     85        {
     86            av_copy_packet(pkt, m_lastVideoPkt);
     87
     88            if (m_lastVideoPkt->pts != AV_NOPTS_VALUE)
     89                m_lastVideoPkt->pts += pkt->duration;
    6890
    69         if (m_lastVideoPkt->dts != AV_NOPTS_VALUE)
    70             m_lastVideoPkt->dts += pkt->duration;
     91            if (m_lastVideoPkt->dts != AV_NOPTS_VALUE)
     92                m_lastVideoPkt->dts += pkt->duration;
     93        }
     94        else
     95        {
     96            LOG(VB_GENERAL, LOG_ERR, LOC + QString( "Need to generate frame @ %1 - %2 but no frame available!")
     97                .arg(pkt->pts)
     98                .arg(m_framesReq));
     99        }
    71100    }
    72101    else
    73102    {
    74         result = av_read_frame(ctx, pkt);
     103        bool gotPacket;
    75104
    76         while (result == AVERROR_EOF && errno == EAGAIN)
     105        do
    77106        {
    78             if (ringBuffer->DVD()->IsReadingBlocked())
     107            gotPacket = true;
     108
     109            result = av_read_frame(ctx, pkt);
     110
     111            while (result == AVERROR_EOF && errno == EAGAIN)
    79112            {
    80                 ringBuffer->DVD()->UnblockReading();
    81                 result = av_read_frame(ctx, pkt);
     113                if (ringBuffer->DVD()->IsReadingBlocked())
     114                {
     115                    if (ringBuffer->DVD()->GetLastEvent() == DVDNAV_HOP_CHANNEL)
     116                    {
     117                        // Non-seamless jump - clear all buffers
     118                        m_framesReq = 0;
     119                        ReleaseContext(m_curContext);
     120
     121                        while (m_contextList.size() > 0)
     122                            m_contextList.takeFirst()->DecrRef();
     123
     124                        Reset(true, false, false);
     125                        m_audio->Reset();
     126                        m_parent->DiscardVideoFrames(false);
     127                    }
     128                    ringBuffer->DVD()->UnblockReading();
     129                    result = av_read_frame(ctx, pkt);
     130                }
     131                else
     132                {
     133                    break;
     134                }
    82135            }
    83             else
     136
     137            if (result >= 0)
    84138            {
    85                 break;
    86             }
    87         }
     139                pkt->dts = ringBuffer->DVD()->AdjustTimestamp(pkt->dts);
     140                pkt->pts = ringBuffer->DVD()->AdjustTimestamp(pkt->pts);
    88141
    89         if (result >= 0)
    90         {
    91             pkt->dts = ringBuffer->DVD()->AdjustTimestamp(pkt->dts);
    92             pkt->pts = ringBuffer->DVD()->AdjustTimestamp(pkt->pts);
    93         }
     142                if (m_returnContext)
     143                {
     144                    // We've jumped in a slideshow and have had to jump again
     145                    // to find the right video packet to show so only allow
     146                    // the packets through that let us find it.
     147                    gotPacket = false;
    94148
    95         AVStream *curstream = ic->streams[pkt->stream_index];
    96         if(curstream->codec->codec_type == AVMEDIA_TYPE_DATA)
    97         {
    98             LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString( "Read DVD context @ %1 - curcontext %2 lastVideo %3 reqFrames %4")
    99                 .arg(pkt->pts)
    100                 .arg((uint64_t)m_curContext, 0, 16)
    101                 .arg((uint64_t)m_lastVideoPkt, 0, 16)
    102                 .arg(m_framesReq));
    103         }
     149                    AVStream *curstream = ic->streams[pkt->stream_index];
     150
     151                    if ((curstream->codec->codec_type == AVMEDIA_TYPE_VIDEO) ||
     152                        (curstream->codec->codec_id == AV_CODEC_ID_DVD_NAV))
     153                    {
     154                        // Allow video or NAV packets through
     155                        gotPacket = true;
     156                    }
     157                }
     158            }
     159        }while(!gotPacket);
    104160    }
    105161
    106162    return result;
    void AvFormatDecoderDVD::CheckContext(int64_t pts) 
    110166{
    111167    if (pts != AV_NOPTS_VALUE)
    112168    {
     169        // Remove any contexts we should have
     170        // already processed.(but have somehow jumped past)
    113171        while (m_contextList.size() > 0 &&
    114172               pts >= m_contextList.first()->GetEndPTS())
    115173        {
    116             if (m_curContext)
    117                 m_curContext->DecrRef();
    118 
     174            ReleaseContext(m_curContext);
    119175            m_curContext = m_contextList.takeFirst();
    120176
    121177            LOG(VB_GENERAL, LOG_ERR, LOC +
    void AvFormatDecoderDVD::CheckContext(int64_t pts) 
    125181                .arg(m_curContext->GetEndPTS()));
    126182        }
    127183
     184        // See whether we can take the next context from the list
    128185        if (m_contextList.size() > 0 &&
    129186            pts >= m_contextList.first()->GetStartPTS())
    130187        {
    131             if (m_curContext)
    132                 m_curContext->DecrRef();
    133 
     188            ReleaseContext(m_curContext);
    134189            m_curContext = m_contextList.takeFirst();
    135190
    136             LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString( "New DVD context @ %1 - %2")
    137                 .arg(pts)
    138                 .arg(m_curContext->GetNumFramesPresent()));
     191            if (m_curContext->GetLBAPrevVideoFrame() != m_lbaLastVideoPkt)
     192                ReleaseLastVideoPkt();
    139193
    140194            if (m_curContext->GetNumFramesPresent() == 0)
    141195            {
    142                 // No video frames present, so we need to generate
    143                 // them based on the last 'sequence end' video packet.
    144                 m_framesReq = m_curContext->GetNumFrames();
     196                if (m_lastVideoPkt)
     197                {
     198                    // No video frames present, so we need to generate
     199                    // them based on the last 'sequence end' video packet.
     200                    m_framesReq = m_curContext->GetNumFrames();
     201                }
     202                else
     203                {
     204                    // There are no video frames in this VOBU and
     205                    // we don't have one stored.  We've probably
     206                    // jumped into the middle of a cell.
     207                    // Jump back to the first VOBU that contains
     208                    // video so we can get the video frame we need
     209                    // before jumping back again.
     210                    m_framesReq = 0;
     211                    uint32_t lastVideoSector = m_curContext->GetLBAPrevVideoFrame();
     212
     213                    if (lastVideoSector != INVALID_LBA)
     214                    {
     215                        LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString( "Missing video.  Jumping to sector %1")
     216                            .arg(lastVideoSector));
     217
     218                        ringBuffer->DVD()->SectorSeek(lastVideoSector);
     219
     220                        m_returnContext = m_curContext;
     221                        m_curContext = NULL;
     222                    }
     223                    else
     224                    {
     225                        LOG(VB_GENERAL, LOG_ERR, LOC +
     226                            QString("Missing video frame and no previous frame available! lba: %1")
     227                            .arg(m_curContext->GetLBA()));
     228                    }
     229                }
    145230            }
    146231            else
    147232            {
     233                // Normal VOBU with at least one video frame so we don't need to generate frames.
    148234                m_framesReq = 0;
    149                 if (m_lastVideoPkt)
    150                 {
    151                     av_free_packet(m_lastVideoPkt);
    152                     delete m_lastVideoPkt;
    153                     m_lastVideoPkt = NULL;
    154                 }
     235                ReleaseLastVideoPkt();
    155236            }
    156237        }
    157238    }
    bool AvFormatDecoderDVD::ProcessVideoPacket(AVStream *stream, AVPacket *pkt) 
    190271
    191272        av_init_packet(m_lastVideoPkt);
    192273        av_copy_packet(m_lastVideoPkt, pkt);
     274        m_lbaLastVideoPkt = m_curContext->GetLBA();
     275
     276        if (m_returnContext)
     277        {
     278            // After seeking in a slideshow, we needed to find
     279            // the previous video frame to display.
     280                // We've found it now, so we need to jump back to
     281                // where we originally wanted to be.
     282            LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString( "Found video packet, jumping back to sector %1")
     283                .arg(m_returnContext->GetLBA()));
     284
     285            ringBuffer->DVD()->SectorSeek(m_returnContext->GetLBA());
     286            ReleaseContext(m_returnContext);
     287        }
     288        else
     289        {
     290            if (m_lastVideoPkt->pts != AV_NOPTS_VALUE)
     291                m_lastVideoPkt->pts += pkt->duration;
     292
     293            if (m_lastVideoPkt->dts != AV_NOPTS_VALUE)
     294                m_lastVideoPkt->dts += pkt->duration;
     295
     296            m_framesReq = m_curContext->GetNumFrames() - m_curContext->GetNumFramesPresent();
    193297
    194         if (m_lastVideoPkt->pts != AV_NOPTS_VALUE)
    195             m_lastVideoPkt->pts += pkt->duration;
     298            LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString( "SeqEnd @ %1 - require %2 frame(s)")
     299                .arg(pkt->pts)
     300                .arg(m_framesReq));
     301        }
     302    }
    196303
    197         if (m_lastVideoPkt->dts != AV_NOPTS_VALUE)
    198             m_lastVideoPkt->dts += pkt->duration;
     304    return ret;
     305}
    199306
    200         m_framesReq = m_curContext->GetNumFrames() - m_curContext->GetNumFramesPresent();
     307bool AvFormatDecoderDVD::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
     308{
     309    bool ret = true;
    201310
    202         LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString( "SeqEnd @ %1 - require %2 frame(s)")
    203             .arg(pkt->pts)
    204             .arg(m_framesReq));
     311    if (m_returnContext == NULL)
     312    {
     313        // Only process video frames if we're not searching for
     314        // the previous video frame after seeking in a slideshow.
     315        ret = AvFormatDecoder::ProcessVideoFrame(stream, mpa_pic);
    205316    }
    206317
    207318    return ret;
    bool AvFormatDecoderDVD::ProcessDataPacket(AVStream *curstream, AVPacket *pkt, 
    224335            // If we don't have a current context, use
    225336            // the first in the list
    226337            CheckContext(m_contextList.first()->GetStartPTS());
     338
     339            if (m_lastVideoPkt && m_curContext)
     340            {
     341                // If there was no current context but there was
     342                // a video packet, we've almost certainly been
     343                // seeking so set the timestamps of the video
     344                // packet to the new context to ensure we don't
     345                // get sync errors.
     346                m_lastVideoPkt->pts = m_curContext->GetStartPTS();
     347                m_lastVideoPkt->dts = m_lastVideoPkt->pts;
     348            }
    227349        }
    228350        else
    229351        if (m_lastVideoPkt)
  • mythtv/libs/libmythtv/DVD/avformatdecoderdvd.h

    diff --git a/mythtv/libs/libmythtv/DVD/avformatdecoderdvd.h b/mythtv/libs/libmythtv/DVD/avformatdecoderdvd.h
    index 00de975..3d8b548 100644
    a b class AvFormatDecoderDVD : public AvFormatDecoder 
    1919  protected:
    2020    virtual int  ReadPacket(AVFormatContext *ctx, AVPacket *pkt);
    2121    virtual bool ProcessVideoPacket(AVStream *stream, AVPacket *pkt);
     22    virtual bool ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic);
    2223    virtual bool ProcessDataPacket(AVStream *curstream, AVPacket *pkt,
    2324                                   DecodeType decodetype);
    2425
    class AvFormatDecoderDVD : public AvFormatDecoder 
    3132    virtual AudioTrackType GetAudioTrackType(uint stream_index);
    3233
    3334    void CheckContext(int64_t pts);
     35    void ReleaseLastVideoPkt();
     36    void ReleaseContext(MythDVDContext *&context);
    3437
    3538    long long DVDFindPosition(long long desiredFrame);
    3639
    3740    MythDVDContext*        m_curContext;
    3841    QList<MythDVDContext*> m_contextList;
    3942    AVPacket*              m_lastVideoPkt;
     43    uint32_t               m_lbaLastVideoPkt;
    4044    int                    m_framesReq;
     45    MythDVDContext*        m_returnContext;
    4146};
    4247
    4348#endif // AVFORMATDECODERDVD_H
  • mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp b/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
    index 2bf1088..cb854d7 100644
    a b MythDVDContext::~MythDVDContext() 
    8787{
    8888}
    8989
     90/** \brief Returns the duration of this VOBU in frames
     91 *  \sa GetNumFramesPresent
     92 */
    9093int MythDVDContext::GetNumFrames() const
    9194{
    9295    return ((GetEndPTS() - GetStartPTS()) * GetFPS()) / 90000;
    9396}
    9497
     98/** \brief Returns the number of video frames present in this VOBU
     99 *  \sa GetNumFrames
     100 */
    95101int MythDVDContext::GetNumFramesPresent() const
    96102{
    97103    int frames = 0;
    int MythDVDContext::GetNumFramesPresent() const 
    112118    return frames;
    113119}
    114120
     121/** \brief Returns the logical block address of the previous
     122 * VOBU containing video.
     123 * \return LBA or 0xbfffffff if no previous VOBU with video exists
     124 */
     125uint32_t MythDVDContext::GetLBAPrevVideoFrame() const
     126{
     127    uint32_t lba = m_dsi.vobu_sri.prev_video;
     128
     129    if (lba != 0xbfffffff)
     130    {
     131        // If there is a previous video frame in this
     132        // cell, calculate the absolute LBA from the
     133        // offset
     134        lba = GetLBA() - (lba & 0x7ffffff);
     135    }
     136
     137    return lba;
     138}
     139
    115140DVDRingBuffer::DVDRingBuffer(const QString &lfilename) :
    116141    RingBuffer(kRingBuffer_DVD),
    117142    m_dvdnav(NULL),     m_dvdBlockReadBuf(NULL),
    long long DVDRingBuffer::NormalSeek(long long time) 
    295320    return Seek(time);
    296321}
    297322
     323bool DVDRingBuffer::SectorSeek(uint64_t sector)
     324{
     325    dvdnav_status_t dvdRet = DVDNAV_STATUS_OK;
     326
     327    QMutexLocker lock(&m_seekLock);
     328
     329    dvdRet = dvdnav_sector_search(m_dvdnav, sector, SEEK_SET);
     330
     331    if (dvdRet == DVDNAV_STATUS_ERR)
     332    {
     333        LOG(VB_PLAYBACK, LOG_ERR, LOC +
     334            QString("SectorSeek() to sector %1 failed").arg(sector));
     335        return false;
     336    }
     337    else
     338    {
     339        LOG(VB_PLAYBACK, LOG_DEBUG, LOC +
     340            QString("DVD Playback SectorSeek() sector: %1").arg(sector));
     341        return true;
     342    }
     343}
     344
    298345long long DVDRingBuffer::Seek(long long time)
    299346{
    300347    dvdnav_status_t dvdRet = DVDNAV_STATUS_OK;
    int DVDRingBuffer::safe_read(void *data, uint sz) 
    939986
    940987            case DVDNAV_HOP_CHANNEL:
    941988            {
    942                 // debug
    943                 LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "DVDNAV_HOP_CHANNEL");
    944                 WaitForPlayer();
     989                if (!bReprocessing && !m_skipstillorwait)
     990                {
     991                    LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "DVDNAV_HOP_CHANNEL - waiting");
     992                    m_processState = PROCESS_WAIT;
     993                    break;
     994                }
     995                else
     996                {
     997                    // debug
     998                    LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "DVDNAV_HOP_CHANNEL");
     999                    WaitForPlayer();
     1000                }
    9451001            }
    9461002            break;
    9471003
  • mythtv/libs/libmythtv/DVD/dvdringbuffer.h

    diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.h b/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
    index 42e1cfc..c5e4d36 100644
    a b extern "C" { 
    2020
    2121#include "dvdnav/dvdnav.h"
    2222
     23/** \class MythDVDContext
     24 *  \brief Encapsulates playback context at any given moment.
     25 *
     26 * This class is mainly represents a single VOBU (video object unit)
     27 * on a DVD
     28 */
    2329class MTV_PUBLIC MythDVDContext : public ReferenceCounter
    2430{
    2531    friend class DVDRingBuffer;
    class MTV_PUBLIC MythDVDContext : public ReferenceCounter 
    2733  public:
    2834    virtual ~MythDVDContext();
    2935
    30     int64_t  GetStartPTS()         const { return (int64_t)m_pci.pci_gi.vobu_s_ptm;    }
    31     int64_t  GetEndPTS()           const { return (int64_t)m_pci.pci_gi.vobu_e_ptm;    }
    32     int64_t  GetSeqEndPTS()        const { return (int64_t)m_pci.pci_gi.vobu_se_e_ptm; }
    33     uint32_t GetLBA()              const { return m_pci.pci_gi.nv_pck_lbn;             }
    34     int      GetNumFrames()        const;
    35     int      GetNumFramesPresent() const;
    36     int      GetFPS()              const { return (m_pci.pci_gi.e_eltm.frame_u & 0x80) ? 30 : 25; }
     36    int64_t  GetStartPTS()          const { return (int64_t)m_pci.pci_gi.vobu_s_ptm;    }
     37    int64_t  GetEndPTS()            const { return (int64_t)m_pci.pci_gi.vobu_e_ptm;    }
     38    int64_t  GetSeqEndPTS()         const { return (int64_t)m_pci.pci_gi.vobu_se_e_ptm; }
     39    uint32_t GetLBA()               const { return m_pci.pci_gi.nv_pck_lbn;             }
     40    uint32_t GetLBAPrevVideoFrame() const;
     41    int      GetNumFrames()         const;
     42    int      GetNumFramesPresent()  const;
     43    int      GetFPS()               const { return (m_pci.pci_gi.e_eltm.frame_u & 0x80) ? 30 : 25; }
    3744
    3845  protected:
    3946    MythDVDContext();
    class MTV_PUBLIC DVDRingBuffer : public RingBuffer 
    104111    uint32_t AdjustTimestamp(uint32_t timestamp);
    105112    int64_t AdjustTimestamp(int64_t timestamp);
    106113    MythDVDContext* GetDVDContext(void);
     114    int32_t GetLastEvent(void) const     { return m_dvdEvent; }
    107115
    108116    // Public menu/button stuff
    109117    AVSubtitle *GetMenuSubtitle(uint &version);
    class MTV_PUBLIC DVDRingBuffer : public RingBuffer 
    143151    virtual int safe_read(void *data, uint sz);
    144152    virtual long long Seek(long long pos, int whence, bool has_lock);
    145153    long long NormalSeek(long long time);
     154    bool SectorSeek(uint64_t sector);
    146155    void SkipStillFrame(void);
    147156    void WaitSkip(void);
    148157    void SkipDVDWaitingForPlayer(void)    { m_playerWait = false;           }
  • mythtv/libs/libmythtv/avformatdecoder.h

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
    index 52cc8e9..04556c5 100644
    a b class AvFormatDecoder : public DecoderBase 
    223223    int  H264PreProcessPkt(AVStream *stream, AVPacket *pkt);
    224224    bool PreProcessVideoPacket(AVStream *stream, AVPacket *pkt);
    225225    virtual bool ProcessVideoPacket(AVStream *stream, AVPacket *pkt);
    226     bool ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic);
     226    virtual bool ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic);
    227227    bool ProcessAudioPacket(AVStream *stream, AVPacket *pkt,
    228228                            DecodeType decodetype);
    229229    bool ProcessSubtitlePacket(AVStream *stream, AVPacket *pkt);