在目标c中读取视频元数据

永远

我正在尝试查看用户选择的视频文件是否是隔行扫描/逐行扫描,然后根据需要进行一些操作。

我试图检查是否将我提取的cmsamplebuffer定义为“首先是顶部字段”还是“首先是底部字段”,但是这对于所有输入都返回null。

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。我可能正在尝试以完全错误的庄园进行测试,因此非常感谢您的帮助!

永远

感谢苹果开发人员jeschot回答了这个问题,https: //forums.developer.apple.com/thread/39029如果其他人正在尝试类似的方法来从视频中获取大多数元数据,请执行以下操作:

    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;
    }

对于对此感到困惑的任何人,请注意,如果容器中的元数据(例如干净的apeture)小于完整分辨率,则自然尺寸并不总是图像的完整分辨率。目前正在努力解决这个问题,但这是一个不同的问题!

更新:

从那以后,我发现自然尺寸就是显示分辨率。要找到编码的分辨率,您需要解码第一帧并检查您获得的缓冲区对象的分辨率。在诸如像素长宽比!= 1或清洁锐角(如上所述)的情况下,这些可以是不同的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章