Skip to content

Puiching-Memory/pylibde265

Repository files navigation

pylibde265

Decode HEVC(H.265) video in python.

Warning! This repository is still in early release, the code is subject to frequent disruptive changes, and we cannot guarantee compatibility with the current version.

Concept

image:vedio_steam

Common video files, such as .mp4, are containers that include video streams (HEVC encoded) and audio streams (AAC encoded).

libde265 is responsible for decoding the HEVC encoded video stream into raw bitstreams.

Starting from v0.1.0, pylibde265 includes a lightweight MP4 demuxer that supports decoding HEVC video streams directly from .mp4/.mov files.

Quick Start

pip install pylibde265
import pylibde265.de265
import matplotlib.pyplot as plt
import os

# Initialize decoder (specify number of threads)
dec = pylibde265.de265.decoder(threads=os.cpu_count() or 1)

# Stream load and decode HEVC (.265/.hevc) file
for img in dec.load_file("your_video.h265"):
    print(f"Frame PTS: {img.pts}, {img.width()}x{img.height()}")
    
    # Get raw YUV components (numpy view, no copy)
    # y, cb, cr = img.yuv()
    
    # Convert to RGB (C++ accelerated, supports 420/422/444 and 8-12bit)
    rgb = img.to_rgb()
    
    plt.imshow(rgb)
    plt.show()
    break

example_preview.png

Advanced Usage: Memory Stream Processing

If you are processing stream data from network or memory:

dec = pylibde265.de265.decoder()
with open("stream.h265", "rb") as f:
    while True:
        chunk = f.read(4096)
        if not chunk: break
        
        dec.push_data(chunk)
        for img in dec.decode():
             # Process image
             process(img.to_rgb())

Direct MP4 Decoding

import pylibde265

demuxer = pylibde265.FileDemuxer("video.mp4")
decoder = pylibde265.decoder()

# Get video info
print(f"FPS: {demuxer.get_fps()}, Total frames: {len(demuxer)}")

# Initialize with headers (VPS/SPS/PPS)
decoder.push_data(demuxer.get_headers())

# Iterate through packets
for frame_data in demuxer:
    decoder.push_data(frame_data)
    for img in decoder.decode():
        # Process image (e.g., convert to RGB)
        rgb = img.to_rgb()

More Examples

This project provides detailed example codes located in the example/ directory, covering aspects from basic decoding to visualization:

For detailed instructions, please refer to example/README.md.

Performance

  • High Performance C++ Core: All pixel processing and color conversion (YUV to RGB) has been fully migrated to the C++ layer, using pybind11 for zero-copy data exchange.
  • Multi-threading Support: Fully utilizes libde265's multi-threaded decoding capabilities, performing excellently on multi-core processors.
  • Performance Benchmarks (720p H.265):
    • Decoding Speed: > 100 FPS (single frame ~8ms).
    • Color Conversion: ~6ms (C++ accelerated, supports 4:2:0/4:2:2/4:4:4).
    • Total Throughput: Can stably reach 30+ FPS real-time playback rate under 4 threads.

Specific performance data (based on test/bench_performance.py):

Threads Decode (ms) RGB Conversion (ms) Total FPS
1 73.18 6.20 12.6
4 27.64 5.72 30.0
16 22.19 5.79 35.7

Build from Source

Requirements

  • C++11 compatible compiler (Windows: VS 2022 / GCC / Clang)
  • CMake 3.15+
  • Python 3.9+

Use uv (Recommended)

  1. Clone repository: git clone https://github.com/Puiching-Memory/pylibde265.git
  2. Install dependencies and build automatically:
# Create and activate environment
uv venv
.venv\Scripts\activate

# Install in editable mode (internally calls CMake to build C++ modules)
uv pip install -e .[dev]

Running Tests

Standardized tests are provided using pytest:

pytest test/

Roadmap

  • High Performance C++ Color Conversion: Support various sampling formats and bit depths.
  • Stream Data Loading: Support push_data real-time decoding.
  • Demuxer: Built-in lightweight demuxer supporting standard and Fragmented MP4 (fMP4).
  • Hardware Acceleration: Integrate DXVA2/D3D11VA.

Acknowledgements

Author:

  • @梦归云帆 (MengGuiYunFan)

References:

Stats Badges:

Data Analysis: