Warning, /graphics/digikam/core/libs/video/QtAVPlayer/qavhwdevice_videotoolbox.mm is written in an unsupported language. File is not indexed.

0001 /*********************************************************
0002  * Copyright (C) 2020, Val Doroshchuk <valbok@gmail.com> *
0003  *                                                       *
0004  * This file is part of QtAVPlayer.                      *
0005  * Free Qt Media Player based on FFmpeg.                 *
0006  *********************************************************/
0007 
0008 #include "qavhwdevice_videotoolbox_p.h"
0009 #include "qavvideobuffer_gpu_p.h"
0010 
0011 #import <CoreVideo/CoreVideo.h>
0012 #if defined(Q_OS_MACOS)
0013 #import <IOSurface/IOSurface.h>
0014 #else
0015 #import <IOSurface/IOSurfaceRef.h>
0016 #endif
0017 #import <Metal/Metal.h>
0018 
0019 #include <QList>
0020 #include <QVariant>
0021 #include <QDebug>
0022 
0023 QT_BEGIN_NAMESPACE
0024 
0025 class QAVHWDevice_VideoToolboxPrivate
0026 {
0027 public:
0028     id<MTLDevice> device = nullptr;
0029     CVPixelBufferRef pbuf = nullptr;
0030 };
0031 
0032 QAVHWDevice_VideoToolbox::QAVHWDevice_VideoToolbox()
0033     : d_ptr(new QAVHWDevice_VideoToolboxPrivate)
0034 {
0035 }
0036 
0037 QAVHWDevice_VideoToolbox::~QAVHWDevice_VideoToolbox()
0038 {
0039     Q_D(QAVHWDevice_VideoToolbox);
0040     CVPixelBufferRelease(d->pbuf);
0041     [d->device release];
0042 }
0043 
0044 AVPixelFormat QAVHWDevice_VideoToolbox::format() const
0045 {
0046     return AV_PIX_FMT_VIDEOTOOLBOX;
0047 }
0048 
0049 AVHWDeviceType QAVHWDevice_VideoToolbox::type() const
0050 {
0051     return AV_HWDEVICE_TYPE_VIDEOTOOLBOX;
0052 }
0053 
0054 class VideoBuffer_MTL : public QAVVideoBuffer_GPU
0055 {
0056 public:
0057     VideoBuffer_MTL(QAVHWDevice_VideoToolboxPrivate *hw, const QAVVideoFrame &frame)
0058         : QAVVideoBuffer_GPU(frame)
0059         , m_hw(hw)
0060     {
0061     }
0062 
0063     QAVVideoFrame::HandleType handleType() const override
0064     {
0065         return QAVVideoFrame::MTLTextureHandle;
0066     }
0067 
0068     QVariant handle(QRhi */*rhi*/) const override
0069     {
0070         CVPixelBufferRelease(m_hw->pbuf);
0071         m_hw->pbuf = (CVPixelBufferRef)frame().frame()->data[3];
0072         CVPixelBufferRetain(m_hw->pbuf);
0073         QList<QVariant> textures = { 0, 0 };
0074 
0075         if (!m_hw->pbuf)
0076             return textures;
0077 
0078         if (CVPixelBufferGetDataSize(m_hw->pbuf) <= 0)
0079             return textures;
0080 
0081         auto format = CVPixelBufferGetPixelFormatType(m_hw->pbuf);
0082         if (format != '420v') {
0083             qWarning() << "420v is supported only";
0084             return textures;
0085         }
0086 
0087         if (!m_hw->device)
0088             m_hw->device = MTLCreateSystemDefaultDevice();
0089 
0090         IOSurfaceRef surface = CVPixelBufferGetIOSurface(m_hw->pbuf);
0091         int planes = CVPixelBufferGetPlaneCount(m_hw->pbuf);
0092         for (int i = 0; i < planes; ++i) {
0093             int w = IOSurfaceGetWidthOfPlane(surface, i);
0094             int h = IOSurfaceGetHeightOfPlane(surface, i) ;
0095             MTLPixelFormat f = i ?  MTLPixelFormatRG8Unorm : MTLPixelFormatR8Unorm;
0096             MTLTextureDescriptor *desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:f width:w height:h mipmapped:NO];
0097 
0098             textures[i] = quint64([m_hw->device newTextureWithDescriptor:desc iosurface:surface plane:i]);
0099         }
0100 
0101         return textures;
0102     }
0103 
0104     QAVHWDevice_VideoToolboxPrivate *m_hw = nullptr;
0105 };
0106 
0107 QAVVideoBuffer *QAVHWDevice_VideoToolbox::videoBuffer(const QAVVideoFrame &frame) const
0108 {
0109     return new VideoBuffer_MTL(d_ptr.get(), frame);
0110 }
0111 
0112 QT_END_NAMESPACE