From 4fe1522fc8fd957f76fa3d82f0b9cecf7ad7748c Mon Sep 17 00:00:00 2001 From: Mark Kendall Date: Mon, 17 Oct 2011 13:46:32 +0100 Subject: [PATCH] Subtitles: Add initial forced subtitle support. This enables forced subtitles when they are part of the current, automatically selected subtitle stream (i.e. if your language is English, an English subtitle track is automatically selected in the existing code. Any forced subtitle detected will now be displayed). I will add an OSD menu option to toggle forced subtitles. This will not work for blu ray material where the forced subtitles are on a different track entirely. There are still some intermittent issues with DVD material that seem to be related to the existing code. In these cases the forced subtitles may no display. --- mythtv/libs/libmythtv/avformatdecoder.cpp | 7 +++++-- mythtv/libs/libmythtv/mythplayer.cpp | 17 +++++++++++++++ mythtv/libs/libmythtv/mythplayer.h | 4 ++++ mythtv/libs/libmythtv/subtitlereader.cpp | 25 ++++++++++++++++++++--- mythtv/libs/libmythtv/subtitlereader.h | 2 +- mythtv/libs/libmythtv/subtitlescreen.cpp | 7 ++++--- 6 files changed, 53 insertions(+), 9 deletions(-) diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp index 89e05299607..40a2180fbb8 100644 --- a/mythtv/libs/libmythtv/avformatdecoder.cpp +++ b/mythtv/libs/libmythtv/avformatdecoder.cpp @@ -3398,8 +3398,11 @@ bool AvFormatDecoder::ProcessSubtitlePacket(AVStream *curstream, AVPacket *pkt) .arg(subtitle.start_display_time) .arg(subtitle.end_display_time)); - m_parent->GetSubReader(pkt->stream_index)->AddAVSubtitle( - subtitle, curstream->codec->codec_id == CODEC_ID_XSUB); + if (m_parent->GetSubReader(pkt->stream_index)->AddAVSubtitle( + subtitle, curstream->codec->codec_id == CODEC_ID_XSUB)) + { + m_parent->EnableForcedSubtitles(); + } } return true; diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp index 4e53e26577c..60eb4116f59 100644 --- a/mythtv/libs/libmythtv/mythplayer.cpp +++ b/mythtv/libs/libmythtv/mythplayer.cpp @@ -167,6 +167,7 @@ MythPlayer::MythPlayer(bool muted) ttPageNum(0x888), // Support for captions, teletext, etc. decoded by libav textDesired(false), enableCaptions(false), disableCaptions(false), + enableForcedSubtitles(false), allowForcedSubtitles(true), // CC608/708 db_prefer708(true), cc608(this), cc708(this), // MHEG/MHI Interactive TV visible in OSD @@ -1536,6 +1537,18 @@ void MythPlayer::EnableSubtitles(bool enable) disableCaptions = true; } +void MythPlayer::DoEnableForcedSubtitles(void) +{ + enableForcedSubtitles = false; + if (!allowForcedSubtitles) + return; + + osdLock.lock(); + if (osd) + osd->InitSubtitles(); + osdLock.unlock(); +} + int MythPlayer::GetTrack(uint type) { if (decoder) @@ -2603,6 +2616,10 @@ void MythPlayer::EventLoop(void) if (disableCaptions) SetCaptionsEnabled(false, false); + // enable forced subtitles if signalled by the decoder + if (enableForcedSubtitles) + DoEnableForcedSubtitles(); + // reset the scan (and hence deinterlacers) if triggered by the decoder if (resetScan != kScan_Ignore) SetScanType(resetScan); diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h index 3caefa3e2a4..21ccd3da40f 100644 --- a/mythtv/libs/libmythtv/mythplayer.h +++ b/mythtv/libs/libmythtv/mythplayer.h @@ -258,6 +258,7 @@ class MTV_PUBLIC MythPlayer // Public Audio/Subtitle/EIA-608/EIA-708 stream selection - thread safe void TracksChanged(uint trackType); void EnableSubtitles(bool enable); + void EnableForcedSubtitles(void) { enableForcedSubtitles = true; } // Public MHEG/MHI stream selection bool SetAudioByComponentTag(int tag); @@ -441,6 +442,7 @@ class MTV_PUBLIC MythPlayer int ChangeTrack(uint type, int dir); void ChangeCaptionTrack(int dir); int NextCaptionTrack(int mode); + void DoEnableForcedSubtitles(void); // Teletext Menu and non-NUV teletext decoder void EnableTeletext(int page = 0x100); @@ -653,6 +655,8 @@ class MTV_PUBLIC MythPlayer bool textDesired; bool enableCaptions; bool disableCaptions; + bool enableForcedSubtitles; + bool allowForcedSubtitles; // CC608/708 bool db_prefer708; diff --git a/mythtv/libs/libmythtv/subtitlereader.cpp b/mythtv/libs/libmythtv/subtitlereader.cpp index a6eb2e4d3a8..e017d3d8438 100644 --- a/mythtv/libs/libmythtv/subtitlereader.cpp +++ b/mythtv/libs/libmythtv/subtitlereader.cpp @@ -1,3 +1,4 @@ +#include "mythlogging.h" #include "subtitlereader.h" SubtitleReader::SubtitleReader() @@ -28,18 +29,36 @@ void SubtitleReader::EnableRawTextSubtitles(bool enable) m_RawTextSubtitlesEnabled = enable; } -void SubtitleReader::AddAVSubtitle(const AVSubtitle &subtitle, +bool SubtitleReader::AddAVSubtitle(const AVSubtitle &subtitle, bool fix_position) { - if (!m_AVSubtitlesEnabled) + bool enableforced = false; + if (!m_AVSubtitlesEnabled && !subtitle.forced) { FreeAVSubtitle(subtitle); - return; + return enableforced; } + + if (!m_AVSubtitlesEnabled && subtitle.forced) + enableforced = true; + + bool clearsubs = false; m_AVSubtitles.lock.lock(); m_AVSubtitles.fixPosition = fix_position; m_AVSubtitles.buffers.push_back(subtitle); + // in case forced subtitles aren't displayed, avoid leaking by + // manually clearing the subtitles + if (m_AVSubtitles.buffers.size() > 20) + { + LOG(VB_GENERAL, LOG_ERR, ">20 AVSubtitles queued - clearing."); + clearsubs = true; + } m_AVSubtitles.lock.unlock(); + + if (clearsubs) + ClearAVSubtitles(); + + return enableforced; } void SubtitleReader::ClearAVSubtitles(void) diff --git a/mythtv/libs/libmythtv/subtitlereader.h b/mythtv/libs/libmythtv/subtitlereader.h index cc6591e223d..454861cb1c9 100644 --- a/mythtv/libs/libmythtv/subtitlereader.h +++ b/mythtv/libs/libmythtv/subtitlereader.h @@ -38,7 +38,7 @@ class SubtitleReader void EnableRawTextSubtitles(bool enable); AVSubtitles* GetAVSubtitles(void) { return &m_AVSubtitles; } - void AddAVSubtitle(const AVSubtitle& subtitle, bool fix_position); + bool AddAVSubtitle(const AVSubtitle& subtitle, bool fix_position); void ClearAVSubtitles(void); void FreeAVSubtitle(const AVSubtitle &sub); diff --git a/mythtv/libs/libmythtv/subtitlescreen.cpp b/mythtv/libs/libmythtv/subtitlescreen.cpp index c4905f922a8..b35a41692fa 100644 --- a/mythtv/libs/libmythtv/subtitlescreen.cpp +++ b/mythtv/libs/libmythtv/subtitlescreen.cpp @@ -88,9 +88,10 @@ bool SubtitleScreen::Create(void) void SubtitleScreen::Pulse(void) { ExpireSubtitles(); - if (kDisplayAVSubtitle == m_subtitleType) - DisplayAVSubtitles(); - else if (kDisplayTextSubtitle == m_subtitleType) + + DisplayAVSubtitles(); // allow forced subtitles to work + + if (kDisplayTextSubtitle == m_subtitleType) DisplayTextSubtitles(); else if (kDisplayCC608 == m_subtitleType) DisplayCC608Subtitles();