7#include <opencv2/core.hpp>
8#include <opencv2/highgui.hpp>
9#include <opencv2/imgcodecs.hpp>
10#include <opencv2/imgproc.hpp>
13#include <libavutil/imgutils.h>
14#include <libswscale/swscale.h>
21 AVPixelFormat pixelFormat;
23 struct swsContextDeleter {
24 void operator()(SwsContext *s)
const noexcept { sws_freeContext(s); }
26 std::unique_ptr<SwsContext, swsContextDeleter> swsContext;
27 std::vector<uint8_t> data;
30 AVPixelFormat outputPixelFormat = AV_PIX_FMT_BGR24;
31 int outputWidth = 1920;
32 int outputHeight = 1080;
34 void virtualInit(AVCodecContext *decoderContext)
override {
35 spdlog::info(
"intitializing VideoFrameSink");
37 width = decoderContext->width;
38 height = decoderContext->height;
39 pixelFormat = decoderContext->pix_fmt;
42 av_image_fill_linesizes(linesize, outputPixelFormat, outputWidth);
44 char error[AV_ERROR_MAX_STRING_SIZE];
45 av_make_error_string(error, AV_ERROR_MAX_STRING_SIZE, res);
46 throw std::runtime_error(
47 "Error getting linesize in VideoFrameSink: " +
51 res = av_image_get_buffer_size(outputPixelFormat, outputWidth,
54 char error[AV_ERROR_MAX_STRING_SIZE];
55 av_make_error_string(error, AV_ERROR_MAX_STRING_SIZE, res);
56 throw std::runtime_error(
57 "Error getting plane size in VideoFrameSink: " +
60 data.resize(
static_cast<std::size_t
>(res));
62 swsContext = {sws_getCachedContext(
nullptr, width, height, pixelFormat,
63 outputWidth, outputHeight,
64 outputPixelFormat, 0,
nullptr,
67 spdlog::info(
"intitialized VideoFrameSink");
70 void virtualOutputFrame(AVFrame *frame)
override {
71 if (frame->width != width || frame->height != height ||
72 frame->format != pixelFormat) {
73 throw std::runtime_error(
74 "Cannot support changing input format in VideoFrameSink");
77 uint8_t *dataPointer = data.data();
78 int res = sws_scale(swsContext.get(), frame->data, frame->linesize, 0,
79 height, &dataPointer, linesize);
81 char error[AV_ERROR_MAX_STRING_SIZE];
82 av_make_error_string(error, AV_ERROR_MAX_STRING_SIZE, res);
83 throw std::runtime_error(
84 "Error converting image in VideoFrameSink: " +
89 void getDataWithoutLock(std::vector<uint8_t> &dataCopy)
override {
90 dataCopy.resize(this->data.size());
91 std::copy(this->data.begin(), this->data.end(), dataCopy.begin());
97 AVMediaType
getType()
const override {
return AVMEDIA_TYPE_VIDEO; }
Definition: FFmpegFrameSink.h:23
Definition: VideoFrameSink.h:17
int getHeight() const
Definition: VideoFrameSink.h:100
AVMediaType getType() const override
Definition: VideoFrameSink.h:97
VideoFrameSink()
Definition: VideoFrameSink.h:95
int getWidth() const
Definition: VideoFrameSink.h:99