Warning, file /libraries/phonon-vlc/src/video/videodataoutput.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 Copyright (C) 2010-2021 Harald Sitter <sitter@kde.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Lesser General Public 0006 License as published by the Free Software Foundation; either 0007 version 2.1 of the License, or (at your option) version 3, or any 0008 later version accepted by the membership of KDE e.V. (or its 0009 successor approved by the membership of KDE e.V.), Nokia Corporation 0010 (or its successors, if any) and the KDE Free Qt Foundation, which shall 0011 act as a proxy defined in Section 6 of version 3 of the license. 0012 0013 This library is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 Lesser General Public License for more details. 0017 0018 You should have received a copy of the GNU Lesser General Public 0019 License along with this library. If not, see <http://www.gnu.org/licenses/>. 0020 */ 0021 0022 #include "videodataoutput.h" 0023 0024 #include <phonon/medianode.h> 0025 #include <phonon/audiooutput.h> 0026 #include <phonon/experimental/abstractvideodataoutput.h> 0027 0028 #include <QMetaObject> 0029 0030 #include "utils/debug.h" 0031 #include "media.h" 0032 #include "mediaobject.h" 0033 0034 using namespace Phonon::Experimental; 0035 0036 namespace Phonon 0037 { 0038 namespace VLC 0039 { 0040 0041 VideoDataOutput::VideoDataOutput(QObject *parent) 0042 : QObject(parent) 0043 , m_frontend(0) 0044 { 0045 } 0046 0047 VideoDataOutput::~VideoDataOutput() 0048 { 0049 } 0050 0051 void VideoDataOutput::handleConnectToMediaObject(MediaObject *mediaObject) 0052 { 0053 Q_UNUSED(mediaObject); 0054 setCallbacks(m_player); 0055 } 0056 0057 void VideoDataOutput::handleDisconnectFromMediaObject(MediaObject *mediaObject) 0058 { 0059 Q_UNUSED(mediaObject); 0060 unsetCallbacks(m_player); 0061 } 0062 0063 void VideoDataOutput::handleAddToMedia(Media *media) 0064 { 0065 media->addOption(":video"); 0066 } 0067 0068 Experimental::AbstractVideoDataOutput *VideoDataOutput::frontendObject() const 0069 { 0070 return m_frontend; 0071 } 0072 0073 void VideoDataOutput::setFrontendObject(Experimental::AbstractVideoDataOutput *frontend) 0074 { 0075 m_frontend = frontend; 0076 } 0077 0078 void *VideoDataOutput::lockCallback(void **planes) 0079 { 0080 m_mutex.lock(); 0081 DEBUG_BLOCK; 0082 planes[0] = reinterpret_cast<void *>(m_frame.data0.data()); 0083 planes[1] = reinterpret_cast<void *>(m_frame.data1.data()); 0084 planes[2] = reinterpret_cast<void *>(m_frame.data2.data()); 0085 return 0; 0086 } 0087 0088 void VideoDataOutput::unlockCallback(void *picture, void *const*planes) 0089 { 0090 Q_UNUSED(picture); 0091 Q_UNUSED(planes); 0092 DEBUG_BLOCK; 0093 0094 // For some reason VLC yields BGR24, so we swap it to RGB 0095 if (m_frame.format == Experimental::VideoFrame2::Format_RGB888) { 0096 uchar *data = (uchar *) m_frame.data0.data(); 0097 uchar tmp; 0098 for (int i = 0; i < m_frame.data0.size(); i += 3) { 0099 tmp = data[i]; 0100 data[i] = data[i+2]; 0101 data[i+2] = tmp; 0102 } 0103 } 0104 0105 if (m_frontend) 0106 m_frontend->frameReady(m_frame); 0107 0108 m_mutex.unlock(); 0109 } 0110 0111 void VideoDataOutput::displayCallback(void *picture) 0112 { 0113 Q_UNUSED(picture); 0114 DEBUG_BLOCK; 0115 // We send the frame while unlocking as we could loose syncing otherwise. 0116 // With VDO the consumer is expected to ensure syncness while not blocking 0117 // unlock for long periods of time. Good luck with that... -.- 0118 } 0119 0120 static VideoFrame2::Format fourccToFormat(const char *fourcc) 0121 { 0122 if (qstrcmp(fourcc, "RV24")) 0123 return VideoFrame2::Format_RGB888; 0124 else if (qstrcmp(fourcc, "RV32")) 0125 return VideoFrame2::Format_RGB32; 0126 else if (qstrcmp(fourcc, "YV12")) 0127 return VideoFrame2::Format_YV12; 0128 else if (qstrcmp(fourcc, "YUY2")) 0129 return VideoFrame2::Format_YUY2; 0130 else 0131 return VideoFrame2::Format_Invalid; 0132 } 0133 0134 static uint32_t setFormat(VideoFrame2::Format format, char **chroma) 0135 { 0136 switch (format) { 0137 case VideoFrame2::Format_Invalid: 0138 *chroma = nullptr; 0139 return 0; 0140 case VideoFrame2::Format_RGB32: 0141 qstrcpy(*chroma, "RV32"); 0142 return VLC_CODEC_RGB32; 0143 case VideoFrame2::Format_RGB888: 0144 qstrcpy(*chroma, "RV24"); 0145 return VLC_CODEC_RGB24; 0146 case VideoFrame2::Format_YV12: 0147 qstrcpy(*chroma, "YV12"); 0148 return VLC_CODEC_YV12; 0149 case VideoFrame2::Format_YUY2: 0150 qstrcpy(*chroma, "YUY2"); 0151 return VLC_CODEC_YUYV; 0152 } 0153 return 0; 0154 } 0155 0156 unsigned VideoDataOutput::formatCallback(char *chroma, 0157 unsigned *width, unsigned *height, 0158 unsigned *pitches, unsigned *lines) 0159 { 0160 DEBUG_BLOCK; 0161 0162 m_frame.width = *width; 0163 m_frame.height = *height; 0164 0165 uint32_t fourcc = 0; 0166 0167 QSet<VideoFrame2::Format> allowedFormats = m_frontend->allowedFormats(); 0168 VideoFrame2::Format suggestedFormat = fourccToFormat(chroma); 0169 if (suggestedFormat != VideoFrame2::Format_Invalid 0170 && allowedFormats.contains(suggestedFormat)) { // Use suggested 0171 fourcc = setFormat(suggestedFormat, &chroma); 0172 m_frame.format = suggestedFormat; 0173 } else { // Pick first and use that 0174 foreach (const VideoFrame2::Format &format, allowedFormats) { 0175 fourcc = setFormat(format, &chroma); 0176 if (fourcc > 0) { 0177 m_frame.format = format; 0178 break; 0179 } 0180 } 0181 } 0182 0183 Q_ASSERT(fourcc > 0); 0184 0185 unsigned int bufferSize = setPitchAndLines(fourcc, *width, *height, pitches, lines); 0186 0187 m_frame.data0.resize(pitches[0] * lines[0]); 0188 m_frame.data1.resize(pitches[1] * lines[1]); 0189 m_frame.data2.resize(pitches[2] * lines[0]); 0190 0191 return bufferSize; 0192 } 0193 0194 void VideoDataOutput::formatCleanUpCallback() 0195 { 0196 DEBUG_BLOCK; 0197 } 0198 0199 } // namespace VLC 0200 } // namespace Phonon