1 /* 2 * Copyright (C) 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 #include "config.h" 26 27 #include "QTPixelBuffer.h" 28 29 #include <CFNumber.h> 30 #include <CFString.h> 31 #include <CGColorSpace.h> 32 #include <CGImage.h> 33 #include <CVPixelBuffer.h> 34 #include <QuickDraw.h> 35 #include <memory.h> 36 37 static OSStatus SetNumberValue(CFMutableDictionaryRef inDict, CFStringRef inKey, SInt32 inValue) 38 { 39 CFNumberRef number; 40 41 number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue); 42 if (!number) 43 return coreFoundationUnknownErr; 44 45 CFDictionarySetValue(inDict, inKey, number); 46 CFRelease(number); 47 48 return noErr; 49 } 50 51 CFDictionaryRef QTPixelBuffer::createPixelBufferAttributesDictionary(QTPixelBuffer::Type contextType) 52 { 53 static const CFStringRef kDirect3DCompatibilityKey = CFSTR("Direct3DCompatibility"); 54 55 CFMutableDictionaryRef pixelBufferAttributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 56 if (contextType == QTPixelBuffer::ConfigureForCAImageQueue) { 57 // Ask for D3D compatible pixel buffers so no further work is needed. 58 CFDictionarySetValue(pixelBufferAttributes, kDirect3DCompatibilityKey, kCFBooleanTrue); 59 } else { 60 // Use the k32BGRAPixelFormat, as QuartzCore will be able to use the pixels directly, 61 // without needing an additional copy or rendering pass. 62 SetNumberValue(pixelBufferAttributes, kCVPixelBufferPixelFormatTypeKey, k32BGRAPixelFormat); 63 64 // Set kCVPixelBufferBytesPerRowAlignmentKey to 16 to ensure that each row of pixels 65 // starts at a 16 byte aligned address for most efficient data reading. 66 SetNumberValue(pixelBufferAttributes, kCVPixelBufferBytesPerRowAlignmentKey, 16); 67 CFDictionarySetValue(pixelBufferAttributes, kCVPixelBufferCGImageCompatibilityKey, kCFBooleanTrue); 68 } 69 return pixelBufferAttributes; 70 } 71 72 QTPixelBuffer::QTPixelBuffer() 73 : m_pixelBuffer(0) 74 { 75 } 76 77 QTPixelBuffer::QTPixelBuffer(const QTPixelBuffer& p) 78 : m_pixelBuffer(p.m_pixelBuffer) 79 { 80 CVPixelBufferRetain(m_pixelBuffer); 81 } 82 83 QTPixelBuffer::QTPixelBuffer(CVPixelBufferRef ref) 84 : m_pixelBuffer(ref) 85 { 86 CVPixelBufferRetain(m_pixelBuffer); 87 } 88 89 QTPixelBuffer::~QTPixelBuffer() 90 { 91 clear(); 92 } 93 94 QTPixelBuffer& QTPixelBuffer::operator=(const QTPixelBuffer& p) 95 { 96 set(p.m_pixelBuffer); 97 return *this; 98 } 99 100 void QTPixelBuffer::set(CVPixelBufferRef ref) 101 { 102 CVPixelBufferRetain(ref); 103 CVPixelBufferRelease(m_pixelBuffer); 104 m_pixelBuffer = ref; 105 } 106 107 CVPixelBufferRef QTPixelBuffer::pixelBufferRef() 108 { 109 return m_pixelBuffer; 110 } 111 112 void QTPixelBuffer::adopt(CVPixelBufferRef ref) 113 { 114 if (ref == m_pixelBuffer) 115 return; 116 CVPixelBufferRelease(m_pixelBuffer); 117 m_pixelBuffer = ref; 118 } 119 120 void QTPixelBuffer::clear() 121 { 122 CVPixelBufferRelease(m_pixelBuffer); 123 m_pixelBuffer = 0; 124 } 125 126 CVReturn QTPixelBuffer::lockBaseAddress() 127 { 128 return CVPixelBufferLockBaseAddress(m_pixelBuffer, 0); 129 } 130 131 CVReturn QTPixelBuffer::unlockBaseAddress() 132 { 133 return CVPixelBufferUnlockBaseAddress(m_pixelBuffer, 0); 134 } 135 136 void* QTPixelBuffer::baseAddress() 137 { 138 return CVPixelBufferGetBaseAddress(m_pixelBuffer); 139 } 140 141 size_t QTPixelBuffer::width() const 142 { 143 return CVPixelBufferGetWidth(m_pixelBuffer); 144 } 145 146 size_t QTPixelBuffer::height() const 147 { 148 return CVPixelBufferGetHeight(m_pixelBuffer); 149 } 150 151 unsigned long QTPixelBuffer::pixelFormatType() const 152 { 153 return CVPixelBufferGetPixelFormatType(m_pixelBuffer); 154 } 155 156 bool QTPixelBuffer::pixelFormatIs32ARGB() const 157 { 158 return CVPixelBufferGetPixelFormatType(m_pixelBuffer) == k32ARGBPixelFormat; 159 } 160 161 bool QTPixelBuffer::pixelFormatIs32BGRA() const 162 { 163 return CVPixelBufferGetPixelFormatType(m_pixelBuffer) == k32BGRAPixelFormat; 164 } 165 166 size_t QTPixelBuffer::bytesPerRow() const 167 { 168 return CVPixelBufferGetBytesPerRow(m_pixelBuffer); 169 } 170 171 size_t QTPixelBuffer::dataSize() const 172 { 173 return CVPixelBufferGetDataSize(m_pixelBuffer); 174 } 175 176 bool QTPixelBuffer::isPlanar() const 177 { 178 return CVPixelBufferIsPlanar(m_pixelBuffer); 179 } 180 181 size_t QTPixelBuffer::planeCount() const 182 { 183 return CVPixelBufferGetPlaneCount(m_pixelBuffer); 184 } 185 186 size_t QTPixelBuffer::widthOfPlane(size_t plane) const 187 { 188 return CVPixelBufferGetWidthOfPlane(m_pixelBuffer, plane); 189 } 190 191 size_t QTPixelBuffer::heightOfPlane(size_t plane) const 192 { 193 return CVPixelBufferGetHeightOfPlane(m_pixelBuffer, plane); 194 } 195 196 void* QTPixelBuffer::baseAddressOfPlane(size_t plane) const 197 { 198 return CVPixelBufferGetBaseAddressOfPlane(m_pixelBuffer, plane); 199 } 200 201 size_t QTPixelBuffer::bytesPerRowOfPlane(size_t plane) const 202 { 203 return CVPixelBufferGetBytesPerRowOfPlane(m_pixelBuffer, plane); 204 } 205 206 void QTPixelBuffer::getExtendedPixels(size_t* left, size_t* right, size_t* top, size_t* bottom) const 207 { 208 return CVPixelBufferGetExtendedPixels(m_pixelBuffer, left, right, top, bottom); 209 } 210 211 CFDictionaryRef QTPixelBuffer::attachments() const 212 { 213 return CVBufferGetAttachments(m_pixelBuffer, kCVAttachmentMode_ShouldPropagate); 214 } 215 216 void QTPixelBuffer::retainCallback(void* refcon) 217 { 218 CVPixelBufferRetain(static_cast<CVPixelBufferRef>(refcon)); 219 } 220 221 void QTPixelBuffer::releaseCallback(void* refcon) 222 { 223 CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon)); 224 } 225 226 void QTPixelBuffer::imageQueueReleaseCallback(unsigned int type, uint64_t id, void* refcon) 227 { 228 CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon)); 229 } 230 231 void QTPixelBuffer::dataProviderReleaseBytePointerCallback(void* refcon, const void* pointer) 232 { 233 CVPixelBufferUnlockBaseAddress(static_cast<CVPixelBufferRef>(refcon), 0); 234 } 235 236 const void* QTPixelBuffer::dataProviderGetBytePointerCallback(void* refcon) 237 { 238 CVPixelBufferLockBaseAddress(static_cast<CVPixelBufferRef>(refcon), 0); 239 return CVPixelBufferGetBaseAddress(static_cast<CVPixelBufferRef>(refcon)); 240 } 241 242 size_t QTPixelBuffer::dataProviderGetBytesAtPositionCallback(void* refcon, void* buffer, size_t position, size_t count) 243 { 244 char* data = (char*)CVPixelBufferGetBaseAddress(static_cast<CVPixelBufferRef>(refcon)); 245 size_t size = CVPixelBufferGetDataSize(static_cast<CVPixelBufferRef>(refcon)); 246 if (size - position < count) 247 count = size - position; 248 249 memcpy(buffer, data+position, count); 250 return count; 251 } 252 253 void QTPixelBuffer::dataProviderReleaseInfoCallback(void* refcon) 254 { 255 CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon)); 256 } 257