]> git.sesse.net Git - casparcg/blobdiff - modules/ffmpeg/producer/util/util.cpp
2.1.0: cpu/image_mixer: Added support for image conversion and blending. Only interla...
[casparcg] / modules / ffmpeg / producer / util / util.cpp
index 9eb61fb8916811f95d5dbf331d952bbae5ef35d7..f06e3084655a42edf6813978c37df3149d0c3e01 100644 (file)
@@ -34,7 +34,7 @@
 #include <core/frame/frame_transform.h>\r
 #include <core/frame/frame_factory.h>\r
 #include <core/producer/frame_producer.h>\r
-#include <core/mixer/gpu/write_frame.h>\r
+#include <core/frame/write_frame.h>\r
 \r
 #include <common/except.h>\r
 \r
@@ -289,6 +289,74 @@ spl::shared_ptr<core::write_frame> make_write_frame(const void* tag, const spl::
        return spl::make_shared_ptr(write);\r
 }\r
 \r
+spl::shared_ptr<AVFrame> make_av_frame(caspar::core::data_frame& frame)\r
+{\r
+       std::array<void*, 4> data = {};\r
+       for(int n = 0; n < frame.get_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
+}\r
+\r
+spl::shared_ptr<AVFrame> make_av_frame(std::array<void*, 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
+       \r
+       auto planes              = pix_desc.planes;\r
+       auto format              = pix_desc.format.value();\r
+\r
+       av_frame->width  = planes[0].width;\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->linesize[n] = planes[n].linesize;     \r
+       }\r
+       switch(format)\r
+       {\r
+       case core::pixel_format::rgba:\r
+               av_frame->format = PIX_FMT_RGBA; \r
+               break;\r
+       case core::pixel_format::argb:\r
+               av_frame->format = PIX_FMT_ARGB; \r
+               break;\r
+       case core::pixel_format::bgra:\r
+               av_frame->format = PIX_FMT_BGRA; \r
+               break;\r
+       case core::pixel_format::abgr:\r
+               av_frame->format = PIX_FMT_ABGR; \r
+               break;\r
+       case core::pixel_format::gray:\r
+               av_frame->format = PIX_FMT_GRAY8; \r
+               break;\r
+       case core::pixel_format::ycbcr:\r
+       {\r
+               int y_w = planes[0].width;\r
+               int y_h = planes[0].height;\r
+               int c_w = planes[1].width;\r
+               int c_h = planes[1].height;\r
+\r
+               if(c_h == y_h && c_w == y_w)\r
+                       av_frame->format = PIX_FMT_YUV444P;\r
+               else if(c_h == y_h && c_w*2 == y_w)\r
+                       av_frame->format = PIX_FMT_YUV422P;\r
+               else if(c_h == y_h && c_w*4 == y_w)\r
+                       av_frame->format = PIX_FMT_YUV411P;\r
+               else if(c_h*2 == y_h && c_w*2 == y_w)\r
+                       av_frame->format = PIX_FMT_YUV420P;\r
+               else if(c_h*2 == y_h && c_w*4 == y_w)\r
+                       av_frame->format = PIX_FMT_YUV410P;\r
+\r
+               break;\r
+       }\r
+       case core::pixel_format::ycbcra:\r
+               av_frame->format = PIX_FMT_YUVA420P;\r
+               break;\r
+       }\r
+       return av_frame;\r
+}\r
+\r
 bool is_sane_fps(AVRational time_base)\r
 {\r
        double fps = static_cast<double>(time_base.den) / static_cast<double>(time_base.num);\r