Programatically retrieving field and frame information

Q: How can I programatically find out if video media in a QuickTime Movie is interlaced or progressive scan?

A: The Field/Frame information for a Media is stored in the Image Description and may be returned by calling ICMImageDescriptionGetProperty using the kICMImageDescriptionPropertyID_FieldInfo property ID.

Asking for the kICMImageDescriptionPropertyID_FieldInfo property will return the information (if available) in a FieldInfoImageDescriptionExtension2 structure (see below). The fields variable of this structure will be either set to kQTFieldsProgressiveScan if the content is progressive, or kQTFieldsInterlaced if it is interlaced.

Note: If the kICMImageDescriptionPropertyID_FieldInfo property does not exist, assume progressive scan.

/* Field/Frame Info */
struct FieldInfoImageDescriptionExtension2 {
  UInt8               fields;
  UInt8               detail;
};

/* Field Info Values */
enum {
  kQTFieldsProgressiveScan  = 1,
  kQTFieldsInterlaced       = 2
};

/* Frame Detail Values */
enum {
  kQTFieldDetailUnknown                 = 0,
  kQTFieldDetailTemporalTopFirst        = 1,
  kQTFieldDetailTemporalBottomFirst     = 6,
  kQTFieldDetailSpatialFirstLineEarly   = 9,
  kQTFieldDetailSpatialFirstLineLate    = 14
};

Listing 1 demonstrates using ICMImageDescriptionGetProperty to get the Field/Frame info.

Listing 1: IsInterlaced function.

Boolean IsInterlaced(Track inVideoTrack)
{
    Media aMedia = 0;
    Boolean isInterlaced = NO;  // assume progressive
    FieldInfoImageDescriptionExtension2 *fieldInfo = NULL;
    ImageDescriptionHandle desc = NULL;

    if (0 == inVideoTrack) goto bail;

    // get the tracks media
    aMedia = GetTrackMedia(inVideoTrack);
    if (0 == aMedia) goto bail;

    // grab the image description
    desc = (ImageDescriptionHandle)NewHandle(0);
    if (NULL == desc) goto bail;
    GetMediaSampleDescription(aMedia, 1, (SampleDescriptionHandle)desc);

    // get the size of the returned property
    ByteCount propertyValueSize = 0;
    ComponentValueType propertyType = 0;
    UInt32 propertyFlags = 0;

    OSStatus status = ICMImageDescriptionGetPropertyInfo(desc,
                                                         kQTPropertyClass_ImageDescription,
                                                         kICMImageDescriptionPropertyID_FieldInfo,
                                                         &propertyType,
                                                         &propertyValueSize,
                                                         &propertyFlags);
   if (noErr != status) goto bail;

    // get the FieldInfo property - for more information see ImageCodec.h
    fieldInfo = (FieldInfoImageDescriptionExtension2 *)calloc(1, propertyValueSize);

    status = ICMImageDescriptionGetProperty(desc,
                                            kQTPropertyClass_ImageDescription,
                                            kICMImageDescriptionPropertyID_FieldInfo,
                                            propertyValueSize,
                                            fieldInfo,
                                            NULL);
    // check the value
    if (noErr == status) {
        isInterlaced = (fieldInfo->fields == kQTFieldsInterlaced);
    }

bail:
    if (NULL != desc) DisposeHandle((Handle)desc);
    if (NULL != fieldInfo) free(fieldInfo);

    return isInterlaced;
}

References

Back to Top 

Document Revision History

DateNotes
2007-09-13First Version

Posted: 2007-09-13


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.