<ClInclude Include="producer\audio\audio_decoder.h" />\r
<ClInclude Include="producer\ffmpeg_producer.h" />\r
<ClInclude Include="producer\input.h" />\r
- <ClInclude Include="producer\packet.h" />\r
<ClInclude Include="producer\video\video_decoder.h" />\r
<ClInclude Include="StdAfx.h" />\r
<ClInclude Include="tbb_avcodec.h" />\r
<ClInclude Include="StdAfx.h" />\r
<ClInclude Include="ffmpeg.h" />\r
<ClInclude Include="ffmpeg_error.h" />\r
- <ClInclude Include="producer\packet.h">\r
- <Filter>producer</Filter>\r
- </ClInclude>\r
<ClInclude Include="tbb_avcodec.h" />\r
</ItemGroup>\r
</Project>
\ No newline at end of file
}\r
}\r
\r
- std::vector<std::vector<short>> execute(packet&& audio_packet)\r
+ std::vector<std::vector<short>> execute(std::shared_ptr<AVPacket>&& audio_packet)\r
{ \r
std::vector<std::vector<short>> result;\r
\r
- switch(audio_packet.type)\r
- {\r
- case flush_packet:\r
- avcodec_flush_buffers(&codec_context_);\r
- break;\r
- case data_packet:\r
- auto s = current_chunk_.size();\r
- current_chunk_.resize(s + 4*format_desc_.audio_sample_rate*2+FF_INPUT_BUFFER_PADDING_SIZE/2);\r
+ if(!audio_packet)\r
+ return result;\r
+\r
+ auto s = current_chunk_.size();\r
+ current_chunk_.resize(s + 4*format_desc_.audio_sample_rate*2+FF_INPUT_BUFFER_PADDING_SIZE/2);\r
\r
- int written_bytes = (current_chunk_.size() - s)*2 - FF_INPUT_BUFFER_PADDING_SIZE;\r
- const int errn = avcodec_decode_audio3(&codec_context_, ¤t_chunk_[s], &written_bytes, audio_packet.av_packet.get());\r
- if(errn < 0)\r
- { \r
- BOOST_THROW_EXCEPTION(\r
- invalid_operation() <<\r
- boost::errinfo_api_function("avcodec_decode_audio2") <<\r
- boost::errinfo_errno(AVUNERROR(errn)));\r
- }\r
+ int written_bytes = (current_chunk_.size() - s)*2 - FF_INPUT_BUFFER_PADDING_SIZE;\r
+ const int errn = avcodec_decode_audio3(&codec_context_, ¤t_chunk_[s], &written_bytes, audio_packet.get());\r
+ if(errn < 0)\r
+ { \r
+ BOOST_THROW_EXCEPTION(\r
+ invalid_operation() <<\r
+ boost::errinfo_api_function("avcodec_decode_audio2") <<\r
+ boost::errinfo_errno(AVUNERROR(errn)));\r
+ }\r
\r
- current_chunk_.resize(s + written_bytes/2);\r
+ current_chunk_.resize(s + written_bytes/2);\r
\r
- const auto last = current_chunk_.end() - current_chunk_.size() % format_desc_.audio_samples_per_frame;\r
+ const auto last = current_chunk_.end() - current_chunk_.size() % format_desc_.audio_samples_per_frame;\r
\r
- for(auto it = current_chunk_.begin(); it != last; it += format_desc_.audio_samples_per_frame) \r
- result.push_back(std::vector<short>(it, it + format_desc_.audio_samples_per_frame)); \r
+ for(auto it = current_chunk_.begin(); it != last; it += format_desc_.audio_samples_per_frame) \r
+ result.push_back(std::vector<short>(it, it + format_desc_.audio_samples_per_frame)); \r
\r
- current_chunk_.erase(current_chunk_.begin(), last);\r
- }\r
+ current_chunk_.erase(current_chunk_.begin(), last);\r
\r
return result;\r
}\r
};\r
\r
audio_decoder::audio_decoder(AVCodecContext& codec_context, const core::video_format_desc& format_desc) : impl_(new implementation(codec_context, format_desc)){}\r
-std::vector<std::vector<short>> audio_decoder::execute(packet&& audio_packet){return impl_->execute(std::move(audio_packet));}\r
+std::vector<std::vector<short>> audio_decoder::execute(std::shared_ptr<AVPacket>&& audio_packet){return impl_->execute(std::move(audio_packet));}\r
}
\ No newline at end of file
*/\r
#pragma once\r
\r
-#include "../packet.h"\r
-\r
#include <core/video_format.h>\r
\r
#include <tbb/cache_aligned_allocator.h>\r
{\r
public:\r
explicit audio_decoder(AVCodecContext& codec_context, const core::video_format_desc& format_desc);\r
- std::vector<std::vector<short>> execute(packet&& audio_packet);\r
+ std::vector<std::vector<short>> execute(std::shared_ptr<AVPacket>&& audio_packet);\r
private:\r
struct implementation;\r
std::shared_ptr<implementation> impl_;\r
, loop_(loop) \r
, graph_(diagnostics::create_graph(narrow(print())))\r
, frame_factory_(frame_factory) \r
- , input_(safe_ptr<diagnostics::graph>(graph_), filename_, loop_, start, length)\r
+ , input_(safe_ptr<diagnostics::graph>(graph_), filename_, loop_, start)\r
{\r
graph_->add_guide("frame-time", 0.5);\r
graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
return try_merge_audio_and_video(); \r
}\r
\r
- void try_decode_video_packet(packet&& video_packet)\r
+ void try_decode_video_packet(std::shared_ptr<AVPacket>&& video_packet)\r
{\r
if(!video_decoder_)\r
return;\r
}\r
}\r
\r
- void try_decode_audio_packet(packet&& audio_packet)\r
+ void try_decode_audio_packet(std::shared_ptr<AVPacket>&& audio_packet)\r
{\r
if(!audio_decoder_)\r
return;\r
int video_s_index_;\r
int audio_s_index_;\r
const int start_;\r
- const int length_;\r
- int eof_count_;\r
\r
- tbb::concurrent_bounded_queue<packet> video_packet_buffer_;\r
- tbb::concurrent_bounded_queue<packet> audio_packet_buffer_;\r
+ tbb::concurrent_bounded_queue<std::shared_ptr<AVPacket>> video_packet_buffer_;\r
+ tbb::concurrent_bounded_queue<std::shared_ptr<AVPacket>> audio_packet_buffer_;\r
\r
std::exception_ptr exception_;\r
executor executor_;\r
public:\r
- explicit implementation(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, int start, int length) \r
+ explicit implementation(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, int start) \r
: graph_(graph)\r
, loop_(loop)\r
, video_s_index_(-1)\r
, filename_(filename)\r
, executor_(print())\r
, start_(std::max(start, 0))\r
- , length_(length)\r
- , eof_count_(length)\r
{ \r
graph_->set_color("input-buffer", diagnostics::color(1.0f, 1.0f, 0.0f));\r
graph_->set_color("seek", diagnostics::color(0.5f, 1.0f, 0.5f)); \r
stop();\r
}\r
\r
- packet get_video_packet()\r
+ std::shared_ptr<AVPacket> get_video_packet()\r
{\r
return get_packet(video_packet_buffer_);\r
}\r
\r
- packet get_audio_packet()\r
+ std::shared_ptr<AVPacket> get_audio_packet()\r
{\r
return get_packet(audio_packet_buffer_);\r
}\r
if(loop_)\r
{\r
seek_frame(start_, AVSEEK_FLAG_BACKWARD);\r
- eof_count_ += length_; // AVCodecContext.frame_number is not reset. Increase the target frame_number.\r
graph_->add_tag("seek"); \r
CASPAR_LOG(info) << print() << " Received EOF. Looping."; \r
} \r
boost::errinfo_api_function("seek_frame") <<\r
boost::errinfo_errno(AVUNERROR(errn)));\r
}\r
-\r
- // Notify decoders to flush buffers.\r
- video_packet_buffer_.try_push(flush_packet); \r
- audio_packet_buffer_.try_push(flush_packet);\r
} \r
\r
bool is_eof(int errn)\r
{\r
- if(length_ != -1)\r
- return get_default_context()->frame_number > eof_count_; \r
-\r
if(errn == AVERROR(EIO))\r
CASPAR_LOG(warning) << print() << " Received EIO, assuming EOF";\r
\r
return errn == AVERROR_EOF || errn == AVERROR(EIO); // av_read_frame doesn't always correctly return AVERROR_EOF;\r
}\r
\r
- void push_packet(tbb::concurrent_bounded_queue<packet>& buffer, const std::shared_ptr<AVPacket>& read_packet)\r
+ void push_packet(tbb::concurrent_bounded_queue<std::shared_ptr<AVPacket>>& buffer, const std::shared_ptr<AVPacket>& read_packet)\r
{\r
av_dup_packet(read_packet.get());\r
- buffer.push(packet(read_packet)); \r
+ buffer.push(read_packet); \r
}\r
\r
- packet get_packet(tbb::concurrent_bounded_queue<packet>& buffer)\r
+ std::shared_ptr<AVPacket> get_packet(tbb::concurrent_bounded_queue<std::shared_ptr<AVPacket>>& buffer)\r
{\r
- packet packet;\r
+ std::shared_ptr<AVPacket> packet;\r
buffer.try_pop(packet);\r
return packet;\r
}\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, length)){}\r
+input::input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, int start) \r
+ : impl_(new implementation(graph, filename, loop, start)){}\r
const std::shared_ptr<AVCodecContext>& input::get_video_codec_context() const{return impl_->video_codec_context_;}\r
const std::shared_ptr<AVCodecContext>& input::get_audio_codec_context() const{return impl_->audio_codex_context_;}\r
bool input::has_packet() const{return impl_->has_packet();}\r
bool input::is_running() const {return impl_->executor_.is_running();}\r
-packet input::get_video_packet(){return impl_->get_video_packet();}\r
-packet input::get_audio_packet(){return impl_->get_audio_packet();}\r
+std::shared_ptr<AVPacket> input::get_video_packet(){return impl_->get_video_packet();}\r
+std::shared_ptr<AVPacket> input::get_audio_packet(){return impl_->get_audio_packet();}\r
double input::fps() const { return impl_->fps(); }\r
}
\ No newline at end of file
\r
#include <common/diagnostics/graph.h>\r
\r
-#include "packet.h"\r
-\r
#include <memory>\r
#include <string>\r
\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, int start);\r
const std::shared_ptr<AVCodecContext>& get_video_codec_context() const;\r
const std::shared_ptr<AVCodecContext>& get_audio_codec_context() const;\r
\r
- packet get_video_packet();\r
- packet get_audio_packet();\r
+ std::shared_ptr<AVPacket> get_video_packet();\r
+ std::shared_ptr<AVPacket> get_audio_packet();\r
\r
bool has_packet() const;\r
bool is_running() const;\r
+++ /dev/null
-#pragma once\r
-\r
-#include <vector>\r
-\r
-#include <memory>\r
-\r
-namespace caspar {\r
- \r
-enum packet_type\r
-{\r
- data_packet,\r
- flush_packet,\r
- empty_packet\r
-};\r
-\r
-struct packet\r
-{\r
- packet_type type;\r
- std::shared_ptr<AVPacket> av_packet;\r
- \r
- packet(packet_type t = empty_packet) \r
- : type(t){}\r
-\r
- packet(const std::shared_ptr<AVPacket>& av_packet) \r
- : type(data_packet)\r
- , av_packet(av_packet){}\r
-};\r
-\r
-}
\ No newline at end of file
}\r
}\r
\r
- std::vector<safe_ptr<core::write_frame>> execute(packet&& video_packet)\r
+ std::vector<safe_ptr<core::write_frame>> execute(std::shared_ptr<AVPacket>&& video_packet)\r
{ \r
std::vector<safe_ptr<core::write_frame>> result;\r
\r
- switch(video_packet.type)\r
- {\r
- case flush_packet:\r
- avcodec_flush_buffers(&codec_context_);\r
- break;\r
- case data_packet: \r
- safe_ptr<AVFrame> decoded_frame(avcodec_alloc_frame(), av_free);\r
-\r
- int frame_finished = 0;\r
- const int errn = avcodec_decode_video2(&codec_context_, decoded_frame.get(), &frame_finished, video_packet.av_packet.get());\r
- \r
- if(errn < 0)\r
- {\r
- BOOST_THROW_EXCEPTION(\r
- invalid_operation() <<\r
- msg_info(av_error_str(errn)) <<\r
- boost::errinfo_api_function("avcodec_decode_video") <<\r
- boost::errinfo_errno(AVUNERROR(errn)));\r
- }\r
+ if(!video_packet)\r
+ return result;\r
+ \r
+ safe_ptr<AVFrame> decoded_frame(avcodec_alloc_frame(), av_free);\r
+\r
+ int frame_finished = 0;\r
+ const int errn = avcodec_decode_video2(&codec_context_, decoded_frame.get(), &frame_finished, video_packet.get());\r
\r
- if(frame_finished != 0) \r
- result.push_back(make_write_frame(decoded_frame));\r
+ if(errn < 0)\r
+ {\r
+ BOOST_THROW_EXCEPTION(\r
+ invalid_operation() <<\r
+ msg_info(av_error_str(errn)) <<\r
+ boost::errinfo_api_function("avcodec_decode_video") <<\r
+ boost::errinfo_errno(AVUNERROR(errn)));\r
}\r
+ \r
+ if(frame_finished != 0) \r
+ result.push_back(make_write_frame(decoded_frame));\r
\r
return result;\r
}\r
};\r
\r
video_decoder::video_decoder(AVCodecContext& codec_context, const safe_ptr<core::frame_factory>& frame_factory) : impl_(new implementation(codec_context, frame_factory)){}\r
-std::vector<safe_ptr<core::write_frame>> video_decoder::execute(packet&& video_packet){return impl_->execute(std::move(video_packet));}\r
+std::vector<safe_ptr<core::write_frame>> video_decoder::execute(std::shared_ptr<AVPacket>&& video_packet){return impl_->execute(std::move(video_packet));}\r
\r
}
\ No newline at end of file
*/\r
#pragma once\r
\r
-#include "../packet.h"\r
-\r
#include <common/memory/safe_ptr.h>\r
\r
struct AVCodecContext;\r
{\r
public:\r
explicit video_decoder(AVCodecContext& codec_context, const safe_ptr<core::frame_factory>& frame_factory);\r
- std::vector<safe_ptr<core::write_frame>> execute(packet&& video_packet); \r
+ std::vector<safe_ptr<core::write_frame>> execute(std::shared_ptr<AVPacket>&& video_packet); \r
private:\r
struct implementation;\r
safe_ptr<implementation> impl_;\r