0
# Codec Management
1
2
Codec contexts for encoding and decoding with hardware acceleration support. PyAV provides access to all FFmpeg codecs with comprehensive parameter control and hardware acceleration capabilities.
3
4
## Capabilities
5
6
### Codec Discovery
7
8
Find and inspect available codecs in the system.
9
10
```python { .api }
11
# Global codec availability
12
codecs_available: set[str] # Set of available codec names
13
14
class Codec:
15
"""Codec information and factory."""
16
17
# Properties
18
name: str # Codec name (e.g., 'h264', 'aac')
19
canonical_name: str # Canonical codec name
20
long_name: str # Descriptive name
21
type: str # Codec type ('video', 'audio', 'subtitle')
22
id: int # Codec ID number
23
is_encoder: bool # True if can encode
24
is_decoder: bool # True if can decode
25
mode: str # 'r' for decoder, 'w' for encoder
26
descriptor: Descriptor # Codec descriptor with options
27
28
# Format support
29
frame_rates: tuple[Fraction, ...] # Supported frame rates
30
audio_rates: tuple[int, ...] # Supported sample rates
31
video_formats: tuple[VideoFormat, ...] # Supported pixel formats
32
audio_formats: tuple[AudioFormat, ...] # Supported sample formats
33
34
# Capabilities
35
properties: int # Codec properties flags
36
37
def create(self, kind=None) -> CodecContext:
38
"""
39
Create codec context.
40
41
Parameters:
42
- kind: str - Context type ('encoder' or 'decoder')
43
44
Returns:
45
Appropriate codec context (AudioCodecContext or VideoCodecContext)
46
"""
47
48
def dump_codecs() -> None:
49
"""Print all available codecs to stdout."""
50
51
def dump_hwconfigs() -> None:
52
"""Print hardware configurations to stdout."""
53
```
54
55
### Base Codec Context
56
57
Base codec context with common encoding/decoding functionality.
58
59
```python { .api }
60
class CodecContext:
61
"""Base codec context for encoding/decoding."""
62
63
# Properties
64
name: str # Codec name
65
type: str # Context type ('audio', 'video', 'subtitle')
66
codec: Codec # Associated codec
67
options: dict[str, str] # Codec options
68
extradata: bytes | None # Codec extradata
69
time_base: Fraction # Time base for timestamps
70
codec_tag: int # Codec tag
71
profile: str | None # Codec profile
72
profiles: tuple[str, ...] # Available profiles
73
74
# Bitrate control
75
bit_rate: int # Target bitrate
76
bit_rate_tolerance: int # Bitrate tolerance
77
78
# Threading
79
thread_count: int # Number of threads
80
thread_type: int # Threading type flags
81
82
# Flags
83
flags: int # Codec flags
84
flags2: int # Additional codec flags
85
86
def open(self, codec=None, **kwargs) -> None:
87
"""
88
Open codec context.
89
90
Parameters:
91
- codec: Codec | str - Codec to use
92
- **kwargs: Additional codec options
93
"""
94
95
def create(self, codec, mode='r') -> 'CodecContext':
96
"""
97
Create new codec context.
98
99
Parameters:
100
- codec: str | Codec - Codec name or object
101
- mode: str - 'r' for decoder, 'w' for encoder
102
103
Returns:
104
New codec context
105
"""
106
107
def parse(self, data: bytes = b'') -> list[Packet]:
108
"""
109
Parse raw data into packets.
110
111
Parameters:
112
- data: bytes - Raw data to parse
113
114
Returns:
115
List of parsed packets
116
"""
117
118
def flush_buffers(self) -> None:
119
"""Flush internal codec buffers."""
120
121
# Threading and flag enums
122
class ThreadType(Flag):
123
"""Threading types."""
124
FRAME = 1 # Frame-level threading
125
SLICE = 2 # Slice-level threading
126
127
class Flags(IntEnum):
128
"""Primary codec flags."""
129
# Encoding flags
130
QSCALE = 2 # Use fixed qscale
131
TRUNCATED = 8 # Input bitstream might be truncated
132
LOW_DELAY = 524288 # Force low delay
133
GLOBAL_HEADER = 4194304 # Place global headers in extradata
134
135
class Flags2(IntEnum):
136
"""Secondary codec flags."""
137
FAST = 1 # Allow non-spec compliant speedup tricks
138
LOCAL_HEADER = 8 # Place global headers in each keyframe
139
```
140
141
### Hardware Acceleration
142
143
Hardware-accelerated encoding and decoding support.
144
145
```python { .api }
146
class HWDeviceType(IntEnum):
147
"""Hardware device types."""
148
NONE = 0
149
VDPAU = 1
150
CUDA = 2
151
VAAPI = 3
152
DXVA2 = 4
153
QSV = 5
154
VIDEOTOOLBOX = 6
155
D3D11VA = 7
156
DRM = 8
157
OPENCL = 9
158
MEDIACODEC = 10
159
VULKAN = 11
160
161
class HWConfigMethod(IntEnum):
162
"""Hardware configuration methods."""
163
HW_DEVICE_CTX = 1
164
HW_FRAMES_CTX = 2
165
INTERNAL = 4
166
AD_HOC = 8
167
168
class HWConfig:
169
"""Hardware acceleration configuration."""
170
171
device_type: HWDeviceType # Hardware device type
172
pix_fmt: str # Hardware pixel format
173
methods: int # Supported methods
174
175
class HWAccel:
176
"""Hardware acceleration interface."""
177
178
@staticmethod
179
def create(device_type, device=None) -> 'HWAccel':
180
"""
181
Create hardware acceleration context.
182
183
Parameters:
184
- device_type: str | HWDeviceType - Device type
185
- device: str - Specific device (optional)
186
187
Returns:
188
Hardware acceleration context
189
"""
190
191
def hwdevices_available() -> list[str]:
192
"""
193
Get available hardware devices.
194
195
Returns:
196
List of available hardware device names
197
"""
198
```
199
200
### Video Codec Context
201
202
Video-specific codec context with video encoding/decoding parameters.
203
204
```python { .api }
205
class VideoCodecContext(CodecContext):
206
"""Video codec context."""
207
208
# Video properties
209
format: VideoFormat | None # Pixel format
210
width: int # Frame width
211
height: int # Frame height
212
coded_width: int # Coded width (with padding)
213
coded_height: int # Coded height (with padding)
214
bits_per_coded_sample: int # Bits per coded sample
215
pix_fmt: str | None # Pixel format name
216
217
# Frame rate and timing
218
framerate: Fraction # Frame rate
219
rate: Fraction # Alias for framerate
220
time_base: Fraction # Time base
221
ticks_per_frame: int # Ticks per frame
222
223
# GOP structure
224
gop_size: int # GOP size
225
has_b_frames: bool # Uses B-frames
226
max_b_frames: int # Maximum B-frames
227
228
# Aspect ratios
229
sample_aspect_ratio: Fraction # Sample aspect ratio
230
display_aspect_ratio: Fraction # Display aspect ratio
231
232
# Color properties
233
colorspace: int # Color space
234
color_range: int # Color range
235
color_primaries: int # Color primaries
236
color_trc: int # Transfer characteristics
237
chroma_sample_location: int # Chroma sample location
238
239
# Quality control
240
qmin: int # Minimum quantizer
241
qmax: int # Maximum quantizer
242
qcompress: float # Quantizer compression
243
qblur: float # Quantizer blur
244
245
# Rate control
246
rc_max_rate: int # Maximum bitrate
247
rc_min_rate: int # Minimum bitrate
248
rc_buffer_size: int # Rate control buffer size
249
250
def encode(self, frame=None) -> list[Packet]:
251
"""
252
Encode video frame.
253
254
Parameters:
255
- frame: VideoFrame | None - Frame to encode (None flushes)
256
257
Returns:
258
List of encoded packets
259
"""
260
261
def encode_lazy(self, frame=None) -> Iterator[Packet]:
262
"""
263
Lazy encoding iterator.
264
265
Parameters:
266
- frame: VideoFrame | None - Frame to encode (None flushes)
267
268
Yields:
269
Encoded packets as they become available
270
"""
271
272
def decode(self, packet=None) -> list[VideoFrame]:
273
"""
274
Decode video packet.
275
276
Parameters:
277
- packet: Packet | None - Packet to decode (None flushes)
278
279
Returns:
280
List of decoded frames
281
"""
282
```
283
284
### Audio Codec Context
285
286
Audio-specific codec context with audio encoding/decoding parameters.
287
288
```python { .api }
289
class AudioCodecContext(CodecContext):
290
"""Audio codec context."""
291
292
# Audio properties
293
frame_size: int # Samples per frame
294
sample_rate: int # Sample rate in Hz
295
rate: int # Alias for sample_rate
296
format: AudioFormat # Sample format
297
layout: AudioLayout # Channel layout
298
channels: int # Number of channels
299
300
# Quality control
301
cutoff: int # Cutoff frequency
302
303
def encode(self, frame=None) -> list[Packet]:
304
"""
305
Encode audio frame.
306
307
Parameters:
308
- frame: AudioFrame | None - Frame to encode (None flushes)
309
310
Returns:
311
List of encoded packets
312
"""
313
314
def encode_lazy(self, frame=None) -> Iterator[Packet]:
315
"""
316
Lazy encoding iterator.
317
318
Parameters:
319
- frame: AudioFrame | None - Frame to encode (None flushes)
320
321
Yields:
322
Encoded packets as they become available
323
"""
324
325
def decode(self, packet=None) -> list[AudioFrame]:
326
"""
327
Decode audio packet.
328
329
Parameters:
330
- packet: Packet | None - Packet to decode (None flushes)
331
332
Returns:
333
List of decoded frames
334
"""
335
```
336
337
### Properties and Capabilities
338
339
```python { .api }
340
class Properties(Flag):
341
"""Codec properties."""
342
INTRA_ONLY = 1 # Intra frames only
343
LOSSY = 2 # Lossy compression
344
LOSSLESS = 4 # Lossless compression
345
REORDER = 8 # Codec reorders frames
346
BITMAP_SUB = 16 # Bitmap subtitles
347
TEXT_SUB = 32 # Text subtitles
348
349
class Capabilities(IntEnum):
350
"""Codec capabilities."""
351
DRAW_HORIZ_BAND = 1 # Supports draw_horiz_band
352
DR1 = 2 # Supports direct rendering
353
TRUNCATED = 8 # Supports truncated bitstreams
354
HWACCEL = 16 # Supports hardware acceleration
355
DELAY = 32 # Has encoding/decoding delay
356
SMALL_LAST_FRAME = 64 # Supports small last frame
357
HWACCEL_VDPAU = 128 # VDPAU hardware acceleration
358
SUBFRAMES = 256 # Supports subframes
359
EXPERIMENTAL = 512 # Experimental codec
360
CHANNEL_CONF = 1024 # Channel configuration
361
NEG_LINESIZES = 2048 # Negative line sizes
362
FRAME_THREADS = 4096 # Frame threading
363
SLICE_THREADS = 8192 # Slice threading
364
PARAM_CHANGE = 16384 # Parameter changes
365
AUTO_THREADS = 32768 # Automatic threading
366
VARIABLE_FRAME_SIZE = 65536 # Variable frame size
367
```
368
369
## Usage Examples
370
371
### Basic Encoding
372
373
```python
374
import av
375
import numpy as np
376
377
# Create output container
378
output = av.open('encoded.mp4', 'w')
379
380
# Add video stream with specific codec
381
video_stream = output.add_stream('libx264', rate=30)
382
video_stream.width = 1920
383
video_stream.height = 1080
384
video_stream.pix_fmt = 'yuv420p'
385
386
# Configure codec options
387
video_stream.codec_context.options = {
388
'preset': 'medium',
389
'crf': '23'
390
}
391
392
# Add audio stream
393
audio_stream = output.add_stream('aac', rate=44100)
394
audio_stream.channels = 2
395
audio_stream.layout = 'stereo'
396
397
# Generate and encode frames
398
for i in range(90): # 3 seconds at 30fps
399
# Create video frame
400
array = np.random.randint(0, 255, (1080, 1920, 3), dtype=np.uint8)
401
frame = av.VideoFrame.from_ndarray(array, format='rgb24')
402
frame.pts = i
403
frame.time_base = video_stream.time_base
404
405
# Encode and mux
406
for packet in video_stream.encode(frame):
407
output.mux(packet)
408
409
# Flush encoders
410
for packet in video_stream.encode():
411
output.mux(packet)
412
for packet in audio_stream.encode():
413
output.mux(packet)
414
415
output.close()
416
```
417
418
### Codec Discovery and Selection
419
420
```python
421
import av
422
423
# List all available codecs
424
print("Available video encoders:")
425
for codec_name in av.codecs_available:
426
codec = av.Codec(codec_name, 'w')
427
if codec.type == 'video' and codec.is_encoder:
428
print(f" {codec.name}: {codec.long_name}")
429
430
print("\nAvailable audio encoders:")
431
for codec_name in av.codecs_available:
432
codec = av.Codec(codec_name, 'w')
433
if codec.type == 'audio' and codec.is_encoder:
434
print(f" {codec.name}: {codec.long_name}")
435
436
# Check specific codec capabilities
437
h264_codec = av.Codec('h264', 'w')
438
print(f"\nH.264 codec info:")
439
print(f" Long name: {h264_codec.long_name}")
440
print(f" Is encoder: {h264_codec.is_encoder}")
441
print(f" Supported pixel formats: {[fmt.name for fmt in h264_codec.video_formats]}")
442
print(f" Properties: {h264_codec.properties}")
443
444
# Create codec context
445
ctx = h264_codec.create()
446
print(f" Context type: {ctx.type}")
447
print(f" Available profiles: {ctx.profiles}")
448
```
449
450
### Hardware Acceleration
451
452
```python
453
import av
454
455
# Check available hardware devices
456
hw_devices = av.hwdevices_available()
457
print(f"Available hardware devices: {hw_devices}")
458
459
if 'cuda' in hw_devices:
460
# Create output with hardware encoding
461
output = av.open('hw_encoded.mp4', 'w')
462
463
# Add hardware-accelerated video stream
464
stream = output.add_stream('h264_nvenc', rate=30) # NVIDIA hardware encoder
465
stream.width = 1920
466
stream.height = 1080
467
stream.pix_fmt = 'yuv420p'
468
469
# Configure hardware-specific options
470
stream.codec_context.options = {
471
'preset': 'fast',
472
'rc': 'cbr',
473
'cbr': 'true',
474
'b': '5M'
475
}
476
477
print("Using NVIDIA hardware encoding")
478
479
elif 'vaapi' in hw_devices:
480
# Use VAAPI (Linux Intel/AMD)
481
output = av.open('hw_encoded.mp4', 'w')
482
483
stream = output.add_stream('h264_vaapi', rate=30)
484
stream.width = 1920
485
stream.height = 1080
486
stream.pix_fmt = 'nv12' # VAAPI preferred format
487
488
print("Using VAAPI hardware encoding")
489
490
else:
491
print("No hardware acceleration available, using software encoding")
492
output = av.open('sw_encoded.mp4', 'w')
493
stream = output.add_stream('libx264', rate=30)
494
stream.width = 1920
495
stream.height = 1080
496
stream.pix_fmt = 'yuv420p'
497
498
# ... encoding loop ...
499
output.close()
500
```
501
502
### Advanced Codec Configuration
503
504
```python
505
import av
506
507
# Create output with advanced codec settings
508
output = av.open('advanced.mp4', 'w')
509
510
# Video stream with detailed configuration
511
video_stream = output.add_stream('libx264', rate=24)
512
video_stream.width = 1920
513
video_stream.height = 1080
514
video_stream.pix_fmt = 'yuv420p'
515
516
# Configure video codec context
517
ctx = video_stream.codec_context
518
ctx.bit_rate = 5000000 # 5 Mbps
519
ctx.gop_size = 48 # GOP size (2 seconds at 24fps)
520
ctx.max_b_frames = 2 # B-frame configuration
521
ctx.flags |= av.codec.context.Flags.GLOBAL_HEADER
522
523
# Advanced x264 options
524
ctx.options = {
525
'preset': 'slow', # Quality preset
526
'tune': 'film', # Content tuning
527
'crf': '18', # Constant rate factor
528
'profile': 'high', # H.264 profile
529
'level': '4.1', # H.264 level
530
'x264-params': 'keyint=48:min-keyint=12:scenecut=40'
531
}
532
533
# Audio stream with AAC configuration
534
audio_stream = output.add_stream('aac', rate=48000)
535
audio_stream.channels = 2
536
audio_stream.layout = 'stereo'
537
538
# Configure audio codec
539
audio_ctx = audio_stream.codec_context
540
audio_ctx.bit_rate = 192000 # 192 kbps
541
audio_ctx.options = {
542
'profile': 'aac_low',
543
'cutoff': '18000'
544
}
545
546
print(f"Video codec: {video_stream.codec_context.name}")
547
print(f" Bitrate: {ctx.bit_rate}")
548
print(f" GOP size: {ctx.gop_size}")
549
print(f" B-frames: {ctx.max_b_frames}")
550
551
print(f"Audio codec: {audio_stream.codec_context.name}")
552
print(f" Bitrate: {audio_ctx.bit_rate}")
553
print(f" Sample rate: {audio_ctx.sample_rate}")
554
555
# ... encoding process ...
556
output.close()
557
```
558
559
### Decoding with Different Codecs
560
561
```python
562
import av
563
564
def analyze_container_codecs(filename):
565
"""Analyze codecs used in a media file."""
566
567
container = av.open(filename)
568
569
print(f"Container format: {container.format.name}")
570
print(f"Duration: {container.duration / av.time_base:.2f} seconds")
571
572
for i, stream in enumerate(container.streams):
573
codec = stream.codec_context
574
575
print(f"\nStream {i} ({stream.type}):")
576
print(f" Codec: {codec.name}")
577
print(f" Bitrate: {codec.bit_rate}")
578
579
if stream.type == 'video':
580
print(f" Resolution: {codec.width}x{codec.height}")
581
print(f" Pixel format: {codec.pix_fmt}")
582
print(f" Frame rate: {stream.framerate}")
583
print(f" Profile: {codec.profile}")
584
585
elif stream.type == 'audio':
586
print(f" Sample rate: {codec.sample_rate}")
587
print(f" Channels: {codec.channels}")
588
print(f" Sample format: {codec.format.name}")
589
print(f" Channel layout: {codec.layout.name}")
590
591
# Test decoding capabilities
592
for stream in container.streams.video[:1]: # First video stream
593
print(f"\nTesting video decoding...")
594
frame_count = 0
595
for frame in container.decode(stream):
596
frame_count += 1
597
if frame_count >= 5: # Test first 5 frames
598
break
599
print(f"Successfully decoded {frame_count} frames")
600
601
container.close()
602
603
# Analyze file
604
analyze_container_codecs('sample.mp4')
605
```
606
607
### Custom Codec Parameters
608
609
```python
610
import av
611
612
def create_high_quality_encoder():
613
"""Create high-quality video encoder with custom parameters."""
614
615
output = av.open('high_quality.mp4', 'w')
616
617
# Create video stream
618
stream = output.add_stream('libx264', rate=25)
619
stream.width = 3840
620
stream.height = 2160
621
stream.pix_fmt = 'yuv420p10le' # 10-bit encoding
622
623
# High quality settings
624
ctx = stream.codec_context
625
ctx.bit_rate = 50000000 # 50 Mbps
626
ctx.gop_size = 50 # 2-second GOP
627
ctx.max_b_frames = 4 # More B-frames for efficiency
628
ctx.qmin = 10 # Higher minimum quality
629
ctx.qmax = 30 # Lower maximum quantizer
630
631
# Professional encoding options
632
ctx.options = {
633
'preset': 'veryslow', # Best compression
634
'tune': 'film', # Film content
635
'crf': '16', # Very high quality
636
'profile': 'high10', # 10-bit profile
637
'level': '5.1', # 4K level
638
'psy-rd': '1.0:0.15', # Psychovisual optimization
639
'deblock': '1:1', # Deblocking filter
640
'ref': '8', # Reference frames
641
'bframes': '4', # B-frame count
642
'b-adapt': '2', # Adaptive B-frames
643
'direct': 'auto', # Direct MV prediction
644
'me': 'umh', # Motion estimation
645
'subme': '10', # Sub-pixel motion estimation
646
'analyse': 'all', # Partition analysis
647
'trellis': '2', # Trellis quantization
648
'no-fast-pskip': None, # Disable fast P-skip
649
'no-dct-decimate': None, # Disable DCT decimation
650
}
651
652
return output, stream
653
654
# Create high-quality encoder
655
output, stream = create_high_quality_encoder()
656
print(f"Created high-quality encoder:")
657
print(f" Resolution: {stream.width}x{stream.height}")
658
print(f" Pixel format: {stream.pix_fmt}")
659
print(f" Bitrate: {stream.codec_context.bit_rate}")
660
print(f" Preset: {stream.codec_context.options.get('preset')}")
661
662
# ... encoding process ...
663
output.close()
664
```