Complete VIDEO-001 through VIDEO-004 software video studies

This commit is contained in:
LittleSam129
2026-09-16 18:27:35 +03:00
parent af7c05f2da
commit 95f664076a
403 changed files with 392009 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
"""Отдельная проверка 13-байтного видеозаголовка; формат VIDEO-002 не меняется."""
from __future__ import annotations
import struct
from protocol.video_stream_transport import (
MAX_FRAGMENTS, FrameType, VideoFragment, VideoTransportError,
)
VERSION = 2
HEADER_FORMAT = "!BIIBBH"
HEADER_SIZE = struct.calcsize(HEADER_FORMAT) # 13 байт
def encode(fragment: VideoFragment, max_phy_payload: int) -> bytes:
"""Оставить поток и кадр 32-битными; кодировать count как count-1."""
if not 0 <= fragment.stream_id <= 0xFFFFFFFF or not 0 <= fragment.frame_id <= 0xFFFFFFFF:
raise VideoTransportError("номер потока или кадра вне диапазона")
if not 1 <= fragment.fragment_count <= MAX_FRAGMENTS:
raise VideoTransportError("неверное число фрагментов")
if not 0 <= fragment.fragment_index < fragment.fragment_count:
raise VideoTransportError("неверный номер фрагмента")
if fragment.frame_type not in (FrameType.KEYFRAME, FrameType.DELTA_FRAME):
raise VideoTransportError("неверный тип кадра")
if not 0 <= fragment.age_ms <= 0xFFFF:
raise VideoTransportError("неверный возраст кадра")
if not isinstance(fragment.data, bytes) or not 1 <= len(fragment.data) <= max_phy_payload - HEADER_SIZE:
raise VideoTransportError("данные не помещаются в PHY payload")
flags = (VERSION << 4) | int(fragment.frame_type)
header = struct.pack(HEADER_FORMAT, flags, fragment.stream_id, fragment.frame_id,
fragment.fragment_index, fragment.fragment_count - 1,
fragment.age_ms)
return header + fragment.data
def decode(wire: bytes, max_phy_payload: int) -> VideoFragment:
"""Размер данных берётся из длины внешнего CRC-проверенного payload."""
if not isinstance(wire, bytes) or not HEADER_SIZE < len(wire) <= max_phy_payload:
raise VideoTransportError("длина видеопакета вне диапазона")
flags, stream_id, frame_id, index, count_minus_one, age_ms = struct.unpack(
HEADER_FORMAT, wire[:HEADER_SIZE])
if flags >> 4 != VERSION or (flags & 0x0F) not in (1, 2):
raise VideoTransportError("версия или тип кадра не поддерживается")
count = count_minus_one + 1
if index >= count:
raise VideoTransportError("неверный номер фрагмента")
return VideoFragment(stream_id, frame_id, index, count,
FrameType(flags & 0x0F), age_ms, wire[HEADER_SIZE:])