or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

audio.mdcodecs.mdcontainers.mdfilters.mdindex.mdstreams.mdvideo.md

codecs.mddocs/

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

```