From fa592f198eb6d89395241baf0e702e49b93557c3 Mon Sep 17 00:00:00 2001 From: John Peebles Date: Mon, 1 Sep 2014 13:21:41 +0200 Subject: Allow selecting subtitles on a substring match in advanced mode Fixes issue 453. Signed-off-by: Hendrik Leppkes --- demuxer/Demuxers/BaseDemuxer.h | 2 ++ demuxer/Demuxers/LAVFDemuxer.cpp | 6 ++++++ demuxer/Demuxers/LAVFUtils.cpp | 23 +++++++++++++++-------- demuxer/Demuxers/LAVFUtils.h | 1 + demuxer/LAVSplitter/LAVSplitter.cpp | 12 ++++++++++-- 5 files changed, 34 insertions(+), 10 deletions(-) (limited to 'demuxer') diff --git a/demuxer/Demuxers/BaseDemuxer.h b/demuxer/Demuxers/BaseDemuxer.h index c65e6ed2..ff916a88 100644 --- a/demuxer/Demuxers/BaseDemuxer.h +++ b/demuxer/Demuxers/BaseDemuxer.h @@ -36,6 +36,7 @@ struct ILAVFSettingsInternal; typedef struct CSubtitleSelector { std::string audioLanguage; std::string subtitleLanguage; + std::string subtitleTrackName; #define SUBTITLE_FLAG_DEFAULT 0x0001 #define SUBTITLE_FLAG_FORCED 0x0002 @@ -57,6 +58,7 @@ public: CStreamInfo *streamInfo; DWORD pid; std::string language; + std::string trackName; LCID lcid; struct stream() { streamInfo = nullptr; pid = 0; lcid = 0; } operator DWORD() const { return pid; } diff --git a/demuxer/Demuxers/LAVFDemuxer.cpp b/demuxer/Demuxers/LAVFDemuxer.cpp index 76eb0650..54f585a9 100644 --- a/demuxer/Demuxers/LAVFDemuxer.cpp +++ b/demuxer/Demuxers/LAVFDemuxer.cpp @@ -1569,6 +1569,9 @@ STDMETHODIMP CLAVFDemuxer::AddStream(int streamId) s.language = "und"; s.lcid = 0; } + const char * title = lavf_get_stream_title(pStream); + if (title) + s.trackName = title; s.streamInfo = new CLAVFStreamInfo(m_avFormat, pStream, m_pszInputFormat, hr); if(FAILED(hr)) { @@ -2050,6 +2053,9 @@ const CBaseDemuxer::stream *CLAVFDemuxer::SelectSubtitleStream(std::listsubtitleTrackName.empty() && sit->trackName.find(it->subtitleTrackName) == std::string::npos) + continue; + if (it->dwFlags == 0 || ((it->dwFlags & SUBTITLE_FLAG_DEFAULT) && (m_avFormat->streams[sit->pid]->disposition & AV_DISPOSITION_DEFAULT)) || ((it->dwFlags & SUBTITLE_FLAG_FORCED) && (m_avFormat->streams[sit->pid]->disposition & AV_DISPOSITION_FORCED)) diff --git a/demuxer/Demuxers/LAVFUtils.cpp b/demuxer/Demuxers/LAVFUtils.cpp index f69849aa..561be62d 100644 --- a/demuxer/Demuxers/LAVFUtils.cpp +++ b/demuxer/Demuxers/LAVFUtils.cpp @@ -194,6 +194,20 @@ static bool show_sample_fmt(AVCodecID codec_id) { return false; } +const char * lavf_get_stream_title(AVStream * pStream) +{ + char *title = nullptr; + if (AVDictionaryEntry *dictEntry = av_dict_get(pStream->metadata, "title", nullptr, 0)) { + title = dictEntry->value; + } else if (AVDictionaryEntry *dictEntry = av_dict_get(pStream->metadata, "handler_name", nullptr, 0)) { + title = dictEntry->value; + if (strcmp(title, "GPAC ISO Video Handler") == 0 || strcmp(title, "VideoHandler") == 0 || strcmp(title, "GPAC ISO Audio Handler") == 0 || strcmp(title, "GPAC Streaming Text Handler") == 0) + title = nullptr; + } + + return title; +} + std::string lavf_get_stream_description(AVStream *pStream) { AVCodecContext *enc = pStream->codec; @@ -210,14 +224,7 @@ std::string lavf_get_stream_description(AVStream *pStream) } } - char *title = nullptr; - if (AVDictionaryEntry *dictEntry = av_dict_get(pStream->metadata, "title", nullptr, 0)) { - title = dictEntry->value; - } else if (AVDictionaryEntry *dictEntry = av_dict_get(pStream->metadata, "handler_name", nullptr, 0)) { - title = dictEntry->value; - if (strcmp(title, "GPAC ISO Video Handler") == 0 || strcmp(title, "VideoHandler") == 0|| strcmp(title, "GPAC ISO Audio Handler") == 0 || strcmp(title, "GPAC Streaming Text Handler") == 0) - title = nullptr; - } + const char * title = lavf_get_stream_title(pStream); // Empty titles are rather useless if (title && strlen(title) == 0) diff --git a/demuxer/Demuxers/LAVFUtils.h b/demuxer/Demuxers/LAVFUtils.h index 4f95fa90..7d0d20d2 100644 --- a/demuxer/Demuxers/LAVFUtils.h +++ b/demuxer/Demuxers/LAVFUtils.h @@ -28,6 +28,7 @@ struct FormatMapping { const char *get_stream_language(const AVStream *pStream); std::string get_codec_name(AVCodecContext *pCodecCtx); +const char * lavf_get_stream_title(AVStream * pStream); std::string lavf_get_stream_description(AVStream *pStream); #define LAVF_DISPOSITION_SUB_STREAM 0x10000 diff --git a/demuxer/LAVSplitter/LAVSplitter.cpp b/demuxer/LAVSplitter/LAVSplitter.cpp index d28de250..de823403 100644 --- a/demuxer/LAVSplitter/LAVSplitter.cpp +++ b/demuxer/LAVSplitter/LAVSplitter.cpp @@ -1465,7 +1465,12 @@ std::list CLAVSplitter::GetSubtitleSelectors() // Add the "off" termination element tokenList.push_back("*:off"); - std::tr1::regex advRegex("(?:(\\*|[[:alpha:]]+):)?(\\*|[[:alpha:]]+)(?:\\|(!?)([fdnh]+))?"); + std::tr1::regex advRegex( + "(?:(\\*|[[:alpha:]]+):)?" // audio language + "(\\*|[[:alpha:]]+)" // subtitle language + "(?:\\|(!?)([fdnh]+))?" // flags + "(?:@([^" + separators + "]+))?" // subtitle track name substring + ); for (const std::string& token : tokenList) { std::tr1::cmatch res; bool found = std::tr1::regex_search(token.c_str(), res, advRegex); @@ -1501,8 +1506,11 @@ std::list CLAVSplitter::GetSubtitleSelectors() selector.dwFlags = (~selector.dwFlags) & 0xFF; } } + + selector.subtitleTrackName = res[5]; + selectorList.push_back(selector); - DbgLog((LOG_TRACE, 10, L"::GetSubtitleSelectors(): Parsed selector \"%S\" to: %S -> %S (flags: 0x%x)", token.c_str(), selector.audioLanguage.c_str(), selector.subtitleLanguage.c_str(), selector.dwFlags)); + DbgLog((LOG_TRACE, 10, L"::GetSubtitleSelectors(): Parsed selector \"%S\" to: %S -> %S (flags: 0x%x, match: %S)", token.c_str(), selector.audioLanguage.c_str(), selector.subtitleLanguage.c_str(), selector.dwFlags, selector.subtitleTrackName.c_str())); } else { DbgLog((LOG_ERROR, 10, L"::GetSubtitleSelectors(): Selector string \"%S\" could not be parsed", token.c_str())); } -- cgit v1.2.3