/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
*\r
-* This file is part of CasparCG.\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
+* 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
+* 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
-#if defined(_MSC_VER)\r
-#pragma warning (disable : 4244)\r
-#endif\r
\r
#include "../../stdafx.h"\r
\r
\r
const std::wstring filename_;\r
tbb::atomic<bool> loop_;\r
- const size_t start_; \r
- const size_t length_;\r
+ const uint64_t start_; \r
+ const uint64_t length_;\r
size_t frame_number_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<AVPacket>> buffer_;\r
boost::condition_variable buffer_cond_;\r
boost::mutex buffer_mutex_;\r
\r
- tbb::atomic<size_t> nb_frames_;\r
- tbb::atomic<size_t> nb_loops_;\r
-\r
boost::thread thread_;\r
tbb::atomic<bool> is_running_;\r
tbb::atomic<bool> is_eof_;\r
\r
tbb::recursive_mutex mutex_;\r
\r
- explicit implementation(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, size_t start, size_t length) \r
+ explicit implementation(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, int64_t start, int64_t length) \r
: graph_(graph)\r
, format_context_(open_input(filename)) \r
, default_stream_index_(av_find_default_stream_index(format_context_.get()))\r
is_eof_ = false;\r
loop_ = loop;\r
buffer_size_ = 0;\r
- nb_frames_ = 0;\r
- nb_loops_ = 0;\r
-\r
- buffer_size_ = 0;\r
- nb_frames_ = 0;\r
- nb_loops_ = 0;\r
\r
if(start_ > 0) \r
do_seek(start_);\r
try\r
{\r
CASPAR_LOG(info) << print() << " Thread Started.";\r
- \r
- CASPAR_ASSERT(nb_frames_ < 1000);\r
\r
while(is_running_)\r
{\r
\r
if(is_eof(ret)) \r
{\r
- ++nb_loops_;\r
frame_number_ = 0;\r
is_eof_ = true;\r
\r
{\r
do_seek(start_);\r
graph_->add_tag("seek"); \r
- CASPAR_LOG(debug) << print() << " Looping."; \r
+ CASPAR_LOG(trace) << print() << " Looping."; \r
} \r
}\r
else\r
THROW_ON_ERROR(ret, "av_read_frame", print());\r
\r
if(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(packet.get()), print());\r
\r
}\r
}\r
\r
- auto time_base = format_context_->streams[default_stream_index_]->time_base;\r
- auto fixed_target = (target*time_base.den)/time_base.num;\r
- auto fixed_time_base = fix_time_base(time_base);\r
- fixed_target = (target * fixed_time_base.num) / fixed_time_base.den;\r
-\r
+ auto stream = format_context_->streams[default_stream_index_];\r
+ auto codec = stream->codec;\r
+ auto fixed_target = (target*stream->time_base.den*codec->time_base.num)/(stream->time_base.num*codec->time_base.den)*codec->ticks_per_frame;\r
+ \r
THROW_ON_ERROR2(avformat_seek_file(format_context_.get(), default_stream_index_, std::numeric_limits<int64_t>::min(), fixed_target, std::numeric_limits<int64_t>::max(), 0), print()); \r
\r
is_eof_ = false;\r
bool is_eof(int ret)\r
{\r
if(ret == AVERROR(EIO))\r
- CASPAR_LOG(trace) << print() << " Received EIO, assuming EOF. " << nb_frames_;\r
+ CASPAR_LOG(trace) << print() << " Received EIO, assuming EOF. ";\r
if(ret == AVERROR_EOF)\r
- CASPAR_LOG(debug) << print() << " Received EOF. " << nb_frames_;\r
+ CASPAR_LOG(trace) << print() << " Received EOF. ";\r
\r
return ret == AVERROR_EOF || ret == AVERROR(EIO) || frame_number_ >= length_; // av_read_frame doesn't always correctly return AVERROR_EOF;\r
}\r
}\r
};\r
\r
-input::input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, size_t start, size_t length) \r
+input::input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, int64_t start, int64_t length) \r
: impl_(new implementation(graph, filename, loop, start, length)){}\r
bool input::eof() const {return impl_->is_eof_;}\r
bool input::try_pop(std::shared_ptr<AVPacket>& packet){return impl_->try_pop(packet);}\r
safe_ptr<AVFormatContext> input::context(){return impl_->format_context_;}\r
-size_t input::nb_frames() const {return impl_->nb_frames_;}\r
-size_t input::nb_loops() const {return impl_->nb_loops_;}\r
void input::loop(bool value){impl_->loop_ = value;}\r
bool input::loop() const{return impl_->loop_;}\r
void input::seek(int64_t target){impl_->seek(target);}\r