#include "../mixer/write_frame.h"\r
\r
#include <common/env.h>\r
+#include <common/log/log.h>\r
\r
#include <boost/range/algorithm_ext/push_back.hpp>\r
\r
const double in_fps_;\r
const video_format_desc format_desc_;\r
bool auto_mode_;\r
- \r
+\r
+ size_t audio_sample_count_;\r
+\r
+ size_t video_frame_count_;\r
+ \r
implementation(double in_fps, const video_format_desc& format_desc)\r
: display_mode_(display_mode::invalid)\r
, in_fps_(in_fps)\r
, format_desc_(format_desc)\r
, auto_mode_(env::properties().get("configuration.auto-mode", false))\r
+ , audio_sample_count_(0)\r
+ , video_frame_count_(0)\r
{\r
}\r
\r
void push(const std::shared_ptr<write_frame>& video_frame)\r
{ \r
if(!video_frame)\r
+ { \r
+ CASPAR_LOG(debug) << L"video-frame-count: " << video_frame_count_;\r
+ video_frame_count_ = 0;\r
return;\r
+ }\r
+\r
+ ++video_frame_count_;\r
\r
// Fix field-order if needed\r
if(video_frame->get_type() == core::video_mode::lower && format_desc_.mode == core::video_mode::upper)\r
\r
void push(const std::shared_ptr<std::vector<int16_t>>& audio_samples)\r
{\r
- if(!audio_samples)\r
+ if(!audio_samples) \r
+ {\r
+ auto truncate = audio_sample_count_ % format_desc_.audio_samples_per_frame;\r
+ if(truncate > 0)\r
+ {\r
+ audio_samples_.erase(audio_samples_.end() - truncate, audio_samples_.end());\r
+ CASPAR_LOG(info) << L"frame_muxer: Truncating " << truncate << L" audio samples.";\r
+ }\r
+\r
+ CASPAR_LOG(debug) << L"audio-chunk-count: " << audio_sample_count_;\r
+ audio_sample_count_ = 0;\r
return;\r
+ }\r
+\r
+ audio_sample_count_ += audio_samples->size();\r
\r
boost::range::push_back(audio_samples_, *audio_samples);\r
process();\r
auto end = begin + format_desc_.audio_samples_per_frame;\r
\r
auto samples = std::vector<int16_t>(begin, end);\r
- audio_samples_ = std::vector<int16_t>(end, audio_samples_.end());\r
+ audio_samples_.erase(begin, end);\r
\r
return samples;\r
}\r
\r
void decode_frame()\r
{\r
+ bool flush = false;\r
+\r
for(int n = 0; n < 32 && ((muxer_.video_frames() < 2 && !video_decoder_.ready()) || (muxer_.audio_chunks() < 2 && !audio_decoder_.ready())); ++n) \r
{\r
std::shared_ptr<AVPacket> pkt;\r
{\r
video_decoder_.push(pkt);\r
audio_decoder_.push(pkt);\r
+\r
+ flush = !pkt;\r
}\r
}\r
\r
if(muxer_.audio_chunks() < 2)\r
audio_samples = audio_decoder_.poll();\r
});\r
-\r
- BOOST_FOREACH(auto& video, video_frames)\r
- muxer_.push(video); \r
-\r
+ \r
BOOST_FOREACH(auto& audio, audio_samples)\r
muxer_.push(audio);\r
+\r
+ BOOST_FOREACH(auto& video, video_frames)\r
+ muxer_.push(video); \r
}\r
\r
virtual std::wstring print() const\r