Читать метаданные видео в цели 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
}

независимо от чересстрочного ввода входного файла выше всегда возвращает ноль. Я, вероятно, пытаюсь проверить это в совершенно неправильном поместье, поэтому любая помощь очень ценится!

1 ответ

Решение

Спасибо 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;
    }

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

ОБНОВИТЬ:

С тех пор я обнаружил, что естественным размером является разрешение экрана. чтобы найти закодированное разрешение, вам нужно декодировать первый кадр и проверить разрешение получаемого вами объекта буфера. Они могут отличаться в таких случаях, как соотношение сторон пикселя!=1 или (как описано выше) чистая апертура.

Другие вопросы по тегам