});\r
\r
// Remove first field stills.\r
- boost::range::remove_erase_if(layer.items, [&](const item& item)\r
+ if(format_desc.field_mode != core::field_mode::progressive)\r
{\r
- return item.transform.is_still && item.transform.field_mode == format_desc.field_mode; // only use last field for stills.\r
- });\r
+ boost::range::remove_erase_if(layer.items, [&](const item& item)\r
+ {\r
+ return item.transform.is_still && item.transform.field_mode == format_desc.field_mode; // only use last field for stills.\r
+ });\r
+ }\r
\r
if(layer.items.empty())\r
return;\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
</Link>\r
<PreBuildEvent>\r
- <Command>"SubWCRev.exe" "$(SolutionDir)." "$(SolutionDir)\version.tmpl" "$(SolutionDir)\version.h"</Command>\r
+ <Command>\r
+ </Command>\r
</PreBuildEvent>\r
<Lib />\r
</ItemDefinitionGroup>\r
<OptimizeReferences>true</OptimizeReferences>\r
</Link>\r
<PreBuildEvent>\r
- <Command>"SubWCRev.exe" "$(SolutionDir)." "$(SolutionDir)\version.tmpl" "$(SolutionDir)\version.h"</Command>\r
+ <Command>\r
+ </Command>\r
</PreBuildEvent>\r
<Lib>\r
<LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>\r
return draw_frame(std::move(frames));\r
}\r
\r
+draw_frame draw_frame::push(draw_frame frame)\r
+{\r
+ std::vector<draw_frame> frames;\r
+ frames.push_back(std::move(frame));\r
+ return draw_frame(std::move(frames));\r
+}\r
+\r
draw_frame eof_frame(const_frame(0));\r
draw_frame empty_frame(const_frame(0));\r
draw_frame late_frame(const_frame(0));\r
static draw_frame over(draw_frame frame1, draw_frame frame2);\r
static draw_frame mask(draw_frame fill, draw_frame key);\r
static draw_frame still(draw_frame frame);\r
+ static draw_frame push(draw_frame frame);\r
\r
static const draw_frame& eof();\r
static const draw_frame& empty();\r
auto transform = tween.fetch_and_tick(1);\r
\r
auto frame = layer.receive(format_desc); \r
- auto frame1 = core::draw_frame(frame);\r
+ auto frame1 = draw_frame::push(frame);\r
frame1.transform() = transform;\r
\r
if(format_desc.field_mode != core::field_mode::progressive)\r
{ \r
- auto frame2 = core::draw_frame(frame);\r
+ auto frame2 = draw_frame::push(frame);\r
frame2.transform() = tween.fetch_and_tick(1);\r
frame1 = core::draw_frame::interlace(frame1, frame2, format_desc.field_mode);\r
}\r
}\r
}();\r
\r
- return compose(dest, source);\r
+ return compose(draw_frame::push(dest), draw_frame::push(source));\r
}\r
\r
draw_frame last_frame() const override\r
<< monitor::event("file/fps") % fps_\r
<< monitor::event("file/path") % filename_\r
<< monitor::event("loop") % input_.loop();\r
+ \r
+ if(frame == core::draw_frame::late() && input_.eof())\r
+ return last_frame();\r
\r
return frame;\r
}\r
tbb::atomic<uint32_t> start_; \r
tbb::atomic<uint32_t> length_;\r
tbb::atomic<bool> loop_;\r
+ tbb::atomic<bool> eof_;\r
uint32_t frame_number_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<AVPacket>> buffer_;\r
start_ = start;\r
length_ = length;\r
loop_ = loop;\r
+ eof_ = false;\r
buffer_size_ = 0;\r
\r
if(start_ > 0) \r
{\r
frame_number_ = 0;\r
\r
- if(!loop_)\r
- return;\r
-\r
- queued_seek(start_);\r
- graph_->set_tag("seek"); \r
- CASPAR_LOG(trace) << print() << " Looping."; \r
+ if(loop_)\r
+ {\r
+ queued_seek(start_);\r
+ graph_->set_tag("seek"); \r
+ CASPAR_LOG(trace) << print() << " Looping."; \r
+ }\r
+ else\r
+ eof_ = true;\r
}\r
else\r
{ \r
+ eof_ = false;\r
+\r
THROW_ON_ERROR(ret, "av_read_frame", print());\r
\r
if(packet->stream_index == default_stream_index_)\r
graph_->set_value("buffer-count", (static_cast<double>(buffer_.size()+0.001)/MAX_BUFFER_COUNT)); \r
} \r
\r
- tick(); \r
+ if(!eof_)\r
+ tick(); \r
}\r
catch(...)\r
{\r
\r
input::input(const spl::shared_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, uint32_t start, uint32_t length) \r
: impl_(new impl(graph, filename, loop, start, length)){}\r
-bool input::eof() const {return !impl_->executor_.is_running();}\r
+bool input::eof() const {return impl_->eof_;}\r
bool input::try_pop(std::shared_ptr<AVPacket>& packet){return impl_->try_pop(packet);}\r
spl::shared_ptr<AVFormatContext> input::context(){return impl_->format_context_;}\r
void input::loop(bool value){impl_->loop_ = value;}\r