Skip to content

Expose AVCodecContext.field_order through VideoCodecContext.field_order #2347

Description

@mockodin

Summary

PyAV exposes video codec-context color properties such as color_range,
color_primaries, color_trc, and colorspace, but it does not expose
AVCodecContext.field_order.

This prevents an in-process PyAV application from reliably inspecting, preserving, or
configuring progressive/interlaced scan order. The value is available in FFmpeg and is
reported by ffprobe, but retrieving or setting it currently requires a subprocess or a
local PyAV patch.

Use case

Media transcode and validation pipelines commonly need to:

  • reject an unexpected progressive/interlaced conversion;
  • preserve source field order when producing a same-format rendition;
  • explicitly configure a progressive or interlaced encoder output; and
  • compare an encoded output against a target media contract.

Inferring field order from decoded frames is not equivalent to reading or configuring the
codec context, and container metadata is not a reliable replacement.

Reproducer

Tested with PyAV 18.0.0:

import av

with av.open("interlaced-input.mxf") as container:
    context = container.streams.video[0].codec_context
    print(hasattr(context, "field_order"))

Current output:

False

For encoding, there is likewise no supported equivalent of:

context.field_order = ...

Expected behavior

Expose a read/write property on VideoCodecContext that wraps
AVCodecContext.field_order:

with av.open("interlaced-input.mxf") as container:
    field_order = container.streams.video[0].codec_context.field_order

encoder = av.CodecContext.create("libx264", "w")
encoder.field_order = field_order

A typed IntEnum corresponding to AVFieldOrder would be ideal if that matches PyAV's API
conventions. Returning and accepting an integer would still be consistent with several
existing codec-context metadata properties.

The property should configure metadata only; it should not imply deinterlacing or alter
frame content.

Minimal implementation

The binding itself appears small:

@property
def field_order(self):
    return self.ptr.field_order

@field_order.setter
def field_order(self, value):
    self.ptr.field_order = value

This is one public API change. Implementing it requires synchronized updates in three
places: declare the existing FFmpeg struct member in include/avcodec.pxd, add the
property in av/video/codeccontext.py, and add its type in
av/video/codeccontext.pyi.

Alternatives considered

  • Calling ffprobe/ffmpeg: works, but adds a subprocess and breaks an otherwise
    in-process PyAV pipeline.
  • Reading container metadata: not consistently equivalent to codec field order.
  • Inspecting decoded frames: does not configure encoder output and is not always a reliable
    stream-level declaration.
  • Exposing all AVCodecParameters: substantially broader and less maintainable than this
    focused property.

Suggested tests

  1. Open an interlaced fixture and assert the decoder context reports the expected field
    order.
  2. Set the property on an encoder context and assert it round-trips before opening.
  3. Encode a short output and verify its resulting stream reports the configured field
    order.
  4. Verify invalid values follow PyAV's normal enum/integer validation behavior.

Would the maintainers accept a focused read/write VideoCodecContext.field_order property
and regression tests?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions