* Author: Robert Nagy, ronag89@gmail.com
*/
-#include "../../stdafx.h"
+#include "../../StdAfx.h"
#include "video_decoder.h"
#include <core/frame/frame_transform.h>
#include <core/frame/frame_factory.h>
-#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/filesystem.hpp>
+#include <tbb/atomic.h>
+
#include <queue>
#if defined(_MSC_VER)
{
core::monitor::subject monitor_subject_;
input* input_;
- int index_;
+ int index_ = -1;
const spl::shared_ptr<AVCodecContext> codec_context_;
std::queue<spl::shared_ptr<AVPacket>> packets_;
const int width_;
const int height_;
- bool is_progressive_;
- uint32_t file_frame_number_;
- double fps_;
+ tbb::atomic<bool> is_progressive_;
+ tbb::atomic<uint32_t> file_frame_number_;
+ boost::rational<int> framerate_;
std::shared_ptr<AVPacket> current_packet_;
public:
- explicit impl(input& in)
+ explicit impl(input& in, bool single_threaded)
: input_(&in)
- , codec_context_(open_codec(input_->context(), AVMEDIA_TYPE_VIDEO, index_))
+ , codec_context_(open_codec(input_->context(), AVMEDIA_TYPE_VIDEO, index_, single_threaded))
, stream_(input_->context().streams[index_])
, nb_frames_(static_cast<uint32_t>(stream_->nb_frames))
, width_(codec_context_->width)
, height_(codec_context_->height)
- , file_frame_number_(0)
- , fps_(read_fps(input_->context(), 0.0))
+ , framerate_(read_framerate(input_->context(), 0))
{
+ is_progressive_ = false;
+ file_frame_number_ = 0;
}
std::shared_ptr<AVFrame> poll()
std::shared_ptr<AVFrame> frame;
- if(!current_packet_)
- {
- avcodec_flush_buffers(codec_context_.get());
- }
- else if(!current_packet_->data)
+ if (!current_packet_->data)
{
if(codec_context_->codec->capabilities & CODEC_CAP_DELAY)
frame = decode(*current_packet_);
- if(!frame)
+ if (!frame)
+ {
+ file_frame_number_ = static_cast<uint32_t>(current_packet_->pos);
+ avcodec_flush_buffers(codec_context_.get());
current_packet_.reset();
+ frame = flush();
+ }
}
else
{
current_packet_.reset();
}
- return frame ? frame : poll();
+ return frame;
}
std::shared_ptr<AVFrame> decode(AVPacket& pkt)
if(got_frame == 0)
return nullptr;
- auto stream_time_base = stream_->time_base;
- auto packet_frame_number = static_cast<uint32_t>((static_cast<double>(pkt.pts * stream_time_base.num)/stream_time_base.den)*fps_);
-
- file_frame_number_ = packet_frame_number;
+ ++file_frame_number_;
is_progressive_ = !frame->interlaced_frame;
uint32_t nb_frames() const
{
- return std::max(nb_frames_, file_frame_number_);
+ return std::max(nb_frames_, static_cast<uint32_t>(file_frame_number_));
}
std::wstring print() const
}
};
-video_decoder::video_decoder(input& in) : impl_(new impl(in)){}
+video_decoder::video_decoder(input& in, bool single_threaded) : impl_(new impl(in, single_threaded)){}
video_decoder::video_decoder(video_decoder&& other) : impl_(std::move(other.impl_)){}
video_decoder& video_decoder::operator=(video_decoder&& other){impl_ = std::move(other.impl_); return *this;}
std::shared_ptr<AVFrame> video_decoder::operator()(){return impl_->poll();}
int video_decoder::height() const{return impl_->height_;}
uint32_t video_decoder::nb_frames() const{return impl_->nb_frames();}
uint32_t video_decoder::file_frame_number() const{return impl_->file_frame_number_;}
+boost::rational<int> video_decoder::framerate() const { return impl_->framerate_; }
bool video_decoder::is_progressive() const{return impl_->is_progressive_;}
std::wstring video_decoder::print() const{return impl_->print();}
core::monitor::subject& video_decoder::monitor_output() { return impl_->monitor_subject_; }
-}}
\ No newline at end of file
+}}