X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fffmpeg%2Fproducer%2Futil%2Futil.cpp;h=f06e3084655a42edf6813978c37df3149d0c3e01;hb=a20af5a695fe2786762e60f99f0633283514c628;hp=9eb61fb8916811f95d5dbf331d952bbae5ef35d7;hpb=9fd502f98e3542241211a2ec4fcbf88936731641;p=casparcg diff --git a/modules/ffmpeg/producer/util/util.cpp b/modules/ffmpeg/producer/util/util.cpp index 9eb61fb89..f06e30846 100644 --- a/modules/ffmpeg/producer/util/util.cpp +++ b/modules/ffmpeg/producer/util/util.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include @@ -289,6 +289,74 @@ spl::shared_ptr make_write_frame(const void* tag, const spl:: return spl::make_shared_ptr(write); } +spl::shared_ptr make_av_frame(caspar::core::data_frame& frame) +{ + std::array data = {}; + for(int n = 0; n < frame.get_pixel_format_desc().planes.size(); ++n) + data[n] = frame.image_data(n).begin(); + + return make_av_frame(data, frame.get_pixel_format_desc()); +} + +spl::shared_ptr make_av_frame(std::array data, const core::pixel_format_desc& pix_desc) +{ + spl::shared_ptr av_frame(avcodec_alloc_frame(), av_free); + avcodec_get_frame_defaults(av_frame.get()); + + auto planes = pix_desc.planes; + auto format = pix_desc.format.value(); + + av_frame->width = planes[0].width; + av_frame->height = planes[0].height; + for(int n = 0; n < planes.size(); ++n) + { + av_frame->data[n] = reinterpret_cast(data[n]); + av_frame->linesize[n] = planes[n].linesize; + } + switch(format) + { + case core::pixel_format::rgba: + av_frame->format = PIX_FMT_RGBA; + break; + case core::pixel_format::argb: + av_frame->format = PIX_FMT_ARGB; + break; + case core::pixel_format::bgra: + av_frame->format = PIX_FMT_BGRA; + break; + case core::pixel_format::abgr: + av_frame->format = PIX_FMT_ABGR; + break; + case core::pixel_format::gray: + av_frame->format = PIX_FMT_GRAY8; + break; + case core::pixel_format::ycbcr: + { + int y_w = planes[0].width; + int y_h = planes[0].height; + int c_w = planes[1].width; + int c_h = planes[1].height; + + if(c_h == y_h && c_w == y_w) + av_frame->format = PIX_FMT_YUV444P; + else if(c_h == y_h && c_w*2 == y_w) + av_frame->format = PIX_FMT_YUV422P; + else if(c_h == y_h && c_w*4 == y_w) + av_frame->format = PIX_FMT_YUV411P; + else if(c_h*2 == y_h && c_w*2 == y_w) + av_frame->format = PIX_FMT_YUV420P; + else if(c_h*2 == y_h && c_w*4 == y_w) + av_frame->format = PIX_FMT_YUV410P; + + break; + } + case core::pixel_format::ycbcra: + av_frame->format = PIX_FMT_YUVA420P; + break; + } + return av_frame; +} + bool is_sane_fps(AVRational time_base) { double fps = static_cast(time_base.den) / static_cast(time_base.num);