23 #include <libavutil/imgutils.h>
24 #include <libswscale/swscale.h>
79 std::unordered_map<VideoFrame::IDType, std::unordered_map<VideoFrame::IDType, std::weak_ptr<VideoFrame>>>
97 , sourceDimensions(dimensions)
98 , sourceFrameKey(getFrameKey(dimensions.size(), pixFmt, sourceFrame->linesize[0]))
99 , freeSourceFrame(freeSourceFrame)
104 case AV_PIX_FMT_YUVJ420P: {
106 sourceFrame->color_range = AVCOL_RANGE_MPEG;
110 case AV_PIX_FMT_YUVJ411P: {
112 sourceFrame->color_range = AVCOL_RANGE_MPEG;
116 case AV_PIX_FMT_YUVJ422P: {
118 sourceFrame->color_range = AVCOL_RANGE_MPEG;
122 case AV_PIX_FMT_YUVJ444P: {
124 sourceFrame->color_range = AVCOL_RANGE_MPEG;
128 case AV_PIX_FMT_YUVJ440P: {
130 sourceFrame->color_range = AVCOL_RANGE_MPEG;
136 sourceFrame->color_range = AVCOL_RANGE_UNSPECIFIED;
144 :
VideoFrame(sourceID, sourceFrame, QRect{0, 0, sourceFrame->width, sourceFrame->height},
145 sourceFrame->format, freeSourceFrame)
169 sourceMutex.unlock();
215 std::shared_ptr<VideoFrame> ret{
this};
219 sourceMutex.unlock();
253 std::shared_ptr<VideoFrame> frame = frameIterator.second.lock();
256 frame->releaseFrame();
260 sourceMutex.unlock();
298 if (!frameSize.isValid()) {
303 const std::function<AVFrame*(AVFrame *
const)> converter = [](AVFrame*
const frame) {
308 AVFrame* nullPointer =
nullptr;
311 return toGenericObject(frameSize, pixelFormat, requireAligned, converter, nullPointer);
327 if (!frameSize.isValid()) {
332 const std::function<QImage(AVFrame *
const)> converter = [&](AVFrame*
const frame) {
333 return QImage{*(frame->data), frameSize.width(), frameSize.height(), *(frame->linesize),
334 QImage::Format_RGB888};
338 return toGenericObject(frameSize, AV_PIX_FMT_RGB24,
false, converter, QImage{});
354 if (!frameSize.isValid()) {
359 const std::function<
ToxYUVFrame(AVFrame *
const)> converter = [&](AVFrame*
const frame) {
360 ToxYUVFrame ret{
static_cast<std::uint16_t
>(frameSize.width()),
361 static_cast<std::uint16_t
>(frameSize.height()), frame->data[0],
362 frame->data[1], frame->data[2]};
423 const bool lineAligned)
425 , frameHeight(height)
426 , pixelFormat(pixFmt)
427 , linesizeAligned(lineAligned)
451 return !operator==(other);
464 std::hash<int> intHasher;
465 std::hash<bool> boolHasher;
491 return getFrameKey(frameSize, pixFmt, frameSize.width() == linesize);
503 const bool frameAligned)
505 return {frameSize.width(), frameSize.height(), pixFmt, frameAligned};
524 const bool requireAligned)
526 if (!requireAligned) {
558 const bool requireAligned)
560 AVFrame* ret = av_frame_alloc();
567 ret->width = dimensions.width();
568 ret->height = dimensions.height();
569 ret->format = pixelFormat;
580 if (!requireAligned || alreadyAligned) {
581 bufSize = av_image_alloc(ret->data, ret->linesize, dimensions.width(), dimensions.height(),
584 bufSize = av_image_alloc(ret->data, ret->linesize, dimensions.width(), dimensions.height(),
585 static_cast<AVPixelFormat
>(pixelFormat), 1);
594 int resizeAlgo =
sourceDimensions.width() > dimensions.width() ? SWS_BILINEAR : SWS_BICUBIC;
599 dimensions.height(),
static_cast<AVPixelFormat
>(pixelFormat), resizeAlgo,
600 nullptr,
nullptr,
nullptr);
603 av_freep(&ret->data[0]);
604 #if LIBAVCODEC_VERSION_INT < 3747941
613 sws_scale(swsCtx, source->data, source->linesize, 0,
sourceDimensions.height(), ret->data,
615 sws_freeContext(swsCtx);
651 av_freep(&frame->data[0]);
652 #if LIBAVCODEC_VERSION_INT < 3747941
653 av_frame_unref(frame);
655 av_frame_free(&frame);
678 AVFrame* frame = frameIterator.second;
683 av_freep(&frame->data[0]);
685 #if LIBAVCODEC_VERSION_INT < 3747941
686 av_frame_unref(frame);
688 av_frame_free(&frame);
690 av_freep(&frame->data[0]);
691 #if LIBAVCODEC_VERSION_INT < 3747941
692 av_frame_unref(frame);
694 av_frame_free(&frame);
721 template <
typename T>
723 const std::function<T(AVFrame*
const)>& objectConstructor,
734 AVFrame* frame =
retrieveAVFrame(dimensions,
static_cast<int>(pixelFormat), requireAligned);
737 T ret = objectConstructor(frame);
744 frame =
generateAVFrame(dimensions,
static_cast<int>(pixelFormat), requireAligned);
756 frame =
storeAVFrame(frame, dimensions,
static_cast<int>(pixelFormat));
758 T ret = objectConstructor(frame);
765 template QImage VideoFrame::toGenericObject<QImage>(
766 const QSize& dimensions,
const int pixelFormat,
const bool requireAligned,
767 const std::function<QImage(AVFrame*
const)> &objectConstructor,
const QImage& nullObject);
768 template ToxYUVFrame VideoFrame::toGenericObject<ToxYUVFrame>(
769 const QSize& dimensions,
const int pixelFormat,
const bool requireAligned,
781 return width > 0 && height > 0;
787 ToxYUVFrame::operator bool()
const