void MediaPlayerPrivateQuickTimeVisualContext::retrieveCurrentImage() { if (!m_visualContext) return; #if USE(ACCELERATED_COMPOSITING) if (m_qtVideoLayer) { QTPixelBuffer buffer = m_visualContext->imageForTime(0); if (!buffer.pixelBufferRef()) return; WKCACFLayer* layer = static_cast<WKCACFLayer*>(m_qtVideoLayer->platformLayer()); if (!buffer.lockBaseAddress()) { if (requiredDllsAvailable()) { if (!m_imageQueue) { m_imageQueue = new WKCAImageQueue(buffer.width(), buffer.height(), 30); m_imageQueue->setFlags(WKCAImageQueue::Fill, WKCAImageQueue::Fill); layer->setContents(m_imageQueue->get()); } // Debug QuickTime links against a non-Debug version of CoreFoundation, so the // CFDictionary attached to the CVPixelBuffer cannot be directly passed on into the // CAImageQueue without being converted to a non-Debug CFDictionary. Additionally, // old versions of QuickTime used a non-AAS CoreFoundation, so the types are not // interchangable even in the release case. RetainPtr<CFDictionaryRef> attachments(AdoptCF, QTCFDictionaryCreateCopyWithDataCallback(kCFAllocatorDefault, buffer.attachments(), &QTCFDictionaryCreateWithDataCallback)); CFTimeInterval imageTime = QTMovieVisualContext::currentHostTime(); m_imageQueue->collect(); uint64_t imageId = m_imageQueue->registerPixelBuffer(buffer.baseAddress(), buffer.dataSize(), buffer.bytesPerRow(), buffer.width(), buffer.height(), buffer.pixelFormatType(), attachments.get(), 0); if (m_imageQueue->insertImage(imageTime, WKCAImageQueue::Buffer, imageId, WKCAImageQueue::Opaque | WKCAImageQueue::Flush, &QTPixelBuffer::imageQueueReleaseCallback, buffer.pixelBufferRef())) { // Retain the buffer one extra time so it doesn't dissappear before CAImageQueue decides to release it: QTPixelBuffer::retainCallback(buffer.pixelBufferRef()); } } else { CGImageRef image = CreateCGImageFromPixelBuffer(buffer); layer->setContents(image); CGImageRelease(image); } buffer.unlockBaseAddress(); layer->rootLayer()->setNeedsRender(); } } else #endif m_player->repaint(); m_visualContext->task(); }
QTPixelBuffer QTDecompressionSession::decompress(QTPixelBuffer inBuffer) { if (!canDecompress(inBuffer)) return QTPixelBuffer(); inBuffer.lockBaseAddress(); ICMDecompressionSessionDecodeFrame(m_session, static_cast<UInt8*>(inBuffer.baseAddress()), inBuffer.dataSize(), 0, // frameOptions 0, // frameTime 0); // sourceFrameRefCon // Because we passed in 0 for frameTime, the above function // is synchronous, and the client callback will have been // called before the function returns, and m_latestFrame // will contain the newly decompressed frame. return m_latestFrame; }