\r
#include <core/frame/frame_transform.h>\r
#include <core/frame/frame_factory.h>\r
+#include <core/frame/frame.h>\r
#include <core/producer/frame_producer.h>\r
-#include <core/frame/write_frame.h>\r
\r
#include <common/except.h>\r
\r
}\r
}\r
\r
-core::pixel_format_desc get_pixel_format_desc(PixelFormat pix_fmt, int width, int height)\r
+core::pixel_format_desc pixel_format_desc(PixelFormat pix_fmt, int width, int height)\r
{\r
// Get linesizes\r
AVPicture dummy_pict; \r
}\r
}\r
\r
-spl::shared_ptr<core::write_frame> make_write_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags)\r
+core::mutable_frame make_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags)\r
{ \r
static tbb::concurrent_unordered_map<int, tbb::concurrent_queue<std::shared_ptr<SwsContext>>> sws_contexts_;\r
\r
\r
const auto width = decoded_frame->width;\r
const auto height = decoded_frame->height;\r
- auto desc = get_pixel_format_desc(static_cast<PixelFormat>(decoded_frame->format), width, height);\r
+ auto desc = pixel_format_desc(static_cast<PixelFormat>(decoded_frame->format), width, height);\r
\r
if(flags & core::frame_producer::flags::alpha_only)\r
- desc = get_pixel_format_desc(static_cast<PixelFormat>(make_alpha_format(decoded_frame->format)), width, height);\r
-\r
- std::shared_ptr<core::write_frame> write;\r
-\r
+ desc = pixel_format_desc(static_cast<PixelFormat>(make_alpha_format(decoded_frame->format)), width, height);\r
+ \r
if(desc.format == core::pixel_format::invalid)\r
{\r
auto pix_fmt = static_cast<PixelFormat>(decoded_frame->format);\r
else if(pix_fmt == PIX_FMT_YUV444P10)\r
target_pix_fmt = PIX_FMT_YUV444P;\r
\r
- auto target_desc = get_pixel_format_desc(target_pix_fmt, width, height);\r
+ auto target_desc = pixel_format_desc(target_pix_fmt, width, height);\r
\r
- write = frame_factory->create_frame(tag, target_desc);\r
+ auto write = frame_factory->create_frame(tag, target_desc, fps, get_mode(*decoded_frame));\r
\r
std::shared_ptr<SwsContext> sws_context;\r
\r
avcodec_get_frame_defaults(av_frame.get()); \r
if(target_pix_fmt == PIX_FMT_BGRA)\r
{\r
- auto size = avpicture_fill(reinterpret_cast<AVPicture*>(av_frame.get()), write->image_data(0).begin(), PIX_FMT_BGRA, width, height);\r
- CASPAR_VERIFY(size == write->image_data(0).size()); \r
+ auto size = avpicture_fill(reinterpret_cast<AVPicture*>(av_frame.get()), write.image_data(0).begin(), PIX_FMT_BGRA, width, height);\r
+ CASPAR_VERIFY(size == write.image_data(0).size()); \r
}\r
else\r
{\r
av_frame->height = height;\r
for(int n = 0; n < target_desc.planes.size(); ++n)\r
{\r
- av_frame->data[n] = write->image_data(n).begin();\r
+ av_frame->data[n] = write.image_data(n).begin();\r
av_frame->linesize[n] = target_desc.planes[n].linesize;\r
}\r
}\r
\r
sws_scale(sws_context.get(), decoded_frame->data, decoded_frame->linesize, 0, height, av_frame->data, av_frame->linesize); \r
pool.push(sws_context); \r
+\r
+ return std::move(write);\r
}\r
else\r
{\r
- write = frame_factory->create_frame(tag, desc);\r
-\r
+ auto write = frame_factory->create_frame(tag, desc, fps, get_mode(*decoded_frame));\r
+ \r
for(int n = 0; n < static_cast<int>(desc.planes.size()); ++n)\r
{\r
auto plane = desc.planes[n];\r
- auto result = write->image_data(n).begin();\r
+ auto result = write.image_data(n).begin();\r
auto decoded = decoded_frame->data[n];\r
auto decoded_linesize = decoded_frame->linesize[n];\r
\r
CASPAR_ASSERT(decoded);\r
- CASPAR_ASSERT(write->image_data(n).begin());\r
+ CASPAR_ASSERT(write.image_data(n).begin());\r
\r
// Copy line by line since ffmpeg sometimes pads each line.\r
tbb::affinity_partitioner ap;\r
A_memcpy(result + y*plane.linesize, decoded + y*decoded_linesize, plane.linesize);\r
}, ap);\r
}\r
- }\r
-\r
- if(decoded_frame->height == 480) // NTSC DV\r
- {\r
- write->get_frame_transform().fill_translation[1] += 2.0/static_cast<double>(frame_factory->get_video_format_desc().height);\r
- write->get_frame_transform().fill_scale[1] = 1.0 - 6.0*1.0/static_cast<double>(frame_factory->get_video_format_desc().height);\r
- }\r
\r
- // Fix field-order if needed\r
- if(get_mode(*decoded_frame) == core::field_mode::lower && frame_factory->get_video_format_desc().field_mode == core::field_mode::upper)\r
- write->get_frame_transform().fill_translation[1] += 1.0/static_cast<double>(frame_factory->get_video_format_desc().height);\r
- else if(get_mode(*decoded_frame) == core::field_mode::upper && frame_factory->get_video_format_desc().field_mode == core::field_mode::lower)\r
- write->get_frame_transform().fill_translation[1] -= 1.0/static_cast<double>(frame_factory->get_video_format_desc().height);\r
-\r
- return spl::make_shared_ptr(write);\r
+ return std::move(write);\r
+ }\r
}\r
\r
-spl::shared_ptr<AVFrame> make_av_frame(caspar::core::data_frame& frame)\r
+spl::shared_ptr<AVFrame> make_av_frame(core::mutable_frame& frame)\r
{\r
- std::array<void*, 4> data = {};\r
- for(int n = 0; n < frame.get_pixel_format_desc().planes.size(); ++n)\r
+ std::array<uint8_t*, 4> data = {};\r
+ for(int n = 0; n < frame.pixel_format_desc().planes.size(); ++n)\r
data[n] = frame.image_data(n).begin();\r
\r
- return make_av_frame(data, frame.get_pixel_format_desc());\r
+ return make_av_frame(data, frame.pixel_format_desc());\r
}\r
\r
-spl::shared_ptr<AVFrame> make_av_frame(std::array<void*, 4> data, const core::pixel_format_desc& pix_desc)\r
+spl::shared_ptr<AVFrame> make_av_frame(std::array<uint8_t*, 4> data, const core::pixel_format_desc& pix_desc)\r
{\r
spl::shared_ptr<AVFrame> av_frame(avcodec_alloc_frame(), av_free); \r
avcodec_get_frame_defaults(av_frame.get());\r
av_frame->height = planes[0].height;\r
for(int n = 0; n < planes.size(); ++n) \r
{\r
- av_frame->data[n] = reinterpret_cast<uint8_t*>(data[n]);\r
+ av_frame->data[n] = data[n];\r
av_frame->linesize[n] = planes[n].linesize; \r
}\r
switch(format)\r