X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fffmpeg%2Fproducer%2Ffilter%2Faudio_filter.cpp;h=ac70f04c0ede531c6f718e42f0e59a47300cc2b4;hb=009816de6e071c6a35c74b0954d04cf61005b971;hp=ad6a34ff1ce5b4da0647d793220e58bfc1c49e18;hpb=4439ad71cff8cd80c1eeabc059b6f86da6067980;p=casparcg diff --git a/modules/ffmpeg/producer/filter/audio_filter.cpp b/modules/ffmpeg/producer/filter/audio_filter.cpp index ad6a34ff1..ac70f04c0 100644 --- a/modules/ffmpeg/producer/filter/audio_filter.cpp +++ b/modules/ffmpeg/producer/filter/audio_filter.cpp @@ -77,7 +77,7 @@ std::string create_filter_list(const std::vector& items) return boost::join(items, "|"); } -std::string channel_layout_to_string(int64_t channel_layout) +std::string channel_layout_to_string(uint64_t channel_layout) { return (boost::format("0x%|1$x|") % channel_layout).str(); } @@ -108,13 +108,16 @@ struct audio_filter::implementation std::vector audio_graph_inputs_; std::vector audio_graph_outputs_; + std::vector input_pads_; + implementation( std::vector input_pads, std::vector output_pads, const std::string& filtergraph) : filtergraph_(boost::to_lower_copy(filtergraph)) + , input_pads_(std::move(input_pads)) { - if (input_pads.empty()) + if (input_pads_.empty()) CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("input_pads cannot be empty")); if (output_pads.empty()) @@ -131,7 +134,7 @@ struct audio_filter::implementation { int i = 0; - for (auto& input_pad : input_pads) + for (auto& input_pad : input_pads_) complete_filter_graph.push_back(create_sourcefilter_str(input_pad, "a:" + boost::lexical_cast(i++))); } @@ -211,6 +214,31 @@ struct audio_filter::implementation src_av_frame.get())); } + void push(int input_pad_id, const boost::iterator_range& frame_samples) + { + auto& input_pad = input_pads_.at(input_pad_id); + auto num_samples = frame_samples.size() / av_get_channel_layout_nb_channels(input_pad.audio_channel_layout); + auto input_frame = ffmpeg::create_frame(); + + input_frame->channels = av_get_channel_layout_nb_channels(input_pad.audio_channel_layout); + input_frame->channel_layout = input_pad.audio_channel_layout; + input_frame->sample_rate = input_pad.sample_rate; + input_frame->nb_samples = static_cast(num_samples); + input_frame->format = input_pad.sample_fmt; + input_frame->pts = 0; + + av_samples_fill_arrays( + input_frame->extended_data, + input_frame->linesize, + reinterpret_cast(frame_samples.begin()), + input_frame->channels, + input_frame->nb_samples, + static_cast(input_frame->format), + 16); + + push(input_pad_id, input_frame); + } + std::shared_ptr poll(int output_pad_id) { auto filt_frame = create_frame(); @@ -238,6 +266,7 @@ audio_filter::audio_filter( audio_filter::audio_filter(audio_filter&& other) : impl_(std::move(other.impl_)){} audio_filter& audio_filter::operator=(audio_filter&& other){impl_ = std::move(other.impl_); return *this;} void audio_filter::push(int input_pad_id, const std::shared_ptr& frame){impl_->push(input_pad_id, frame);} +void audio_filter::push(int input_pad_id, const boost::iterator_range& frame_samples) { impl_->push(input_pad_id, frame_samples); } std::shared_ptr audio_filter::poll(int output_pad_id){return impl_->poll(output_pad_id);} std::wstring audio_filter::filter_str() const{return u16(impl_->filtergraph_);} std::vector> audio_filter::poll_all(int output_pad_id)