我的OS X应用程序会生成大量电影缩略图。我试验了很多,以便在缩略图生成和快速显示之间做出正确的权衡。当前设置非常有效,包括将原始ARGB CVPixelBufferData写入磁盘,稍后将它们转换为图像以显示它们(缩略图非常小,最大100x100)。我遇到的问题是我以这种方式生成的图像需要很长时间才能渲染。
这是我用来将缓冲区数据转换回图像的代码:
CGImageRef videoImage = NULL;
CVPixelBufferRef pixelBufferOut = NULL;
NSData *imageData = [NSData dataWithContentsOfURL:imgURL];
if (imageData) {
size_t width = [self.bufferAttributes[(__bridge NSString *)kCVPixelBufferWidthKey] unsignedIntegerValue];
size_t height = [self.bufferAttributes[(__bridge NSString *)kCVPixelBufferHeightKey] unsignedIntegerValue];
//size_t bytesPerRow = [self.bufferAttributes[(__bridge NSString *)kCVPixelBufferBytesPerRowAlignmentKey] unsignedIntegerValue];
OSType pixelFormatType = [self.bufferAttributes[(__bridge NSString *)kCVPixelBufferPixelFormatTypeKey] unsignedIntValue];
CVReturn ret = CVPixelBufferCreate(NULL, width, height, pixelFormatType, (__bridge CFDictionaryRef _Nullable)(self.bufferAttributes), &pixelBufferOut);
if (ret == kCVReturnSuccess) {
CVPixelBufferLockBaseAddress(pixelBufferOut, 0);
void *baseAddress = CVPixelBufferGetBaseAddress(pixelBufferOut);
memcpy(baseAddress, imageData.bytes, imageData.length);
CIImage *ciImage = [CIImage imageWithCVImageBuffer:pixelBufferOut];
CIContext *temporaryContext = [CIContext contextWithOptions:nil];
videoImage = [temporaryContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(pixelBufferOut), CVPixelBufferGetHeight(pixelBufferOut))];
CVPixelBufferUnlockBaseAddress(pixelBufferOut, 0);
} else {
//CFRelease(imgDataCF);
}
}
if (videoImage) {
images[count] = CFBridgingRelease(videoImage);
} else {
}
CVPixelBufferRelease(pixelBufferOut);
渲染这些图像要比加载png的数据慢得多。我试图复制相关的仪器回溯:
Running Time Self (ms) Symbol Name
5851.0ms 56.7% 0.0 -[_NSScrollingConcurrentMainThreadSynchronizer _synchronize:completionHandler:]
5437.0ms 52.7% 0.0 CA::Transaction::commit()
5428.0ms 52.6% 1.0 CA::Context::commit_transaction(CA::Transaction*)
5297.0ms 51.4% 0.0 CA::Layer::prepare_commit(CA::Transaction*)
5289.0ms 51.3% 0.0 CA::Render::prepare_image(CGImage*, CGColorSpace*, unsigned int, double)
5289.0ms 51.3% 0.0 CA::Render::copy_image(CGImage*, CGColorSpace*, unsigned int, double)
5288.0ms 51.3% 0.0 CA::Render::create_image(CGImage*, CGColorSpace*, unsigned int)
5278.0ms 51.2% 0.0 CA::Render::(anonymous namespace)::create_image_by_rendering(CGImage*, CGColorSpace*, unsigned int)
5199.0ms 50.4% 0.0 CGContextDrawImage
5197.0ms 50.4% 0.0 ripc_DrawImage
5175.0ms 50.2% 1.0 ripc_AcquireImage
5174.0ms 50.2% 0.0 CGSImageDataLock
5174.0ms 50.2% 4.0 img_data_lock
5048.0ms 48.9% 0.0 img_blocks_extent
5048.0ms 48.9% 0.0 img_blocks_create
5048.0ms 48.9% 0.0 FECIImageImageProvider::copyImageBlockSet(void*, CGImageProvider*, CGRect, CGSize)
5048.0ms 48.9% 0.0 FECIImageImageProvider::copyImageBlockSet_(CGImageProvider*, CGRect, CGSize)
5024.0ms 48.7% 0.0 FECIImageImageProvider::ensureData(CGColorSpace*, CGRect, CGSize, fe_bitmap_struct*, CGPoint*)
4670.0ms 45.3% 1.0 -[FEImage getBitmap:withContext:origin:transform:colorSpace:alreadyClampedToAlpha:]
4668.0ms 45.3% 0.0 -[FEImage(Internal) _renderWithContext:bounds:transform:colorSpace:format:premultiplied:setupCallback:finishCallback:callbackData:alreadyClampedToAlpha:]
4663.0ms 45.2% 1.0 FETreeContext::renderImage(FEImage*, CGRect, FEShape const*, CGAffineTransform, CGColorSpace*, FEFormat, bool, void (*)(FEContext*, void*, FEFormat), void (*)(FEContext*, void*), void*, signed char)
4571.0ms 44.3% 0.0 FETreeContext::renderImage_(FEImage*, CGRect, FEShape const*, CGAffineTransform, CGColorSpace*, FEFormat, bool, void (*)(FEContext*, void*, FEFormat), void (*)(FEContext*, void*), void*, bool)
4545.0ms 44.1% 1.0 FETreeContext::renderTree(FETreeNode*, FEShape const&, void (*)(FEContext*, void*, FEFormat), void (*)(FEContext*, void*), void*)
4532.0ms 43.9% 0.0 FETreeNode::render(FETreeContext*, FEShape const&, void (*)(FEContext*, void*, FEFormat), void (*)(FEContext*, void*), void*)
4529.0ms 43.9% 2.0 FETreeNode::render_(FETreeContext*, FEShape const*, void (*)(FEContext*, void*, FEFormat), void (*)(FEContext*, void*), void*)
4522.0ms 43.8% 3.0 FEApplyTreeNode::render2(FETreeContext*, FEShape const*, void (*)(FEContext*, void*, FEFormat), void (*)(FEContext*, void*), void*)
2659.0ms 25.8% 1.0 FEApplyTreeNode::render1(FETreeContext*, FEShape const&, fe_kernel_target_struct*, int, float*, FETreeTexture*)
1252.0ms 12.1% 0.0 glBegin_Exec
1252.0ms 12.1% 0.0 gleDoDrawDispatchCore
1250.0ms 12.1% 1.0 gldUpdateDispatch
645.0ms 6.2% 0.0 g575_LoadAndOptimizePipelinePrograms(GLDContextRec*, unsigned int*)
645.0ms 6.2% 0.0 gpusLoadCurrentPipelinePrograms
645.0ms 6.2% 1.0 glrUpdateCtxSysVertexProgram
623.0ms 6.0% 0.0 GHAL3D::CPrivateStateProcessor::CreateVertexShader(GHAL3D::CVertexShader*)
580.0ms 5.6% 0.0 GHAL3D::CGen6StateProcessorCache::CreateVertexShader(GHAL3D::HANDLE_TYPE)
579.0ms 5.6% 1.0 GHAL3D::CStateCache<GHAL3D::SGen6VertexShaderKernelProgramCacheKey, GHAL3D::CGen6VertexShaderKernelProgramCacheData>::PreAllocateData(GHAL3D::SGen6VertexShaderKernelProgramCacheKey const&, GHAL3D::HANDLE_TYPE&)
578.0ms 5.6% 0.0 GHAL3D::CGen6VertexShaderKernelProgramCacheData::Create(GHAL3D::CStateProcessorCache*, GHAL3D::SGen6VertexShaderKernelProgramCacheKey const&, GHAL3D::CGen6VertexShaderKernelProgramCacheData*&)
578.0ms 5.6% 0.0 GHAL3D::CGen6VertexShaderKernelProgramCacheData::Initialize()
577.0ms 5.6% 2.0 GHAL3D::CGen6VertexShaderKernelProgram::Create(void const*, PLATFORM_STR, GHAL3D::CVertexShader const*, S3DKernelHardwareCapabilities const&, GHAL3D::CGen6VertexShaderKernelProgram*&)
574.0ms 5.5% 0.0 GHAL3D::CGen6VertexShaderKernelProgram::Initialize()
567.0ms 5.5% 0.0 GHAL3D::CGen6VertexShaderKernelProgram::Build()
499.0ms 4.8% 0.0 GHAL3D::CGen6VertexShaderKernelProgram::Compile(GHAL3D::SKernelCompilerControls const&)
393.0ms 3.8% 3.0 GHAL3D::CGen4KernelFunctionList::VirtualRegistersToRegisters(GHAL3D::CGen4EURegisterAllocator*, bool, GHAL3D::CGen4ShaderDecomposer*, GHAL3D::CGen4ShaderSymbolTable*, S3DKernelHardwareCapabilities const&, unsigned int, unsigned int, unsigned int, bool&, unsigned int&, unsigned int&, unsigned int&, GHAL3D::SHADER_TYPE)
123.0ms 1.1% 2.0 GHAL3D::CGen4KernelFunctionList::ComputeLivenessSets(unsigned int, bool, bool)
105.0ms 1.0% 1.0 GHAL3D::CGen4LIRControlFlowGraph::ComputeLivenessSets(iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, unsigned int, bool, bool, bool, bool, bool&)
96.0ms 0.9% 77.0 GHAL3D::CGen4LIRBasicBlock::ComputeLivenessSets(iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, iSTD::CBitSet<GHAL3D::CAllocator>&, bool, bool, bool, bool, bool, GHAL3D::CGen4LIRControlFlowGraph*, bool&, bool&)
6.0ms 0.0% 2.0 iSTD::CBitSet<GHAL3D::CAllocator>::Create(unsigned int)
3.0ms 0.0% 0.0 malloc
3.0ms 0.0% 0.0 malloc_zone_malloc
3.0ms 0.0% 2.0 szone_malloc_should_clear
1.0ms 0.0% 1.0 tiny_malloc_from_free_list
关于如何改善渲染时间的任何想法?