2032 | | AVCodec *codec = avcodec_find_decoder(enc->codec_id); |
2033 | | if (!codec) |
2034 | | { |
2035 | | LOG(VB_GENERAL, LOG_ERR, LOC + |
2036 | | QString("Could not find decoder for codec (%1), ignoring.") |
2037 | | .arg(ff_codec_id_string(enc->codec_id))); |
2038 | | |
2039 | | // Nigel's bogus codec-debug. Dump the list of codecs & decoders, |
2040 | | // and have one last attempt to find a decoder. This is usually |
2041 | | // only caused by build problems, where libavcodec needs a rebuild |
2042 | | if (VERBOSE_LEVEL_CHECK(VB_LIBAV, LOG_ANY)) |
2043 | | { |
2044 | | AVCodec *p = av_codec_next(NULL); |
2045 | | int i = 1; |
2046 | | while (p) |
2047 | | { |
2048 | | QString msg; |
2049 | | |
2050 | | if (p->name[0] != '\0') |
2051 | | msg = QString("Codec %1:").arg(p->name); |
2052 | | else |
2053 | | msg = QString("Codec %1, null name,").arg(i); |
2054 | | |
2055 | | if (p->decode == NULL) |
2056 | | msg += "decoder is null"; |
2057 | | |
2058 | | LOG(VB_LIBAV, LOG_INFO, LOC + msg); |
2059 | | |
2060 | | if (p->id == enc->codec_id) |
2061 | | { |
2062 | | codec = p; |
2063 | | break; |
2064 | | } |
2065 | | |
2066 | | LOG(VB_LIBAV, LOG_INFO, LOC + |
2067 | | QString("Codec 0x%1 != 0x%2") .arg(p->id, 0, 16) |
2068 | | .arg(enc->codec_id, 0, 16)); |
2069 | | p = av_codec_next(p); |
2070 | | ++i; |
2071 | | } |
2072 | | } |
2073 | | if (!codec) |
2074 | | continue; |
2075 | | } |
2076 | | // select vdpau capable decoder if needed |
2077 | | else if (enc->codec_type == AVMEDIA_TYPE_VIDEO && |
2078 | | codec_is_vdpau(video_codec_id) && !CODEC_IS_VDPAU(codec)) |
2079 | | { |
2080 | | codec = find_vdpau_decoder(codec, enc->codec_id); |
2081 | | } |
2082 | | |
2083 | | if (!enc->codec) |
| 2032 | if (!InitCodec(enc, i, |
| 2033 | &lang_sub_cnt, &subtitleStreamCount, |
| 2034 | &lang_aud_cnt, &audioStreamCount)) |
2085 | | QMutexLocker locker(avcodeclock); |
2086 | | |
2087 | | int open_val = avcodec_open2(enc, codec, NULL); |
2088 | | if (open_val < 0) |
2089 | | { |
2090 | | LOG(VB_GENERAL, LOG_ERR, LOC + |
2091 | | QString("Could not open codec 0x%1, id(%2) type(%3) " |
2092 | | "aborting. reason %4").arg((uint64_t)enc,0,16) |
2093 | | .arg(ff_codec_id_string(enc->codec_id)) |
2094 | | .arg(ff_codec_type_string(enc->codec_type)) |
2095 | | .arg(open_val)); |
2096 | | //av_close_input_file(ic); // causes segfault |
2097 | | ic = NULL; |
2098 | | scanerror = -1; |
2099 | | break; |
2100 | | } |
2101 | | else |
2102 | | { |
2103 | | LOG(VB_GENERAL, LOG_INFO, LOC + |
2104 | | QString("Opened codec 0x%1, id(%2) type(%3)") |
2105 | | .arg((uint64_t)enc,0,16) |
2106 | | .arg(ff_codec_id_string(enc->codec_id)) |
2107 | | .arg(ff_codec_type_string(enc->codec_type))); |
2108 | | } |
2109 | | } |
2110 | | |
2111 | | if (enc->codec_type == AVMEDIA_TYPE_SUBTITLE) |
2112 | | { |
2113 | | bool forced = ic->streams[i]->disposition & AV_DISPOSITION_FORCED; |
2114 | | int lang = GetSubtitleLanguage(subtitleStreamCount, i); |
2115 | | int lang_indx = lang_sub_cnt[lang]++; |
2116 | | subtitleStreamCount++; |
2117 | | |
2118 | | tracks[kTrackTypeSubtitle].push_back( |
2119 | | StreamInfo(i, lang, lang_indx, ic->streams[i]->id, 0, 0, false, false, forced)); |
2120 | | |
2121 | | LOG(VB_PLAYBACK, LOG_INFO, LOC + |
2122 | | QString("Subtitle track #%1 is A/V stream #%2 " |
2123 | | "and is in the %3 language(%4).") |
2124 | | .arg(tracks[kTrackTypeSubtitle].size()).arg(i) |
2125 | | .arg(iso639_key_toName(lang)).arg(lang)); |
2126 | | } |
2127 | | |
2128 | | if (enc->codec_type == AVMEDIA_TYPE_AUDIO) |
2129 | | { |
2130 | | int lang = GetAudioLanguage(audioStreamCount, i); |
2131 | | int channels = ic->streams[i]->codec->channels; |
2132 | | int lang_indx = lang_aud_cnt[lang]++; |
2133 | | audioStreamCount++; |
2134 | | AudioTrackType type = kAudioTypeNormal; |
2135 | | |
2136 | | if (ic->streams[i]->codec->avcodec_dual_language) |
2137 | | { |
2138 | | tracks[kTrackTypeAudio].push_back( |
2139 | | StreamInfo(i, lang, lang_indx, ic->streams[i]->id, channels, |
2140 | | false, false, false, type)); |
2141 | | lang_indx = lang_aud_cnt[lang]++; |
2142 | | tracks[kTrackTypeAudio].push_back( |
2143 | | StreamInfo(i, lang, lang_indx, ic->streams[i]->id, channels, |
2144 | | true, false, false, type)); |
2145 | | } |
2146 | | else |
2147 | | { |
2148 | | int logical_stream_id; |
2149 | | if (ringBuffer && ringBuffer->IsDVD()) |
2150 | | { |
2151 | | logical_stream_id = |
2152 | | ringBuffer->DVD()->GetAudioTrackNum(ic->streams[i]->id); |
2153 | | type = (AudioTrackType)(ringBuffer->DVD()->GetAudioTrackType(ic->streams[i]->id)); |
2154 | | } |
2155 | | else |
2156 | | logical_stream_id = ic->streams[i]->id; |
2157 | | |
2158 | | tracks[kTrackTypeAudio].push_back( |
2159 | | StreamInfo(i, lang, lang_indx, logical_stream_id, channels, |
2160 | | false, false, false, type)); |
2161 | | } |
2162 | | |
2163 | | LOG(VB_AUDIO, LOG_INFO, LOC + |
2164 | | QString("Audio Track #%1, with type %2 is A/V stream #%3 " |
2165 | | "and has %4 channels in the %5 language(%6).") |
2166 | | .arg(tracks[kTrackTypeAudio].size()).arg((int)type).arg(i) |
2167 | | .arg(enc->channels) |
2168 | | .arg(iso639_key_toName(lang)).arg(lang)); |
| 2036 | scanerror = -1; |
| 2037 | break; |
| 2098 | bool AvFormatDecoder::InitCodec(AVCodecContext *enc, int currentstream, |
| 2099 | map<int,uint> *lang_sub_cnt, |
| 2100 | uint *subtitleStreamCount, |
| 2101 | map<int,uint> *lang_aud_cnt, |
| 2102 | uint *audioStreamCount) |
| 2103 | { |
| 2104 | AVCodec *codec = avcodec_find_decoder(enc->codec_id); |
| 2105 | if (!codec) |
| 2106 | { |
| 2107 | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 2108 | QString("Could not find decoder for codec (%1), ignoring.") |
| 2109 | .arg(ff_codec_id_string(enc->codec_id))); |
| 2110 | |
| 2111 | // Nigel's bogus codec-debug. Dump the list of codecs & decoders, |
| 2112 | // and have one last attempt to find a decoder. This is usually |
| 2113 | // only caused by build problems, where libavcodec needs a rebuild |
| 2114 | if (VERBOSE_LEVEL_CHECK(VB_LIBAV, LOG_ANY)) |
| 2115 | { |
| 2116 | AVCodec *p = av_codec_next(NULL); |
| 2117 | int i = 1; |
| 2118 | while (p) |
| 2119 | { |
| 2120 | QString msg; |
| 2121 | |
| 2122 | if (p->name[0] != '\0') |
| 2123 | msg = QString("Codec %1:").arg(p->name); |
| 2124 | else |
| 2125 | msg = QString("Codec %1, null name,").arg(i); |
| 2126 | |
| 2127 | if (p->decode == NULL) |
| 2128 | msg += "decoder is null"; |
| 2129 | |
| 2130 | LOG(VB_LIBAV, LOG_INFO, LOC + msg); |
| 2131 | |
| 2132 | if (p->id == enc->codec_id) |
| 2133 | { |
| 2134 | codec = p; |
| 2135 | break; |
| 2136 | } |
| 2137 | |
| 2138 | LOG(VB_LIBAV, LOG_INFO, LOC + |
| 2139 | QString("Codec 0x%1 != 0x%2") .arg(p->id, 0, 16) |
| 2140 | .arg(enc->codec_id, 0, 16)); |
| 2141 | p = av_codec_next(p); |
| 2142 | ++i; |
| 2143 | } |
| 2144 | } |
| 2145 | if (!codec) |
| 2146 | return true; |
| 2147 | } |
| 2148 | // select vdpau capable decoder if needed |
| 2149 | else if (enc->codec_type == AVMEDIA_TYPE_VIDEO && |
| 2150 | codec_is_vdpau(video_codec_id) && !CODEC_IS_VDPAU(codec)) |
| 2151 | { |
| 2152 | codec = find_vdpau_decoder(codec, enc->codec_id); |
| 2153 | } |
| 2154 | |
| 2155 | if (!enc->codec) |
| 2156 | { |
| 2157 | QMutexLocker locker(avcodeclock); |
| 2158 | |
| 2159 | int open_val = avcodec_open2(enc, codec, NULL); |
| 2160 | if (open_val < 0) |
| 2161 | { |
| 2162 | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 2163 | QString("Could not open codec 0x%1, id(%2) type(%3) " |
| 2164 | "aborting. reason %4").arg((uint64_t)enc,0,16) |
| 2165 | .arg(ff_codec_id_string(enc->codec_id)) |
| 2166 | .arg(ff_codec_type_string(enc->codec_type)) |
| 2167 | .arg(open_val)); |
| 2168 | //av_close_input_file(ic); // causes segfault |
| 2169 | ic = NULL; |
| 2170 | return false; |
| 2171 | } |
| 2172 | else |
| 2173 | { |
| 2174 | LOG(VB_GENERAL, LOG_INFO, LOC + |
| 2175 | QString("Opened codec 0x%1, id(%2) type(%3)") |
| 2176 | .arg((uint64_t)enc,0,16) |
| 2177 | .arg(ff_codec_id_string(enc->codec_id)) |
| 2178 | .arg(ff_codec_type_string(enc->codec_type))); |
| 2179 | } |
| 2180 | } |
| 2181 | |
| 2182 | if (enc->codec_type == AVMEDIA_TYPE_SUBTITLE) |
| 2183 | { |
| 2184 | bool forced = ic->streams[currentstream]->disposition & AV_DISPOSITION_FORCED; |
| 2185 | int lang = GetSubtitleLanguage(*subtitleStreamCount, currentstream); |
| 2186 | int lang_indx = (*lang_sub_cnt)[lang]++; |
| 2187 | *subtitleStreamCount++; |
| 2188 | |
| 2189 | tracks[kTrackTypeSubtitle].push_back( |
| 2190 | StreamInfo(currentstream, lang, lang_indx, |
| 2191 | ic->streams[currentstream]->id, 0, |
| 2192 | 0, false, false, forced)); |
| 2193 | |
| 2194 | LOG(VB_PLAYBACK, LOG_INFO, LOC + |
| 2195 | QString("Subtitle track #%1 is A/V stream #%2 " |
| 2196 | "and is in the %3 language(%4).") |
| 2197 | .arg(tracks[kTrackTypeSubtitle].size()).arg(currentstream) |
| 2198 | .arg(iso639_key_toName(lang)).arg(lang)); |
| 2199 | } |
| 2200 | |
| 2201 | if (enc->codec_type == AVMEDIA_TYPE_AUDIO) |
| 2202 | { |
| 2203 | int lang = GetAudioLanguage(*audioStreamCount, currentstream); |
| 2204 | int channels = ic->streams[currentstream]->codec->channels; |
| 2205 | int lang_indx = (*lang_aud_cnt)[lang]++; |
| 2206 | *audioStreamCount++; |
| 2207 | AudioTrackType type = kAudioTypeNormal; |
| 2208 | |
| 2209 | if (ic->streams[currentstream]->codec->avcodec_dual_language) |
| 2210 | { |
| 2211 | tracks[kTrackTypeAudio].push_back( |
| 2212 | StreamInfo(currentstream, lang, lang_indx, |
| 2213 | ic->streams[currentstream]->id, channels, |
| 2214 | false, false, false, type)); |
| 2215 | lang_indx = (*lang_aud_cnt)[lang]++; |
| 2216 | tracks[kTrackTypeAudio].push_back( |
| 2217 | StreamInfo(currentstream, lang, lang_indx, |
| 2218 | ic->streams[currentstream]->id, channels, |
| 2219 | true, false, false, type)); |
| 2220 | } |
| 2221 | else |
| 2222 | { |
| 2223 | int logical_stream_id; |
| 2224 | if (ringBuffer && ringBuffer->IsDVD()) |
| 2225 | { |
| 2226 | logical_stream_id = |
| 2227 | ringBuffer->DVD()->GetAudioTrackNum(ic->streams[currentstream]->id); |
| 2228 | type = |
| 2229 | (AudioTrackType)(ringBuffer->DVD()->GetAudioTrackType(ic->streams[currentstream]->id)); |
| 2230 | } |
| 2231 | else |
| 2232 | logical_stream_id = ic->streams[currentstream]->id; |
| 2233 | |
| 2234 | tracks[kTrackTypeAudio].push_back( |
| 2235 | StreamInfo(currentstream, lang, lang_indx, logical_stream_id, |
| 2236 | channels, false, false, false, type)); |
| 2237 | } |
| 2238 | |
| 2239 | LOG(VB_AUDIO, LOG_INFO, LOC + |
| 2240 | QString("Audio Track #%1, with type %2 is A/V stream #%3 " |
| 2241 | "and has %4 channels in the %5 language(%6).") |
| 2242 | .arg(tracks[kTrackTypeAudio].size()).arg((int)type).arg(currentstream) |
| 2243 | .arg(enc->channels) |
| 2244 | .arg(iso639_key_toName(lang)).arg(lang)); |
| 2245 | } |
| 2246 | return true; |
| 2247 | } |
| 2248 | |