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