SORU
3 Mart 2012, CUMARTESİ


İPhone OpenGL glReadPixels için daha hızlı bir alternatif 2.0 ES

Daha hızlı glReadPixels kullanarak daha çerçeve arabelleği erişmek için bir yolu var mı? Salt okunur çerçeve tamponunda küçük dikdörtgen işleme alanı verileri İŞLEMCİ daha fazla işlem gerekir. Performans bu işlemi tekrar tekrar yapmak zorunda çünkü bu önemlidir. Web arama ve Piksel Tampon Nesne ve glMapBuffer kullanarak gibi bazı yaklaşım buldum ama OpenGL ES 2.0 bunları desteklemiyor gibi görünüyor.

CEVAP
14 Mart 2012, ÇARŞAMBA


İOS 5.0, şimdi OpenGL ES veri kapmak için hızlı bir yoldur. Değil mi aşikar, ama ortaya çıkan doku önbellek desteği eklendi iOS 5.0 gelmez işe hızlı upload fotoğraf çerçeveleri için OpenGL ES, ama kullanılabilir tersine çevirmek için hızlı erişim için ham piksel içinde bir OpenGL ES doku.

Bu avantaj çerçeve bir nesne (BAĞLANDIĞINA) bağlı bir doku ile kullanarak OpenGL ES bir render için piksel kapmak için, doku doku önbellek temin ile alabilirsin. Bu BAĞLANDIĞINA içine sahne işleyebilir sonra, o sahne için BGRA piksel glReadPixels() kullanarak onları aşağı çekmeye gerek yok yani senin CVPixelBufferRef içinde olacak.

Bu çok, çok daha hızlı benim kriterler glReadPixels() kullanarak daha. İphone'umda, *6 4* diske kodlama için 720p video kareleri okuma darboğaz olduğunu buldum. Bir şey daha 8-9 FPS meydana gelen kodlama ile sınırlı kaldı. Yerine bu hızlı doku önbellek okuma sağlar bana kodlamak 720p video 20 FPS şimdi ve darboğaz vardır taşınmış piksel okuma için OpenGL ES işleme ve gerçek film kodlama parçaların boru hattı. Bir iPhone 4S, bu 1080p video yazmak için tam 30 FPS verir.

Benim uygulama bulunabilir içinde GPUİmageMovieWriter sınıf içinde benim açık kaynak GPUImage çerçeve, ama ilham vericiydi tarafından Dennis Muhlestein's article on the subject ve Apple'ın ChromaKey örnek uygulama (sadece yapılan mevcut WWDC 2011).

Benim AVAssetWriter yapılandırarak, bir giriş ekleme ve piksel tampon bir giriş yapılandırma başlıyorum. Aşağıdaki kodu piksel tampon girişini ayarlamak için kullanılır:

NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey,
                                                       [NSNumber numberWithInt:videoSize.width], kCVPixelBufferWidthKey,
                                                       [NSNumber numberWithInt:videoSize.height], kCVPixelBufferHeightKey,
                                                       nil];

assetWriterPixelBufferInput = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:assetWriterVideoInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];

Ben bir kez benim video çerçeveleri için aşağıdaki kodu kullanarak render olacağım BAĞLANDIĞINA ben yapılandırma:

if ([GPUImageOpenGLESContext supportsFastTextureUpload])
{
    CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, (__bridge void *)[[GPUImageOpenGLESContext sharedImageProcessingOpenGLESContext] context], NULL, &coreVideoTextureCache);
    if (err) 
    {
        NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d");
    }

    CVPixelBufferPoolCreatePixelBuffer (NULL, [assetWriterPixelBufferInput pixelBufferPool], &renderTarget);

    CVOpenGLESTextureRef renderTexture;
    CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, coreVideoTextureCache, renderTarget,
                                                  NULL, // texture attributes
                                                  GL_TEXTURE_2D,
                                                  GL_RGBA, // opengl format
                                                  (int)videoSize.width,
                                                  (int)videoSize.height,
                                                  GL_BGRA, // native iOS format
                                                  GL_UNSIGNED_BYTE,
                                                  0,
                                                  &renderTexture);

    glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture));
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0);
}

Bu havuzun varlık yazar benim giriş ile ilgili bir piksel tampon oluşturur ve ortakları ile bir doku çeker, ve benim BAĞLANDIĞINA için bir hedef olarak bu doku kullanır.

Bir kare render aldım mı, piksel tampon temel adresini ben kilidi

CVPixelBufferLockBaseAddress(pixel_buffer, 0);

ve sonra sadece kodlanacak varlık yazarım içine yem:

CMTime currentTime = CMTimeMakeWithSeconds([[NSDate date] timeIntervalSinceDate:startTime],120);

if(![assetWriterPixelBufferInput appendPixelBuffer:pixel_buffer withPresentationTime:currentTime]) 
{
    NSLog(@"Problem appending pixel buffer at time: %lld", currentTime.value);
} 
else 
{
//        NSLog(@"Recorded pixel buffer at time: %lld", currentTime.value);
}
CVPixelBufferUnlockBaseAddress(pixel_buffer, 0);

if (![GPUImageOpenGLESContext supportsFastTextureUpload])
{
    CVPixelBufferRelease(pixel_buffer);
}

Hiçbir noktada ben burada elle bir şey okuyorum unutmayın. Ayrıca, dokular herhangi bir renk swizzling burada yapmaya gerek yok yani doğal olarak AVAssetWriters video kodlama kullanmak için optimize edilmiş olan BGRA biçiminde. Ham BGRA pikselleri sadece film yapmak için kodlayıcı içine beslenir.

Bir AVAssetWriter bu kullanımı dışında, ham piksel çıkarılması için kullandım this answer bazı kod var. Ayrıca AVAssetWriter kullanırım piksel arabellek havuzu ile daha az olmasına rağmen glReadPixels() kullanarak göre uygulamada önemli bir hızlanma yaşanıyor.

Bunların hiçbiri video yakalama performansı için çok büyük bir destek sağlar, çünkü her yerde belgelenmiş, bir utanç.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • AndyMcMillinTV

    AndyMcMillin

    6 HAZİRAN 2007
  • huyked

    huyked

    28 Mart 2008
  • JeezyVEVO

    JeezyVEVO

    12 Mayıs 2009