Ticket #259: 259-v1.patch
File 259-v1.patch, 10.0 KB (added by , 18 years ago) |
---|
-
libs/libmythtv/avformatdecoder.cpp
167 167 audio_sample_size(-1), audio_sampling_rate(-1), audio_channels(-1), 168 168 do_ac3_passthru(false), wantedAudioStream(-1), 169 169 audio_check_1st(2), audio_sampling_rate_2nd(0), audio_channels_2nd(0), 170 wantedSubtitleStream(-1) 170 // Subtitles 171 languagePreference(iso639_get_language_key_list()), 172 wantedSubtitleStream(), 173 selectedSubtitleStream() 171 174 { 172 175 bzero(¶ms, sizeof(AVFormatParameters)); 173 176 bzero(prvpkt, 3 * sizeof(char)); … … 835 838 audio_sampling_rate_2nd = -1; 836 839 audio_channels_2nd = -1; 837 840 841 map<int,uint> lang_cnt; 842 838 843 for (int i = 0; i < ic->nb_streams; i++) 839 844 { 840 845 AVCodecContext *enc = ic->streams[i]->codec; … … 989 994 990 995 if (enc->codec_type == CODEC_TYPE_SUBTITLE) 991 996 { 992 subtitleStreams.push_back( i ); 997 int lang = -1, lang_indx = 0; 998 if (ic->streams[i]->language) 999 { 1000 lang = iso639_str3_to_key(ic->streams[i]->language); 1001 lang = iso639_key_to_canonical_key(lang); 1002 lang_indx = lang_cnt[lang]; 1003 lang_cnt[lang]++; 1004 } 1005 subtitleStreams.push_back(SubtitleInfo(i, lang, lang_indx)); 993 1006 } 994 1007 995 1008 if (enc->codec_type == CODEC_TYPE_AUDIO) … … 1869 1882 } 1870 1883 1871 1884 1872 void AvFormatDecoder::incCurrentSubtitleTrack( )1885 void AvFormatDecoder::incCurrentSubtitleTrack(void) 1873 1886 { 1874 if (subtitleStreams.size()) 1875 { 1876 int tempTrackNo = currentSubtitleTrack; 1877 ++tempTrackNo; 1878 if (tempTrackNo > (int)(subtitleStreams.size() - 1)) 1879 tempTrackNo = 0; 1880 1881 currentSubtitleTrack = tempTrackNo; 1882 wantedSubtitleStream = subtitleStreams[currentSubtitleTrack]; 1883 } 1887 int numStreams = (int)subtitleStreams.size(); 1888 int next = (currentSubtitleTrack+1) % numStreams; 1889 setCurrentSubtitleTrack((!numStreams) ? -1 : next); 1884 1890 } 1885 1891 1886 void AvFormatDecoder::decCurrentSubtitleTrack( )1892 void AvFormatDecoder::decCurrentSubtitleTrack(void) 1887 1893 { 1888 if (subtitleStreams.size()) 1889 { 1890 int tempTrackNo = currentSubtitleTrack; 1891 --tempTrackNo; 1892 if (tempTrackNo < 0) 1893 tempTrackNo = subtitleStreams.size() - 1; 1894 1895 currentSubtitleTrack = tempTrackNo; 1896 wantedSubtitleStream = subtitleStreams[currentSubtitleTrack]; 1897 } 1894 int numStreams = (int)subtitleStreams.size(); 1895 int next = (currentSubtitleTrack < 0) ? 0 : currentSubtitleTrack; 1896 next = (next+numStreams-1) % numStreams; 1897 setCurrentSubtitleTrack((!numStreams) ? -1 : next); 1898 1898 } 1899 1899 1900 1900 bool AvFormatDecoder::setCurrentSubtitleTrack(int trackNo) 1901 1901 { 1902 if (trackNo < 0) 1903 trackNo = -1; 1904 else if (trackNo >= (int)subtitleStreams.size()) 1902 if (trackNo >= (int)subtitleStreams.size()) 1905 1903 return false; 1906 1904 1907 currentSubtitleTrack = trackNo; 1908 if (currentSubtitleTrack < 0) 1909 return false; 1910 1911 wantedSubtitleStream = subtitleStreams[currentSubtitleTrack]; 1912 1913 return true; 1905 currentSubtitleTrack = max(-1, trackNo); 1906 if (currentSubtitleTrack > 0) 1907 { 1908 wantedSubtitleStream = subtitleStreams[currentSubtitleTrack]; 1909 selectedSubtitleStream = subtitleStreams[currentSubtitleTrack]; 1910 return true; 1911 } 1912 return false; 1914 1913 } 1915 1914 1916 QStringList AvFormatDecoder::listSubtitleTracks( ) const1915 QStringList AvFormatDecoder::listSubtitleTracks(void) const 1917 1916 { 1918 1917 QStringList list; 1919 int num_tracks = subtitleStreams.size(); 1920 int track; 1921 1922 for (track = 0; track < num_tracks; track++) 1918 1919 for (uint i = 0; i < subtitleStreams.size(); i++) 1923 1920 { 1924 AVStream *s = ic->streams[subtitleStreams[track]]; 1925 1926 if (!s) 1927 continue; 1928 1929 QString t = QString("%1: ").arg(track + 1); 1930 1931 if (strlen(s->language) > 0) 1932 { 1933 t += iso639_str_toName((unsigned char *)(s->language)); 1934 t += " "; 1935 } 1936 1937 list += t; 1921 QString msg = iso639_key_toName(subtitleStreams[i].language); 1922 msg = msg.isEmpty() ? "?" : msg; 1923 list += QString("%1: %2 ").arg(i+1).arg(msg); 1938 1924 } 1939 1925 1940 1926 return list; 1941 1927 } 1942 1928 1943 // in case there's only one subtitle language available, always choose it 1944 // 1945 // if more than one subtitle languages are found, the best one is 1946 // picked according to the ISO639Language[0..] settings 1947 // 1948 // in case there are no ISOLanguage[0..] settings, or no preferred language 1949 // is found, the first found subtitle stream is chosen 1950 bool AvFormatDecoder::autoSelectSubtitleTrack() 1929 /** \fn AvFormatDecoder::autoSelectSubtitleTrack(void) 1930 * \brief Select best subtitle track. 1931 * 1932 * If case there's only one subtitle available, always choose it. 1933 * 1934 * If there is a user selected subtitle we try to find it. 1935 * 1936 * If we can't find the user selected subtitle we try to 1937 * picked according to the ISO639Language[0..] settings. 1938 * 1939 * In case there are no ISOLanguage[0..] settings, or no preferred language 1940 * is found, the first found subtitle stream is chosen 1941 */ 1942 bool AvFormatDecoder::autoSelectSubtitleTrack(void) 1951 1943 { 1952 if (!subtitleStreams.size()) 1944 uint numStreams = subtitleStreams.size(); 1945 1946 if ((currentSubtitleTrack > 0) && (currentSubtitleTrack < (int)numStreams)) 1947 return true; // subtitle already selected 1948 1949 if (!numStreams) 1953 1950 { 1954 1951 currentSubtitleTrack = -1; 1955 wantedSubtitleStream= -1;1956 return false; 1952 selectedSubtitleStream.av_stream_index = -1; 1953 return false; // no subtitles available 1957 1954 } 1958 1955 1959 int maxTracks = (subtitleStreams.size() - 1);1956 int selectedTrack = (1 == numStreams) ? 0 : -1; 1960 1957 1961 int selectedTrack = -1; 1962 1963 // go through all preferred languages and pick the best found 1964 QStringList langPref = iso639_get_language_list(); 1965 QStringList::iterator l = langPref.begin(); 1966 for (; l != langPref.end() && selectedTrack == -1; ++l) 1958 if ((selectedTrack < 0) && wantedSubtitleStream.language) 1967 1959 { 1968 for (int track = 0; track < maxTracks; track++) 1960 // Try to reselect user selected subtitle stream. 1961 // This should find the stream after a commercial 1962 // break and in some cases after a channel change. 1963 int wlang = wantedSubtitleStream.language; 1964 uint windx = wantedSubtitleStream.language_index; 1965 for (uint i = 0; i < numStreams; i++) 1969 1966 { 1970 int tempStream = subtitleStreams[track]; 1971 AVStream* st = ic->streams[tempStream]; 1967 if (wlang == subtitleStreams[i].language) 1968 selectedTrack = i; 1969 if (windx == subtitleStreams[i].language_index) 1970 break; 1971 } 1972 } 1972 1973 1973 if (st->language == *l) 1974 if (selectedTrack < 0) 1975 { 1976 // Find first subtitle stream that matches a language in 1977 // order of most preferred to least preferred language. 1978 vector<int>::iterator it = languagePreference.begin(); 1979 for (; (it != languagePreference.end()) && (selectedTrack < 0); ++it) 1980 { 1981 for (uint i = 0; i < numStreams; i++) 1974 1982 { 1975 selectedTrack = track; 1976 break; 1983 if (*it == subtitleStreams[i].language) 1984 { 1985 selectedTrack = i; 1986 break; 1987 } 1977 1988 } 1978 1989 } 1979 1990 } 1980 1981 if (selectedTrack == -1)1982 {1983 selectedTrack = 0;1984 }1985 1991 1986 currentSubtitleTrack = selectedTrack; 1987 wantedSubtitleStream = subtitleStreams[currentSubtitleTrack]; 1992 currentSubtitleTrack = (selectedTrack < 0) ? 0 : -1; 1993 selectedSubtitleStream = subtitleStreams[currentSubtitleTrack]; 1994 if (!wantedSubtitleStream.language) 1995 wantedSubtitleStream = selectedSubtitleStream; 1988 1996 1989 1997 return true; 1990 1998 } 1991 1999 1992 1993 1994 2000 bool AvFormatDecoder::GetFrame(int onlyvideo) 1995 2001 { 1996 2002 AVPacket *pkt = NULL; … … 2013 2019 autoSelectAudioTrack(); 2014 2020 } 2015 2021 2016 if ((currentSubtitleTrack == -1 || 2017 currentSubtitleTrack >= (int)subtitleStreams.size()) && 2018 subtitleStreams.size() > 0) 2019 { 2020 autoSelectSubtitleTrack(); 2021 } 2022 autoSelectSubtitleTrack(); 2022 2023 2023 2024 bool skipaudio = (lastvpts == 0); 2024 2025 … … 2336 2337 int gotSubtitles = 0; 2337 2338 AVSubtitle subtitle; 2338 2339 2339 if (pkt->stream_index == wantedSubtitleStream) 2340 if (pkt->stream_index == 2341 selectedSubtitleStream.av_stream_index) 2340 2342 { 2341 2343 avcodec_decode_subtitle(context, &subtitle, 2342 2344 &gotSubtitles, ptr, len); -
libs/libmythtv/avformatdecoder.h
20 20 21 21 extern "C" void HandleStreamChange(void*); 22 22 23 class SubtitleInfo 24 { 25 public: 26 SubtitleInfo() : av_stream_index(-1), language(0), language_index(0) {} 27 SubtitleInfo(int a, int b, uint c) 28 : av_stream_index(a), language(b), language_index(c) {} 29 public: 30 int av_stream_index; 31 int language; ///< ISO639 cannonical language key 32 uint language_index; 33 }; 34 typedef vector<SubtitleInfo> sub_vec_t; 35 23 36 /// A decoder for video files. 24 37 25 38 /// The AvFormatDecoder is used to decode non-NuppleVideo files. … … 197 210 int audio_sampling_rate_2nd; ///< Used by CheckAudioParams 198 211 int audio_channels_2nd; ///< Used by CheckAudioParams 199 212 200 QValueVector<int> subtitleStreams; 201 int wantedSubtitleStream; 213 sub_vec_t subtitleStreams; 214 vector<int> languagePreference; 215 SubtitleInfo wantedSubtitleStream; 216 SubtitleInfo selectedSubtitleStream; 202 217 }; 203 218 204 219 #endif