| 214 | } |
| 215 | |
| 216 | void FFMS_AudioSource::SetOutputFormat(FFMS_ResampleOptions const& opt) { |
| 217 | if (opt.SampleRate != AP.SampleRate) |
| 218 | throw FFMS_Exception(FFMS_ERROR_RESAMPLING, FFMS_ERROR_UNSUPPORTED, |
| 219 | "Sample rate changes are currently unsupported."); |
| 220 | |
| 221 | // Cache stores audio in the output format, so clear it and reopen the file |
| 222 | Cache.clear(); |
| 223 | PacketNumber = 0; |
| 224 | OpenFile(); |
| 225 | avcodec_flush_buffers(CodecContext); |
| 226 | |
| 227 | BytesPerSample = av_get_bytes_per_sample(static_cast<AVSampleFormat>(opt.SampleFormat)) * PopCount(opt.ChannelLayout); |
| 228 | NeedsResample = |
| 229 | opt.SampleFormat != (int)CodecContext->sample_fmt || |
| 230 | opt.SampleRate != AP.SampleRate || |
| 231 | opt.ChannelLayout != AP.ChannelLayout || |
| 232 | opt.ForceResample; |
| 233 | |
| 234 | if (!NeedsResample) return; |
| 235 | |
| 236 | SwrContext *rawCtx = swr_alloc(); |
| 237 | |
| 238 | AVChannelLayout ChLayoutOut = { AV_CHANNEL_ORDER_NATIVE, PopCount(opt.ChannelLayout), static_cast<uint64_t>(opt.ChannelLayout), nullptr }; |
| 239 | AVChannelLayout ChLayoutIn = { AV_CHANNEL_ORDER_NATIVE, PopCount(AP.ChannelLayout), static_cast<uint64_t>(AP.ChannelLayout), nullptr }; |
| 240 | swr_alloc_set_opts2(&rawCtx, &ChLayoutOut, (AVSampleFormat)opt.SampleFormat, opt.SampleRate, &ChLayoutIn, CodecContext->sample_fmt, AP.SampleRate, 0, nullptr); |
| 241 | |
| 242 | FFResampleContext newContext{ rawCtx }; |
| 243 | |
| 244 | SetOptions(opt, newContext.get(), resample_options); |
| 245 | |
| 246 | if (swr_init(newContext.get())) |
| 247 | throw FFMS_Exception(FFMS_ERROR_RESAMPLING, FFMS_ERROR_UNKNOWN, |
| 248 | "Could not open avresample context"); |
| 249 | newContext.swap(ResampleContext); |
| 250 | } |
| 251 | |
| 252 | std::unique_ptr<FFMS_ResampleOptions> FFMS_AudioSource::CreateResampleOptions() const { |
| 253 | auto ret = ReadOptions(ResampleContext.get(), resample_options); |
nothing calls this directly
no test coverage detected