- Fixed resampling of planar audio sample formats.
- Removed filter configuration logging.
</ClCompile>\r
<ClCompile Include="producer\audio\audio_resampler.cpp">\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
- <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
</ClCompile>\r
<ClCompile Include="producer\ffmpeg_producer.cpp">\r
<ClCompile Include="producer\filter\filter.cpp">\r
<Filter>source\producer\filter</Filter>\r
</ClCompile>\r
- <ClCompile Include="producer\audio\audio_resampler.cpp">\r
- <Filter>source\producer\audio</Filter>\r
- </ClCompile>\r
<ClCompile Include="producer\util\util.cpp">\r
<Filter>source\producer\util</Filter>\r
</ClCompile>\r
<ClCompile Include="producer\ffmpeg_producer.cpp">\r
<Filter>source\producer</Filter>\r
</ClCompile>\r
+ <ClCompile Include="producer\audio\audio_resampler.cpp">\r
+ <Filter>source\producer\audio</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="producer\ffmpeg_producer.h">\r
<ClInclude Include="producer\filter\filter.h">\r
<Filter>source\producer\filter</Filter>\r
</ClInclude>\r
- <ClInclude Include="producer\audio\audio_resampler.h">\r
- <Filter>source\producer\audio</Filter>\r
- </ClInclude>\r
<ClInclude Include="producer\util\flv.h">\r
<Filter>source\producer\util</Filter>\r
</ClInclude>\r
<ClInclude Include="producer\tbb_avcodec.h">\r
<Filter>source\producer</Filter>\r
</ClInclude>\r
+ <ClInclude Include="producer\audio\audio_resampler.h">\r
+ <Filter>source\producer\audio</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
{\r
#include <libavformat/avformat.h>\r
#include <libavcodec/avcodec.h>\r
+ #include <libswresample/swresample.h>\r
}\r
#if defined(_MSC_VER)\r
#pragma warning (pop)\r
\r
struct audio_decoder::implementation : boost::noncopyable\r
{ \r
- int index_;\r
- const safe_ptr<AVCodecContext> codec_context_; \r
- const core::video_format_desc format_desc_;\r
+ int index_;\r
+ const safe_ptr<AVCodecContext> codec_context_; \r
+ const core::video_format_desc format_desc_;\r
+ \r
+ std::vector<int32_t, tbb::cache_aligned_allocator<int32_t>> buffer_;\r
\r
- audio_resampler resampler_;\r
+ std::queue<safe_ptr<AVPacket>> packets_;\r
\r
- std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> buffer1_;\r
+ const int64_t nb_frames_;\r
+ tbb::atomic<size_t> file_frame_number_;\r
+ core::channel_layout channel_layout_;\r
\r
- std::queue<safe_ptr<AVPacket>> packets_;\r
+ std::shared_ptr<SwrContext> swr_;\r
\r
- const int64_t nb_frames_;\r
- tbb::atomic<size_t> file_frame_number_;\r
- core::channel_layout channel_layout_;\r
public:\r
explicit implementation(const safe_ptr<AVFormatContext>& context, const core::video_format_desc& format_desc, const std::wstring& custom_channel_order) \r
: format_desc_(format_desc) \r
, codec_context_(open_codec(*context, AVMEDIA_TYPE_AUDIO, index_))\r
- , resampler_(codec_context_->channels, codec_context_->channels,\r
- format_desc.audio_sample_rate, codec_context_->sample_rate,\r
- AV_SAMPLE_FMT_S32, codec_context_->sample_fmt)\r
- , buffer1_(480000*2)\r
+ , buffer_(480000*2)\r
, nb_frames_(0)//context->streams[index_]->nb_frames)\r
, channel_layout_(get_audio_channel_layout(*codec_context_, custom_channel_order))\r
- {\r
+ , swr_(swr_alloc_set_opts(nullptr,\r
+ codec_context_->channel_layout ? codec_context_->channel_layout : av_get_default_channel_layout(codec_context_->channels), AV_SAMPLE_FMT_S32, format_desc_.audio_sample_rate,\r
+ codec_context_->channel_layout ? codec_context_->channel_layout : av_get_default_channel_layout(codec_context_->channels), codec_context_->sample_fmt, codec_context_->sample_rate,\r
+ 0, nullptr), [](SwrContext* p){swr_free(&p);})\r
+ { \r
+ if(!swr_)\r
+ BOOST_THROW_EXCEPTION(bad_alloc());\r
+ \r
+ THROW_ON_ERROR2(swr_init(swr_.get()), "[audio_decoder]");\r
+\r
file_frame_number_ = 0;\r
\r
CASPAR_LOG(debug) << print() \r
}\r
\r
std::shared_ptr<core::audio_buffer> decode(AVPacket& pkt)\r
- { \r
- buffer1_.resize(480000*2);\r
- int written_bytes = buffer1_.size() - FF_INPUT_BUFFER_PADDING_SIZE;\r
+ { \r
+ std::shared_ptr<AVFrame> frame(\r
+ av_frame_alloc(), \r
+ [](AVFrame* p)\r
+ {\r
+ av_frame_free(&p);\r
+ });\r
\r
- int ret = THROW_ON_ERROR2(avcodec_decode_audio3(codec_context_.get(), reinterpret_cast<int16_t*>(buffer1_.data()), &written_bytes, &pkt), "[audio_decoder]");\r
-\r
- // There might be several frames in one packet.\r
- pkt.size -= ret;\r
- pkt.data += ret;\r
- \r
- buffer1_.resize(written_bytes);\r
+ int got_frame = 0;\r
+ auto len = THROW_ON_ERROR2(avcodec_decode_audio4(codec_context_.get(), frame.get(), &got_frame, &pkt), "[audio_decoder]");\r
+ \r
+ if(len == 0)\r
+ {\r
+ pkt.size = 0;\r
+ return nullptr;\r
+ }\r
\r
- buffer1_ = resampler_.resample(std::move(buffer1_));\r
+ pkt.data += len;\r
+ pkt.size -= len;\r
+ \r
+ if(!got_frame)\r
+ return nullptr;\r
+ \r
+ const uint8_t **in = const_cast<const uint8_t**>(frame->extended_data); \r
+ uint8_t* out[] = { reinterpret_cast<uint8_t*>(buffer_.data()) };\r
+ \r
+ const auto channel_samples = swr_convert(swr_.get(), \r
+ out, static_cast<int>(buffer_.size()) / codec_context_->channels, \r
+ in, frame->nb_samples);\r
\r
- const auto n_samples = buffer1_.size() / av_get_bytes_per_sample(AV_SAMPLE_FMT_S32);\r
- const auto samples = reinterpret_cast<int32_t*>(buffer1_.data());\r
-\r
++file_frame_number_;\r
\r
- return std::make_shared<core::audio_buffer>(samples, samples + n_samples);\r
+ return std::make_shared<core::audio_buffer>(buffer_.begin(), buffer_.begin() + channel_samples * frame->channels);\r
}\r
\r
bool ready() const\r
+++ /dev/null
-/*\r
-* Copyright 2013 Sveriges Television AB http://casparcg.com/\r
-*\r
-* This file is part of CasparCG (www.casparcg.com).\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-* Author: Robert Nagy, ronag89@gmail.com\r
-*/\r
-\r
-#include "../../StdAfx.h"\r
-\r
-#include "audio_resampler.h"\r
-\r
-#include <common/exception/exceptions.h>\r
-\r
-#if defined(_MSC_VER)\r
-#pragma warning (push)\r
-#pragma warning (disable : 4244)\r
-#endif\r
-extern "C" \r
-{\r
- #include <libavcodec/avcodec.h>\r
-}\r
-#if defined(_MSC_VER)\r
-#pragma warning (pop)\r
-#endif\r
-\r
-namespace caspar { namespace ffmpeg {\r
-\r
-struct audio_resampler::implementation\r
-{ \r
- std::shared_ptr<ReSampleContext> resampler_;\r
- \r
- std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> copy_buffer_;\r
- std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> buffer2_;\r
-\r
- const size_t output_channels_;\r
- const AVSampleFormat output_sample_format_;\r
-\r
- const size_t input_channels_;\r
- const AVSampleFormat input_sample_format_;\r
-\r
- implementation(size_t output_channels, size_t input_channels, size_t output_sample_rate, size_t input_sample_rate, AVSampleFormat output_sample_format, AVSampleFormat input_sample_format)\r
- : output_channels_(output_channels)\r
- , output_sample_format_(output_sample_format)\r
- , input_channels_(input_channels)\r
- , input_sample_format_(input_sample_format)\r
- {\r
- if(input_channels != output_channels || \r
- input_sample_rate != output_sample_rate ||\r
- input_sample_format != output_sample_format)\r
- { \r
- auto resampler = av_audio_resample_init(output_channels, input_channels,\r
- output_sample_rate, input_sample_rate,\r
- output_sample_format, input_sample_format,\r
- 16, 10, 0, 0.8);\r
-\r
- buffer2_.resize(480000*2);\r
-\r
- char sample_fmt_string[200];\r
- av_get_sample_fmt_string(sample_fmt_string, 200, input_sample_format);\r
-\r
- CASPAR_LOG(warning) << L"[audio-resampler]" \r
- << L" sample-rate: " << input_sample_rate \r
- << L" channels: " << input_channels \r
- << L" sample-fmt: " << widen(sample_fmt_string);\r
-\r
- if(resampler)\r
- resampler_.reset(resampler, audio_resample_close);\r
- else\r
- BOOST_THROW_EXCEPTION(caspar_exception());\r
- } \r
- }\r
-\r
- std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> resample(std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>&& data)\r
- {\r
- if(resampler_ && !data.empty())\r
- {\r
- buffer2_.resize(480000*2);\r
- auto ret = audio_resample(resampler_.get(),\r
- reinterpret_cast<short*>(buffer2_.data()), \r
- reinterpret_cast<short*>(data.data()), \r
- data.size() / (av_get_bytes_per_sample(input_sample_format_) * input_channels_)); \r
- buffer2_.resize(ret * av_get_bytes_per_sample(output_sample_format_) * output_channels_);\r
- std::swap(data, buffer2_);\r
- }\r
-\r
- return std::move(data);\r
- }\r
-};\r
-\r
-\r
-audio_resampler::audio_resampler(size_t output_channels, size_t input_channels, size_t output_sample_rate, size_t input_sample_rate, AVSampleFormat output_sample_format, AVSampleFormat input_sample_format)\r
- : impl_(new implementation(output_channels, input_channels, output_sample_rate, input_sample_rate, output_sample_format, input_sample_format)){}\r
-std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> audio_resampler::resample(std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>&& data){return impl_->resample(std::move(data));}\r
-\r
-}}
\ No newline at end of file
+++ /dev/null
-/*\r
-* Copyright 2013 Sveriges Television AB http://casparcg.com/\r
-*\r
-* This file is part of CasparCG (www.casparcg.com).\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-* Author: Robert Nagy, ronag89@gmail.com\r
-*/\r
-\r
-#pragma once\r
-\r
-#include <memory>\r
-\r
-#include <libavutil/samplefmt.h>\r
-\r
-namespace caspar { namespace ffmpeg {\r
-\r
-class audio_resampler\r
-{\r
-public:\r
- audio_resampler(size_t output_channels, size_t input_channels, \r
- size_t output_sample_rate, size_t input_sample_rate, \r
- AVSampleFormat output_sample_format, AVSampleFormat input_sample_format);\r
- \r
- std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> resample(std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>&& data);\r
-private:\r
- struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
-};\r
-\r
-}}
\ No newline at end of file
video_graph_in_ = filt_vsrc;\r
video_graph_out_ = filt_vsink;\r
\r
- CASPAR_LOG(info)\r
- << widen(std::string("\n") \r
- + avfilter_graph_dump(\r
- video_graph_.get(), \r
- nullptr));\r
+ //CASPAR_LOG(info)\r
+ // << widen(std::string("\n") \r
+ // + avfilter_graph_dump(\r
+ // video_graph_.get(), \r
+ // nullptr));\r
}\r
\r
void configure_filtergraph(\r
<ForcedIncludeFiles>common/compiler/vs/disable_silly_warnings.h</ForcedIncludeFiles>\r
</ClCompile>\r
<Link>\r
- <AdditionalDependencies>sfml-system-s-d.lib;sfml-audio-s-d.lib;sfml-window-s-d.lib;sfml-graphics-s-d.lib;OpenGL32.lib;FreeImage.lib;Winmm.lib;Ws2_32.lib;avformat.lib;avcodec.lib;avdevice.lib;avutil.lib;avfilter.lib;swscale.lib;tbb.lib;glew32.lib;zdll.lib</AdditionalDependencies>\r
+ <AdditionalDependencies>sfml-system-s-d.lib;sfml-audio-s-d.lib;sfml-window-s-d.lib;sfml-graphics-s-d.lib;OpenGL32.lib;FreeImage.lib;Winmm.lib;Ws2_32.lib;avformat.lib;avcodec.lib;avdevice.lib;avutil.lib;avfilter.lib;swscale.lib;swresample.lib;tbb.lib;glew32.lib;zdll.lib</AdditionalDependencies>\r
<Version>\r
</Version>\r
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
</Command>\r
</PreLinkEvent>\r
<Link>\r
- <AdditionalDependencies>sfml-system-s.lib;sfml-audio-s.lib;sfml-window-s.lib;sfml-graphics-s.lib;OpenGL32.lib;FreeImage.lib;Winmm.lib;Ws2_32.lib;avformat.lib;avcodec.lib;avdevice.lib;avutil.lib;avfilter.lib;swscale.lib;tbb.lib;glew32.lib;zdll.lib</AdditionalDependencies>\r
+ <AdditionalDependencies>sfml-system-s.lib;sfml-audio-s.lib;sfml-window-s.lib;sfml-graphics-s.lib;OpenGL32.lib;FreeImage.lib;Winmm.lib;Ws2_32.lib;avformat.lib;avcodec.lib;avdevice.lib;avutil.lib;avfilter.lib;swscale.lib;swresample.lib;tbb.lib;glew32.lib;zdll.lib</AdditionalDependencies>\r
<Version>\r
</Version>\r
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r