AVFoundation:从mov文件中读取RAW单帧(v210,未压缩的10位4:2:2)

时间:2012-02-27 18:08:43

标签: objective-c avfoundation

为了从未压缩的v210(像素格式为kCVPixelFormatType_422YpCbCr10)中提取RAW图像缓冲区,我尝试按照这个伟大的帖子: Reading samples via AVAssetReader

在的问题是,当它涉及到的 startReading 的我的 assetReader 我得到一个的 AVAssetReaderStatusFailed (与设定的NSMutableDictionary对象kCVPixelBufferPixelFormatTypeKey为输出设置为kCVPixelFormatType_422YpCbCr10)。如果我将 outputSettings 保留为nil,则会解析每个帧,但CMSampleBufferRef缓冲区为空。

我尝试了很多像素格式,例如

  • kCVPixelFormatType_422YpCbCr10
  • kCVPixelFormatType_422YpCbCr8
  • kCVPixelFormatType_422YpCbCr16
  • kCVPixelFormatType_422YpCbCr8_yuvs
  • kCVPixelFormatType_422YpCbCr8FullRange
  • kCVPixelFormatType_422YpCbCr_4A_8BiPlanar

但它们都不起作用。

我做错了什么?

欢迎任何评论......

这是我的代码:

/* construct an AVAssetReader based on an file based URL */
NSError *error=[[NSError alloc]init];
NSString *filePathString=[[NSString alloc]
                          initWithString:@"/Users/johann/Raw12bit.mov"];

NSURL *movieUrl=[[NSURL alloc] initFileURLWithPath:filePathString];
AVURLAsset *movieAsset=[[AVURLAsset alloc] initWithURL:movieUrl options:nil]; 

/* determine image dimensions of images stored in movie asset */
CGSize size=[movieAsset naturalSize];  
NSLog(@"movie asset natual size: size.width=%f size.height=%f", 
      size.width, size.height);

/* allocate assetReader */
AVAssetReader *assetReader=[[AVAssetReader alloc] initWithAsset:movieAsset
                                                          error:&error];

/* get video track(s) from movie asset */
NSArray *videoTracks=[movieAsset tracksWithMediaType:AVMediaTypeVideo];

/* get first video track, if there is any */
AVAssetTrack *videoTrack0=[videoTracks objectAtIndex:0];

/* set the desired video frame format into attribute dictionary */
NSMutableDictionary* dictionary=[NSDictionary dictionaryWithObjectsAndKeys:
  [NSNumber numberWithInt:kCVPixelFormatType_422YpCbCr10], 
  (NSString*)kCVPixelBufferPixelFormatTypeKey,
  nil];

/* construct the actual track output and add it to the asset reader */
AVAssetReaderTrackOutput* assetReaderOutput=[[AVAssetReaderTrackOutput alloc] 
                                             initWithTrack:videoTrack0 
                                             outputSettings:dictionary]; //nil or dictionary
/* main parser loop */
NSInteger i=0;
if([assetReader canAddOutput:assetReaderOutput]){
  [assetReader addOutput:assetReaderOutput];

  NSLog(@"asset added to output.");

  /* start asset reader */
  if([assetReader startReading]==YES){
    /* read off the samples */
    CMSampleBufferRef buffer;
    while([assetReader status]==AVAssetReaderStatusReading){
      buffer=[assetReaderOutput copyNextSampleBuffer];
      i++;
      NSLog(@"decoding frame #%ld done.", i);
    }
  }
  else {
    NSLog(@"could not start reading asset.");
    NSLog(@"reader status: %ld", [assetReader status]);
  }
}
else {
  NSLog(@"could not add asset to output.");
}

最诚挚的问候, 约翰

2 个答案:

答案 0 :(得分:2)

试试kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,它对我来说很好。

答案 1 :(得分:0)

kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
kCVPixelFormatType_32BGRA

系统仅支持此功能。