| 17 | namespace Ffmpeg { |
| 18 | |
| 19 | AudioFormat |
| 20 | DetectFilterOutputFormat(const AudioFormat &in_audio_format, |
| 21 | AVFilterContext &buffer_src, |
| 22 | AVFilterContext &buffer_sink) |
| 23 | { |
| 24 | uint_least64_t silence[MAX_CHANNELS]; |
| 25 | const size_t silence_size = in_audio_format.GetFrameSize(); |
| 26 | assert(sizeof(silence) >= silence_size); |
| 27 | |
| 28 | PcmSilence(std::as_writable_bytes(std::span{silence}), |
| 29 | in_audio_format.format); |
| 30 | |
| 31 | Frame frame; |
| 32 | frame->format = ToFfmpegSampleFormat(in_audio_format.format); |
| 33 | frame->sample_rate = in_audio_format.sample_rate; |
| 34 | #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 25, 100) |
| 35 | av_channel_layout_default(&frame->ch_layout, in_audio_format.channels); |
| 36 | #else |
| 37 | frame->channels = in_audio_format.channels; |
| 38 | #endif |
| 39 | frame->nb_samples = 1; |
| 40 | |
| 41 | frame.GetBuffer(); |
| 42 | |
| 43 | memcpy(frame.GetData(0), silence, silence_size); |
| 44 | |
| 45 | int err = av_buffersrc_add_frame(&buffer_src, frame.get()); |
| 46 | if (err < 0) |
| 47 | throw MakeFfmpegError(err, "av_buffersrc_add_frame() failed"); |
| 48 | |
| 49 | frame.Unref(); |
| 50 | |
| 51 | err = av_buffersink_get_frame(&buffer_sink, frame.get()); |
| 52 | if (err < 0) { |
| 53 | if (err == AVERROR(EAGAIN)) |
| 54 | /* one sample was not enough input data for |
| 55 | the given filter graph */ |
| 56 | return AudioFormat::Undefined(); |
| 57 | |
| 58 | throw MakeFfmpegError(err, "av_buffersink_get_frame() failed"); |
| 59 | } |
| 60 | |
| 61 | const SampleFormat sample_format = FromFfmpegSampleFormat(AVSampleFormat(frame->format)); |
| 62 | if (sample_format == SampleFormat::UNDEFINED) |
| 63 | throw std::runtime_error("Unsupported FFmpeg sample format"); |
| 64 | |
| 65 | #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 25, 100) |
| 66 | const unsigned out_channels = frame->ch_layout.nb_channels; |
| 67 | #else |
| 68 | const unsigned out_channels = frame->channels; |
| 69 | #endif |
| 70 | |
| 71 | return CheckAudioFormat(frame->sample_rate, sample_format, |
| 72 | out_channels); |
| 73 | } |
| 74 | |
| 75 | } // namespace Ffmpeg |
no test coverage detected