Ticket #9429: 0001-Filter-and-sort-DVD-subtitle-tracks-so-that-only-the.patch

File 0001-Filter-and-sort-DVD-subtitle-tracks-so-that-only-the.patch, 9.8 KB (added by peper03@…, 7 years ago)
  • mythtv/libs/libmythtv/DVD/avformatdecoderdvd.cpp

    From 928733bfca6416f09a84f2ec15330fdfe1945e76 Mon Sep 17 00:00:00 2001
    From: Richard <peper03@yahoo.com>
    Date: Fri, 31 May 2013 21:56:27 +0200
    Subject: [PATCH 2/2] Filter and sort DVD subtitle tracks so that only the
     tracks mapped into the current program chain are shown.
     This patch also adds the subtitle streams that are
     mapped but have not yet been physically read.  This
     allows the user to select the language without having
     to wait for the first subtitle packet (and therefore
     miss it).
    
    ---
     mythtv/libs/libmythtv/DVD/avformatdecoderdvd.cpp |   87 +++++++++++++++++++---
     mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp      |    8 ++
     mythtv/libs/libmythtv/DVD/dvdringbuffer.h        |    1 +
     mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp      |   13 +++-
     mythtv/libs/libmythtv/avformatdecoder.cpp        |    3 -
     mythtv/libs/libmythtv/decoderbase.cpp            |   10 ++-
     6 files changed, 104 insertions(+), 18 deletions(-)
    
    diff --git a/mythtv/libs/libmythtv/DVD/avformatdecoderdvd.cpp b/mythtv/libs/libmythtv/DVD/avformatdecoderdvd.cpp
    index 1abf566..04777d2 100644
    a b void AvFormatDecoderDVD::PostProcessTracks(void) 
    118118
    119119    if (tracks[kTrackTypeSubtitle].size() > 0)
    120120    {
     121        map<int,uint> lang_sub_cnt;
     122        map<int,int>  stream2idx;
     123
     124        // First, create a map containing stream id -> track index
     125        // of the subtitle streams that have been found so far.
     126        for (uint n = 0; n < GetTrackCount(kTrackTypeSubtitle); n++)
     127        {
     128            int stream_id = tracks[kTrackTypeSubtitle][n].stream_id & 0x1f;
     129
     130            stream2idx[stream_id] = n;
     131        }
     132
     133        // Get all subtitle tracks from the DVD and filter out any that
     134        // are not mapped in the current program chain.
     135        sinfo_vec_t filteredTracks;
     136
     137        if (!ringBuffer->DVD()->IsInMenu())
     138        {
     139            for (uint i = 0; i < 32; ++i)
     140            {
     141                int streamid = ringBuffer->DVD()->GetSubtitleTrackNum(i);
     142                if (streamid >= 0)
     143                {
     144                    // This stream is mapped in the current program chain
     145                    int lang = ringBuffer->DVD()->GetSubtitleLanguage(i);
     146                    int lang_indx = lang_sub_cnt[lang]++;
     147                    int trackNo = -1;
     148
     149                    if (stream2idx.count(streamid) != 0)
     150                        trackNo = stream2idx[streamid];
     151
     152                    if (trackNo == -1)
     153                    {
     154                        // Create a dummy track if the physical stream has not
     155                        // yet been seen.
     156                        filteredTracks.push_back(StreamInfo(-1, lang, lang_indx,
     157                                                            streamid, 0, 0, false, false, false));
     158                    }
     159                    else
     160                    {
     161                        // Otherwise use the real data
     162                        filteredTracks.push_back(tracks[kTrackTypeSubtitle][trackNo]);
     163                        filteredTracks.back().stream_id &= 0x1f;
     164                        filteredTracks.back().language = lang;
     165                        filteredTracks.back().language_index = lang_indx;
     166                    }
     167                }
     168            }
     169        }
     170        tracks[kTrackTypeSubtitle] = filteredTracks;
     171
    121172        stable_sort(tracks[kTrackTypeSubtitle].begin(),
    122173                    tracks[kTrackTypeSubtitle].end());
    123         sinfo_vec_t::iterator it = tracks[kTrackTypeSubtitle].begin();
    124         for(; it != tracks[kTrackTypeSubtitle].end(); ++it)
     174
     175        int trackNo = -1;
     176        int selectedStream = ringBuffer->DVD()->GetTrack(kTrackTypeSubtitle);
     177
     178        // Now iterate over the sorted list and try to find the index of the
     179        // currently selected track.
     180        for (uint idx = 0; idx < GetTrackCount(kTrackTypeSubtitle); idx++)
    125181        {
     182            const StreamInfo& stream = tracks[kTrackTypeSubtitle][idx];
     183            int avidx = stream.av_stream_index;
     184            QString mpegstream;
     185
     186            if (avidx >= 0)
     187                mpegstream = QString( "0x%1").arg(ic->streams[avidx]->id,0,16);
     188            else
     189                mpegstream = "n/a";
     190
    126191            LOG(VB_PLAYBACK, LOG_INFO, LOC +
    127                 QString("DVD Subtitle Track Map Stream id #%1 ")
    128                     .arg(it->stream_id));
     192                QString("DVD Subtitle Track Map Stream id #%1, av_stream_idx %2, MPEG #%3, lang %4")
     193                    .arg(stream.stream_id)
     194                    .arg(stream.av_stream_index)
     195                    .arg(mpegstream)
     196                    .arg(iso639_key_toName(stream.language)));
     197
     198            if ((selectedStream != -1) && (stream.stream_id == selectedStream))
     199                trackNo = (int)idx;
    129200        }
    130         stable_sort(tracks[kTrackTypeSubtitle].begin(),
    131                     tracks[kTrackTypeSubtitle].end());
    132         int trackNo = ringBuffer->DVD()->GetTrack(kTrackTypeSubtitle);
     201
    133202        uint captionmode = m_parent->GetCaptionMode();
    134203        int trackcount = (int)GetTrackCount(kTrackTypeSubtitle);
     204
    135205        if (captionmode == kDisplayAVSubtitle &&
    136206            (trackNo < 0 || trackNo >= trackcount))
    137207        {
    138208            m_parent->EnableSubtitles(false);
    139209        }
    140         else if (trackNo >= 0 && trackNo < trackcount &&
    141                  !ringBuffer->IsInDiscMenuOrStillFrame())
     210        else if (trackNo >= 0 && trackNo < trackcount)
    142211        {
    143212            SetTrack(kTrackTypeSubtitle, trackNo);
    144213            m_parent->EnableSubtitles(true);
  • mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp b/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
    index 361e883..5ca2bee 100644
    a b uint DVDRingBuffer::GetSubtitleLanguage(int id) 
    16641664    return ConvertLangCode(lang);
    16651665}
    16661666
     1667/** \brief get the logical subtitle track/stream number from the dvd
     1668 * \param stream_id the stream id, range 0-31
     1669 */
     1670int DVDRingBuffer::GetSubtitleTrackNum(uint stream_id)
     1671{
     1672    return dvdnav_get_spu_logical_stream(m_dvdnav, stream_id);
     1673}
     1674
    16671675/** \brief converts the subtitle/audio lang code to iso639.
    16681676 */
    16691677uint DVDRingBuffer::ConvertLangCode(uint16_t code)
  • mythtv/libs/libmythtv/DVD/dvdringbuffer.h

    diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.h b/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
    index 05809b7..33c83c4 100644
    a b class MTV_PUBLIC DVDRingBuffer : public RingBuffer 
    9090
    9191    // Subtitles
    9292    uint GetSubtitleLanguage(int key);
     93    int GetSubtitleTrackNum(uint stream_id);
    9394    bool DecodeSubtitles(AVSubtitle * sub, int * gotSubtitles,
    9495                         const uint8_t * buf, int buf_size, uint32_t startTime);
    9596
  • mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp

    diff --git a/mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp b/mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp
    index 2bfbd11..9612b78 100644
    a b void MythDVDPlayer::DisableCaptions(uint mode, bool osd_msg) 
    5050void MythDVDPlayer::EnableCaptions(uint mode, bool osd_msg)
    5151{
    5252    if ((kDisplayAVSubtitle & mode) && player_ctx->buffer->IsDVD())
    53         player_ctx->buffer->DVD()->SetTrack(kTrackTypeSubtitle,
    54                                             GetTrack(kTrackTypeSubtitle));
     53    {
     54        int track = GetTrack(kTrackTypeSubtitle);
     55        if (track >= 0 && track < (int)decoder->GetTrackCount(kTrackTypeSubtitle))
     56        {
     57            StreamInfo stream = decoder->GetTrackInfo(kTrackTypeSubtitle,
     58                                                      track);
     59            player_ctx->buffer->DVD()->SetTrack(kTrackTypeSubtitle,
     60                                                stream.stream_id);
     61        }
     62    }
    5563    MythPlayer::EnableCaptions(mode, osd_msg);
    5664}
    5765
    void MythDVDPlayer::DisplayDVDButton(void) 
    549557    // clear any buttons
    550558    if (!numbuttons || !dvdSubtitle || (buttonversion == 0) || expired)
    551559    {
    552         SetCaptionsEnabled(false, false);
    553560        osdLock.lock();
    554561        if (osd)
    555562            osd->ClearSubtitles();
  • mythtv/libs/libmythtv/avformatdecoder.cpp

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
    index 2d71ec9..0b410f1 100644
    a b QString AvFormatDecoder::GetTrackDesc(uint type, uint trackNo) const 
    38773877    }
    38783878    else if (kTrackTypeSubtitle == type)
    38793879    {
    3880         if (ringBuffer->IsDVD())
    3881             lang_key = ringBuffer->DVD()->GetSubtitleLanguage(trackNo);
    3882 
    38833880        return QObject::tr("Subtitle") + QString(" %1: %2%3")
    38843881            .arg(trackNo + 1).arg(iso639_key_toName(lang_key))
    38853882            .arg(forcedString);
  • mythtv/libs/libmythtv/decoderbase.cpp

    diff --git a/mythtv/libs/libmythtv/decoderbase.cpp b/mythtv/libs/libmythtv/decoderbase.cpp
    index f181d2f..00f436d 100644
    a b int DecoderBase::AutoSelectTrack(uint type) 
    10521052        for (uint i = 0; i < numStreams; i++)
    10531053        {
    10541054            if (wlang == tracks[type][i].language)
     1055            {
    10551056                selTrack = i;
    1056             if (windx == tracks[type][i].language_index)
    1057                 break;
     1057
     1058                if (windx == tracks[type][i].language_index)
     1059                    break;
     1060            }
    10581061        }
    10591062    }
    10601063
    int DecoderBase::AutoSelectTrack(uint type) 
    11061109
    11071110    int lang = tracks[type][currentTrack[type]].language;
    11081111    LOG(VB_PLAYBACK, LOG_INFO, LOC +
    1109         QString("Selected track #%1 in the %2 language(%3)")
     1112        QString("Selected track #%1 (type %2) in the %3 language(%4)")
    11101113            .arg(currentTrack[type]+1)
     1114            .arg(type)
    11111115            .arg(iso639_key_toName(lang)).arg(lang));
    11121116
    11131117    if (m_parent && (oldTrack != currentTrack[type]))