std::wstring path = filename + L"." + *ext;\r
bool loop = boost::find(params, L"LOOP") != params.end();\r
\r
- int start = -1;\r
- int length = -1;\r
+ size_t start = 0;\r
+ size_t length = std::numeric_limits<size_t>::max();\r
\r
auto seek_it = std::find(params.begin(), params.end(), L"SEEK");\r
if(seek_it != params.end())\r
{\r
if(++seek_it != params.end())\r
- start = boost::lexical_cast<int>(*seek_it);\r
+ start = boost::lexical_cast<size_t>(*seek_it);\r
+ }\r
+ \r
+ auto length_it = std::find(params.begin(), params.end(), L"LENGTH");\r
+ if(length_it != params.end())\r
+ {\r
+ if(++length_it != params.end())\r
+ length = boost::lexical_cast<size_t>(*length_it);\r
}\r
\r
std::wstring filter = L"";\r
\r
const std::wstring filename_;\r
const bool loop_;\r
- const int start_; \r
+ const size_t start_; \r
+ const size_t length_;\r
+ size_t frame_number_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<AVPacket>> buffer_;\r
tbb::atomic<size_t> buffer_size_;\r
tbb::atomic<size_t> nb_loops_;\r
\r
public:\r
- explicit implementation(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, int start) \r
+ explicit implementation(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, size_t start, size_t length) \r
: graph_(graph)\r
, loop_(loop)\r
, filename_(filename)\r
- , start_(std::max(start, 0))\r
+ , start_(start)\r
+ , length_(length)\r
+ , frame_number_(0)\r
{ \r
is_running_ = true;\r
nb_frames_ = 0;\r
\r
default_stream_index_ = THROW_ON_ERROR2(av_find_default_stream_index(format_context_.get()), print());\r
\r
- if(start_ != 0) \r
+ if(start_ > 0) \r
seek_frame(start_);\r
\r
for(int n = 0; n < 16 && !full(); ++n)\r
if(is_eof(ret)) \r
{\r
++nb_loops_;\r
+ frame_number_ = 0;\r
\r
if(loop_)\r
{\r
{ \r
THROW_ON_ERROR(ret, print(), "av_read_frame");\r
\r
- if(read_packet->stream_index == default_stream_index_ && nb_loops_ == 0)\r
- ++nb_frames_;\r
+ if(read_packet->stream_index == default_stream_index_)\r
+ {\r
+ if(nb_loops_ == 0)\r
+ ++nb_frames_;\r
+ ++frame_number_;\r
+ }\r
\r
THROW_ON_ERROR2(av_dup_packet(read_packet.get()), print());\r
\r
if(ret == AVERROR_EOF)\r
CASPAR_LOG(trace) << print() << " Received EOF. " << nb_frames_;\r
\r
- return ret == AVERROR_EOF || ret == AVERROR(EIO); // av_read_frame doesn't always correctly return AVERROR_EOF;\r
+ return ret == AVERROR_EOF || ret == AVERROR(EIO) || frame_number_ >= length_; // av_read_frame doesn't always correctly return AVERROR_EOF;\r
}\r
\r
std::wstring print() const\r
}\r
};\r
\r
-input::input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, int start, int length) \r
- : impl_(new implementation(graph, filename, loop, start)){}\r
+input::input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, size_t start, size_t length) \r
+ : impl_(new implementation(graph, filename, loop, start, length)){}\r
bool input::eof() const {return !impl_->is_running_;}\r
bool input::try_pop(std::shared_ptr<AVPacket>& packet){return impl_->try_pop(packet);}\r
safe_ptr<AVFormatContext> input::context(){return make_safe(impl_->format_context_);}\r
class input : boost::noncopyable\r
{\r
public:\r
- explicit input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, int start, int length);\r
+ explicit input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, size_t start = 0, size_t length = std::numeric_limits<size_t>::max());\r
\r
bool try_pop(std::shared_ptr<AVPacket>& packet);\r
bool eof() const;\r