2016-08-30 67 views
1

我一直在嘗試將.h264視頻解碼爲opengl,但我顯示的幀是黑色的。我沒有看到任何錯誤,並且如果我將CMSampleBufferRef中的幀導出到相機膠捲中,它們就沒有問題。iOS - 使用OpenGL ES 2.0進行視頻解碼

也許在openGL方面呢?但是當我顯示圖像而不是視頻時,它可以正常工作,所以不知道在哪裏看。

這裏是給init視頻解碼器的代碼:

- (void)initVideo { 

    glActiveTexture(GL_TEXTURE0); 
    glGenTextures(1, &_glTextureHook); 

    NSURL * url = [NSURL URLWithString:[self.videoMedia getFilePath]]; 
    self.videoAsset = [[AVURLAsset alloc] initWithURL:url options:NULL]; 

    dispatch_semaphore_t sema = dispatch_semaphore_create(0); 

    [self.videoAsset loadValuesAsynchronouslyForKeys:@[@"tracks"] completionHandler:^{ 

     self.videoTrack = [self.videoAsset tracksWithMediaType:AVMediaTypeVideo][0]; 

     NSString *key = (NSString *) kCVPixelBufferPixelFormatTypeKey; 
     NSNumber *value = @(kCVPixelFormatType_32BGRA); 
     NSDictionary *settings = @{key : value}; 

     self.outputVideoTrackOuput = [[AVAssetReaderTrackOutput alloc] 
             initWithTrack:self.videoTrack outputSettings:settings]; 

     self.assetReader = [[AVAssetReader alloc] initWithAsset:self.videoAsset error:nil]; 
     [self.assetReader addOutput:self.outputVideoTrackOuput]; 
     [self.assetReader startReading]; 

     dispatch_semaphore_signal(sema); 
    }]; 

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
} 

,並檢索所述OpenGL紋理的代碼中,視頻的每個幀:

- (void)play { 

    if (self.assetReader.status == AVAssetReaderStatusReading) { 
     CMSampleBufferRef sampleBuffer = [self.outputVideoTrackOuput copyNextSampleBuffer]; 
     if(sampleBuffer) { 
      CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

      if(pixelBuffer) { 
       CVPixelBufferLockBaseAddress(pixelBuffer, 0); 

       glBindTexture(GL_TEXTURE_2D, _glTextureHook); 
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(pixelBuffer)); 
       CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 
      } 

      CFRelease(sampleBuffer); 
     } 
    } 
} 

頂點着色器和片段是對於圖像和視頻(與圖像一起使用)相同。我看到的唯一區別是glTexImage2D,其中兩種格式都是GL_RGBA圖像。

我確信,視頻解碼器的_glTextureHook很好地發送到着色器管理器,上下文線程上激活等

這是片段着色器的代碼(這是很基本的,同爲頂點着色器):

precision lowp float; 

uniform sampler2D Texture; 

varying vec4 DestinationColor; 
varying vec2 TexCoordOut; 

void main() { 
    gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); 
} 
+0

你成功成功確實發揮了openGL下的IOS視頻?如果是,你會介意分享代碼嗎?感謝您的提前! – loki

+0

感謝您的代碼,我一直在尋找這樣幾天的具體例子。像@loki問,你有什麼成功?您是否在任何時候都涉及音頻? –

回答

0

我只是錯過創建紋理之後的那些行:

glBindTexture(GL_TEXTURE_2D, _glTextureHook); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);