Summary
PyAV exposes CodecContext.profile, but it does not expose the numeric codec level from
AVCodecContext.level or AVCodecParameters.level.
Codec level is part of common media delivery contracts alongside codec and profile. An
application validating H.264 or HEVC output therefore cannot perform an exact
codec/profile/level check through PyAV alone.
Reproducer
Tested with:
PyAV: 18.0.0
FFmpeg: 8.1.2
import av
with av.open("h264-main-level-3.1.mp4") as container:
context = container.streams.video[0].codec_context
print(context.name)
print(context.profile)
print(hasattr(context, "level"))
Current output:
The same H.264 stream reports level 31 through ffprobe.
A second H.264 sample reports level 50 through ffprobe:
codec=h264 profile=High ffprobe-level=50
An unspecified-level case is also consistent. A ProRes sample reports FFmpeg's
FF_LEVEL_UNKNOWN sentinel through ffprobe:
codec=prores profile=Standard ffprobe-level=-99
PyAV opens each file and exposes its codec and profile, but not its level. ffprobe
reports the corresponding raw level from the same FFmpeg stream information.
Expected behavior
Expose a focused read-only property:
with av.open("input.mp4") as container:
level = container.streams.video[0].codec_context.level
The property should return FFmpeg's raw integer level. Codec-specific formatting and
display conversion can remain caller responsibilities.
Read-only is sufficient for this proposal. There is no demonstrated encoder-setting use
case. The documentation should state that FFmpeg's unknown-level sentinel is returned as
-99.
Minimal implementation
This is one public API change. It requires synchronized updates in four places.
Declare the existing FFmpeg struct member in include/avcodec.pxd:
int bits_per_coded_sample
int profile
int level
AVDiscard skip_frame
Add the read-only property beside profile in av/codec/context.py:
@property
def level(self):
"""The codec level as FFmpeg's raw integer value."""
return self.ptr.level
Add the property type in av/codec/context.pyi:
profile: str | None
level: int
Add it to the public codec API documentation in docs/api/codec.rst:
.. autoattribute:: CodecContext.level
No setter, codec-specific conversion, or broad AVCodecParameters exposure is needed.
The runtime declaration and property above were built against PyAV 18.0.0 and tested
with synthetic fixtures. CodecContext.level matched ffprobe for H.264 levels 31
and 50, and for FFmpeg's unknown-level sentinel -99 on ProRes.
Why a focused property
A single CodecContext.level property is preferable to exposing a dictionary snapshot of
all AVCodecParameters fields:
- it is typed and discoverable;
- it matches the existing
CodecContext.profile surface;
- it avoids coupling Python callers to the full FFmpeg struct layout; and
- it keeps future compatibility work limited to one stable field.
Alternatives considered
- Calling
ffprobe: valid at a CLI validation boundary, but requires a subprocess for a
value already present in the opened FFmpeg context.
- Deriving level from profile, dimensions, or bitrate: ambiguous and codec-specific.
- Exposing all codec parameters: much broader than the use case and increases maintenance.
Suggested tests
- Open a fixture with a known level and compare the property with the expected raw FFmpeg
value.
- Cover an unknown or unspecified level.
- Cover at least two codec families before treating the property as generic.
Would the maintainers accept a focused read-only CodecContext.level property and
regression tests?
Summary
PyAV exposes
CodecContext.profile, but it does not expose the numeric codec level fromAVCodecContext.levelorAVCodecParameters.level.Codec level is part of common media delivery contracts alongside codec and profile. An
application validating H.264 or HEVC output therefore cannot perform an exact
codec/profile/level check through PyAV alone.
Reproducer
Tested with:
Current output:
The same H.264 stream reports level
31throughffprobe.A second H.264 sample reports level
50throughffprobe:An unspecified-level case is also consistent. A ProRes sample reports FFmpeg's
FF_LEVEL_UNKNOWNsentinel throughffprobe:PyAV opens each file and exposes its codec and profile, but not its level.
ffprobereports the corresponding raw level from the same FFmpeg stream information.
Expected behavior
Expose a focused read-only property:
The property should return FFmpeg's raw integer level. Codec-specific formatting and
display conversion can remain caller responsibilities.
Read-only is sufficient for this proposal. There is no demonstrated encoder-setting use
case. The documentation should state that FFmpeg's unknown-level sentinel is returned as
-99.Minimal implementation
This is one public API change. It requires synchronized updates in four places.
Declare the existing FFmpeg struct member in
include/avcodec.pxd:Add the read-only property beside
profileinav/codec/context.py:Add the property type in
av/codec/context.pyi:Add it to the public codec API documentation in
docs/api/codec.rst:No setter, codec-specific conversion, or broad
AVCodecParametersexposure is needed.The runtime declaration and property above were built against PyAV 18.0.0 and tested
with synthetic fixtures.
CodecContext.levelmatchedffprobefor H.264 levels31and
50, and for FFmpeg's unknown-level sentinel-99on ProRes.Why a focused property
A single
CodecContext.levelproperty is preferable to exposing a dictionary snapshot ofall
AVCodecParametersfields:CodecContext.profilesurface;Alternatives considered
ffprobe: valid at a CLI validation boundary, but requires a subprocess for avalue already present in the opened FFmpeg context.
Suggested tests
value.
Would the maintainers accept a focused read-only
CodecContext.levelproperty andregression tests?