Metadata-Version: 2.2
Name: QPMBDeblock
Version: 0.5.0
Summary: Fast native H.264 QP and macroblock map extractor using FFmpeg
Author: PingWer, Mhanz3500
License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
         
         By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
         
         Section 1 – Definitions.
         [... The standard CC BY-NC-SA 4.0 legal code applies. See https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode for the full text ...]
         
         You are free to:
         - Share — copy and redistribute the material in any medium or format
         - Adapt — remix, transform, and build upon the material
         
         Under the following terms:
         - Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
         - NonCommercial — You may not use the material for commercial purposes.
         - ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
         
Classifier: License :: Other/Proprietary License
Requires-Python: >=3.12
Requires-Dist: numpy>=2.0.0
Requires-Dist: vapoursynth>=74
Requires-Dist: vapoursynth-bestsource>=22
Description-Content-Type: text/markdown

# QPMBDeblock

Modern, high-performance in-memory H.264 QP map extractor and raw stream decoder for VapourSynth and Python, backed by native C++ FFmpeg (`libavcodec`/`libavformat`).

## Features

- **100% In-Memory Architecture:** No temporary disk MKV files, no slow IPC pipes, zero disk wear.
- **Fast C++ LRU Cache:** 64-frame in-memory circular cache with sub-millisecond seeking and sub-400MB memory footprint.
- **Synchronized Three-Stream Pipeline:** Single entrypoint `open_h264_source()` yielding:
  1. `clip_src`: Reference clip loaded via `vapoursynth-bestsource`.
  2. `qpmap`: Macroblock QP map (GRAY8 / GRAY16, or full YUV with ITU-T Table 8-15 chroma derivation).
  3. `clip_nodeblock`: Video decoded with in-loop deblocking filter disabled (`skip_loop_filter = AVDISCARD_ALL`).
- **Full Bit-Depth & Chroma Subsampling Support:** Seamlessly decodes 8-bit and 10-bit H.264 streams across 4:2:0, 4:2:2, and 4:4:4 profiles (High, High 10, High 4:2:2, High 4:4:4 Predictive).
- **Automated PPS Chroma Offset Detection:** Automatically parses and extracts `chroma_qp_index_offset` / `second_chroma_qp_index_offset` from the stream's Picture Parameter Set (PPS).
- **Corrupted Block Tracking:** Automatically detects and clamps corrupted blocks (`QP == -1`) to 0, reporting exact macroblock coordinates via console logs and frame properties (`QPCorrupted`, `QPCorruptedCoords`).

---

## Installation

```bash
pip install QPMBDeblock
```

Pre-built binary wheels are distributed for **Windows (x86_64)** and **Linux (x86_64, aarch64)** with dynamic FFmpeg shared libraries bundled in compliance with LGPL v2.1.

---

## VapourSynth Quickstart

```python
import vapoursynth as vs
from qpmbdeblock import open_h264_source

core = vs.core

# Open all three 1:1 frame-synchronized VideoNodes in-memory
clip_src, qpmap, clip_nodeblock = open_h264_source(
    "video.mkv",
    scale_video=True,       # Upscale QP map to match clip_src dimensions (Point resize)
    high_bitdepth=True,     # Output QP map in GRAY16 (values 0-63 scaled)
    chroma_qpmap=False,     # True = derive full YUV chroma planes; False = single GRAY plane
    chroma_qp_offset=None,  # None = auto-detect PPS offsets from video; or provide manual int/(cb, cr)
)

# Set outputs for previewing (e.g. vsview)
clip_src.set_output(0)
qpmap.set_output(1)
clip_nodeblock.set_output(2)
```

---

## Frame Properties

`qpmap` automatically injects diagnostic and stream metadata into VapourSynth frame properties:

| Property | Type | Description |
|---|---|---|
| `QPCorrupted` | `int` | `1` if invalid/corrupted macroblocks (`-1`) were found and clamped to `0`, else `0`. |
| `QPCorruptedCount` | `int` | Total number of corrupted blocks detected in the frame. |
| `QPCorruptedCoords` | `str` | List of `(row, col)` coordinates of the corrupted macroblocks. |
| `ChromaQPOffsetCb` | `int` | PPS `chroma_qp_index_offset` extracted from the stream (e.g. `-3`). |
| `ChromaQPOffsetCr` | `int` | PPS `second_chroma_qp_index_offset` extracted from the stream. |

---

## Deblocking Filter Usage

```python
import vapoursynth as vs
from qpmbdeblock import open_h264_source, av2deblock

core = vs.core

clip_src, qpmap, clip_nodeblock = open_h264_source("input.mkv", high_bitdepth=False)

# Apply AV2 deblocking guided by QP map
deblocked_8x8, deblocked_4x4, debug_clip = av2deblock(
    clip=clip_nodeblock,
    qpmap=qpmap,
    mbmap=..., # macroblock mode map
    qpmap_offset=0,
)
```

---

## Building from Source

**Requirements:**
- Python ≥ 3.12
- CMake ≥ 3.15
- C++17 compatible compiler (MSVC 2019+, GCC 9+, Clang 10+)
- FFmpeg shared development libraries (`libavcodec`, `libavformat`, `libavutil`)

```bash
# Windows (specify FFmpeg directory if not in PATH):
$env:FFMPEG_ROOT = "C:\path\to\ffmpeg-full_build-shared"
pip install .

# Linux (Debian / Ubuntu):
sudo apt-get install -y libavcodec-dev libavformat-dev libavutil-dev
pip install .
```

---

## License

This project is licensed under [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](LICENSE).
FFmpeg dependencies are dynamically linked under the terms of the **GNU LGPL v2.1**.