Воспроизведение видео на iOS с использованием OpenGL-ES - PullRequest
7 голосов
/ 01 октября 2011

Я пытаюсь воспроизвести видео (MP4 / H.263) на iOS, но получаю очень размытые результаты.Вот код для инициализации чтения ресурса:

mTextureHandle = [self createTexture:CGSizeMake(400,400)];

NSURL * url = [NSURL fileURLWithPath:file];    
mAsset = [[AVURLAsset alloc] initWithURL:url options:NULL];

NSArray * tracks = [mAsset tracksWithMediaType:AVMediaTypeVideo];

mTrack = [tracks objectAtIndex:0];

NSLog(@"Tracks: %i", [tracks count]);

NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary * settings = [[NSDictionary alloc] initWithObjectsAndKeys:value, key, nil];

mOutput = [[AVAssetReaderTrackOutput alloc] 
            initWithTrack:mTrack outputSettings:settings];


mReader = [[AVAssetReader alloc] initWithAsset:mAsset error:nil];
[mReader addOutput:mOutput];

Так много для читателя init, теперь фактическое текстурирование:

CMSampleBufferRef sampleBuffer = [mOutput copyNextSampleBuffer];    
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress( pixelBuffer, 0 );

glBindTexture(GL_TEXTURE_2D, mTextureHandle);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 600, 400, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress( pixelBuffer ));    
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );    
CFRelease(sampleBuffer);

Все работает хорошо ... за исключением визуализации изображениякак это;нарезанный и перекошенный?

enter image description here

Я даже пытался просмотреть предпочтительную матрицу преобразования AVAssetTrack, но безрезультатно, поскольку она всегда возвращает CGAffineTransformIdentity.

Примечание: если я переключу источник на камеру, изображение будет отображаться нормально.Я пропустил какой-то шаг декомпрессии?Разве это не должно обрабатываться читателем активов?

Спасибо!

Код: https://github.com/shaded-enmity/objcpp-opengl-video

1 Ответ

6 голосов
/ 01 октября 2011

Я думаю, что CMSampleBuffer использует заполнение из соображений производительности, поэтому вам нужно иметь правильную ширину для текстуры.

Попробуйте установить ширину текстуры с помощью: CVPixelBufferGetBytesPerRow (pixelBuffer) / 4 (если вашформат видео использует 4 байта на пиксель, измените, если другой)

...