2016-02-19 34 views
1

我想看看用户选择的视频文件是隔行/逐行的,然后根据它进行一些操作。阅读目标中的视频元数据c

我试图检查我提取的cmsamplebuffer是否定义为顶部字段第一或底部字段第一,但是这将返回所有输入为空。

NSMutableDictionary *pixBuffAttributes = [[NSMutableDictionary alloc] init]; 
[pixBuffAttributes setObject: 
[NSNumber numberWithInt:kCVPixelFormatType_422YpCbCr8] 
forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey]; 
myAsset = [[AVURLAsset alloc] initWithURL:urlpath options:pixBuffAttributes]; 
myAssetReader = [[AVAssetReader alloc] initWithAsset:myAsset error:nil]; 
myAssetOutput = [[AVAssetReaderTrackOutput alloc]initWithTrack: 
       [[myAsset tracksWithMediaType:AVMediaTypeVideo] 
       objectAtIndex: 0] 
       outputSettings:pixBuffAttributes]; 
[myAssetReader addOutput:myAssetOutput]; 
[myAssetReader startReading]; 
CMSampleBufferRef ref = [myAssetOutput copyNextSampleBuffer]; 
if(CVBufferGetAttachments(ref, kCVImageBufferFieldDetailKey, nil) == nil) 
{ 
    //always the case 
} 
else 
{ 
    //never happens 
} 

无论输入文件的隔行扫描以上总是返回nil。我可能试图在完全错误的庄园中进行测试,所以非常感谢所有帮助!

回答

0

感谢jeschot苹果开发者为回答这个问题,https://forums.developer.apple.com/thread/39029 如果其他人试图做同样的事情的propper方式从视频获得大部分的元数据:

CGSize inputsize = [[myAsset tracksWithMediaType:AVMediaTypeVideo][0] naturalSize]; 

    properties->m_frame_rows = inputsize.height; 
    properties->m_pixel_cols = inputsize.width; 

    CFNumberRef fieldCount = CMFormatDescriptionGetExtension((CMFormatDescriptionRef)[myAsset tracksWithMediaType:AVMediaTypeVideo][0].formatDescriptions[0], kCMFormatDescriptionExtension_FieldCount); 

    if([(NSNumber*) fieldCount integerValue] == 1) 
    { 
     properties->m_interlaced = false; 
     properties->m_fld2_upper = false; 
    } 
    else 
    { 
     properties->m_interlaced = true; 

     CFPropertyListRef interlace = CMFormatDescriptionGetExtension((CMFormatDescriptionRef)[myAsset tracksWithMediaType:AVMediaTypeVideo][0].formatDescriptions[0], kCMFormatDescriptionExtension_FieldDetail); 

     if(interlace == kCMFormatDescriptionFieldDetail_SpatialFirstLineEarly) 
     { 
      properties->m_fld2_upper = false; 
     } 

     if(interlace == kCMFormatDescriptionFieldDetail_SpatialFirstLineLate) 
     { 
      properties->m_fld2_upper = true; 
     } 

     if(interlace == kCMFormatDescriptionFieldDetail_TemporalBottomFirst) 
     { 
      properties->m_fld2_upper = true; 
     } 

     if(interlace == kCMFormatDescriptionFieldDetail_TemporalTopFirst) 
     { 
      properties->m_fld2_upper = false; 
     } 
    } 

    CMTime minDuration = [myAsset tracksWithMediaType:AVMediaTypeVideo][0].minFrameDuration; 

    int64_t fpsNumerator = minDuration.value; 
    int32_t fpsDenominator = minDuration.timescale; 

    properties->m_ticks_duration = (unsigned int) fpsNumerator; 
    if (properties->m_interlaced) 
    { 
     properties->m_ticks_per_second = fpsDenominator * 2; 
    } 
    else 
    { 
     properties->m_ticks_per_second = fpsDenominator; 
    } 

和快速记了任何其他人都会因此而感到困惑,如果容器的元数据(例如清洁度低于全分辨率),自然大小并不总是图像的完整分辨率。目前正试图解决这个问题,但这是一个不同的问题!

UPDATE:

我发现,这种天然的大小是显示分辨率。找到您需要解码第一帧的编码分辨率并检查您获得的缓冲区对象的分辨率。这些可以在像素纵横比!= 1或(如上所述)干净贴图的情况下有所不同。