* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Helge Norberg, helge.norberg@svt.se
+* Author: Robert Nagy, ronag89@gmail.com
*/
#include "StdAfx.h"
{
try
{
- audio_decoders_.push_back(spl::make_shared<audio_decoder>(*input_, core::video_format_desc(), i));
+ audio_decoders_.push_back(spl::make_shared<audio_decoder>(*input_, core::video_format::invalid, i));
}
catch (...)
{
{
frame = (*a_decoder)();
- if (frame && frame->data[0])
+ if (frame == flush() || (frame && frame->data[0]))
break;
else
frame.reset();
{
frame = (*v_decoder)();
- if (frame && frame->data[0])
+ if (frame == flush() || (frame && frame->data[0]))
return { frame };
}
}
virtual void framerate(boost::rational<int> framerate) { CASPAR_THROW_EXCEPTION(invalid_operation() << msg_info(print() + L" not an encoder.")); }
virtual void start(bool has_audio, bool has_video) { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
virtual void stop() { }
+ virtual void flush_all() { }
virtual std::vector<AVSampleFormat> supported_sample_formats() const { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
virtual std::vector<int> supported_samplerates() const { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
virtual std::vector<AVPixelFormat> supported_pixel_formats() const { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
virtual int wanted_num_audio_streams() const { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
- virtual boost::optional<int> wanted_num_channels_per_stream() const { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
+ virtual boost::optional<int> wanted_num_channels_per_stream() const { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
virtual boost::optional<AVMediaType> try_push(AVMediaType type, int stream_index, spl::shared_ptr<AVFrame> frame) { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
virtual void eof() { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
};
void stop() override
{
running_ = false;
- try_pop_frame();
- try_pop_frame();
+ output_frames_.set_capacity(4);
}
std::vector<AVSampleFormat> supported_sample_formats() const override
return boost::none;
}
+ void flush_all() override
+ {
+ audio_samples_.clear();
+
+ while (!video_frames_.empty())
+ video_frames_.pop();
+ }
+
boost::optional<AVMediaType> try_push(AVMediaType type, int stream_index, spl::shared_ptr<AVFrame> av_frame) override
{
if (!has_audio_ && !has_video_)
struct audio_stream_info
{
- int num_channels = 0;
- AVSampleFormat sampleformat = AVSampleFormat::AV_SAMPLE_FMT_NONE;
+ int num_channels = 0;
+ AVSampleFormat sampleformat = AVSampleFormat::AV_SAMPLE_FMT_NONE;
+ uint64_t channel_layout = 0;
};
struct video_stream_info
{
auto needed = *result;
auto input_frames_for_streams = source_->get_input_frames_for_streams(needed);
+ bool flush_all = !input_frames_for_streams.empty() && input_frames_for_streams.at(0) == flush();
- if (!input_frames_for_streams.empty() && input_frames_for_streams.at(0))
+ if (flush_all)
+ {
+ sink_->flush_all();
+
+ if (source_->has_audio() && source_->has_video())
+ result = needed == AVMediaType::AVMEDIA_TYPE_AUDIO ? AVMediaType::AVMEDIA_TYPE_VIDEO : AVMediaType::AVMEDIA_TYPE_AUDIO;
+
+ continue;
+ }
+
+ bool got_requested_media_type = !input_frames_for_streams.empty() && input_frames_for_streams.at(0);
+
+ if (got_requested_media_type)
{
for (int input_stream_index = 0; input_stream_index < input_frames_for_streams.size(); ++input_stream_index)
{
auto& av_frame = *av_frames_per_stream.at(i);
auto& stream = source_audio_streams_.at(i);
+ auto channel_layout = av_frame.channel_layout == 0
+ ? av_get_default_channel_layout(av_frame.channels)
+ : av_frame.channel_layout;
+
set_if_changed(changed, stream.sampleformat, static_cast<AVSampleFormat>(av_frame.format));
set_if_changed(changed, stream.num_channels, av_frame.channels);
+ set_if_changed(changed, stream.channel_layout, channel_layout);
}
if (changed)
boost::rational<int>(1, source_->samplerate()),
source_->samplerate(),
source_audio_stream.sampleformat,
- av_get_default_channel_layout(source_audio_stream.num_channels));
+ source_audio_stream.channel_layout);
}
auto total_num_channels = cpplinq::from(source_audio_streams_)