#!/usr/bin/env bash
#
# Copyright 2026 Jason Wolff
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0. You may use, modify and
# redistribute this file provided this notice is preserved. See LICENSE and
# NOTICE in the project root. Copyright remains with the author.
#
# dvr2mp4 - convert 2007-era 4-channel DVR recordings into playable MP4.
#
#   dvr2mp4 <session-dir-or-file> [output-dir]
#
# The recorder writes files named *.mp4 that are NOT MP4: each frame is
# wrapped in a proprietary header beginning FF FF 00 01, and the MPEG-4 Part 2
# stream inside carries no VOS/VOL headers, so no player can determine the
# frame size. This strips the wrappers and synthesises the missing header.
#
# Parameters were established by decoding against this recorder's own output:
#   352x240 (CIF), quant_type 0, complexity estimation disabled,
#   vop_time_increment_resolution 1.  Anything else decodes to smear.
#
# Camera channel names live in the session's rec_id file.

set -uo pipefail

SRC="${1:-}"
OUTDIR="${2:-$HOME/dvr-converted}"
FPS="${DVR_FPS:-15}"
EXTRACT=/usr/local/share/drive-triage/dvr_extract.py

if [ -z "$SRC" ]; then
    sed -n '3,6p' "$0" | sed 's/^# \{0,1\}//'
    exit 1
fi
command -v ffmpeg >/dev/null || { echo "dvr2mp4: ffmpeg is not installed" >&2; exit 1; }
[ -f "$EXTRACT" ] || { echo "dvr2mp4: missing $EXTRACT" >&2; exit 1; }

mkdir -p "$OUTDIR"

convert_one() {
    local f="$1" label="$2" out="$3"
    local tmp; tmp=$(mktemp /tmp/dvr.XXXXXX.m4v)
    python3 "$EXTRACT" "$f" "$tmp" >/dev/null 2>&1 || { rm -f "$tmp"; return 1; }
    if ffmpeg -hide_banner -loglevel error -r "$FPS" -i "$tmp" -c:v copy -y "$out" 2>/dev/null; then
        printf '  %-28s -> %s\n' "$label" "$out"
    else
        printf '  %-28s FAILED\n' "$label"
    fi
    rm -f "$tmp"
}

if [ -f "$SRC" ]; then
    convert_one "$SRC" "$(basename "$SRC")" "$OUTDIR/$(basename "${SRC%.*}").mp4"
    exit 0
fi

[ -d "$SRC" ] || { echo "dvr2mp4: no such file or directory: $SRC" >&2; exit 1; }

# Channel names, if the session recorded them.
declare -a NAMES=()
if [ -f "$SRC/rec_id" ]; then
    # Names are NUL-separated fixed-width fields starting at 0x25, and one of
    # them may contain a space - splitting on whitespace would break it in two.
    while IFS= read -r n; do
        n="${n#"${n%%[! ]*}"}"; n="${n%"${n##*[! ]}"}"   # trim both ends
        [ -n "$n" ] && NAMES+=("${n// /_}")
    done < <(tail -c +38 "$SRC/rec_id" 2>/dev/null | tr '\0' '\n' | head -12)
fi

SESSION=$(basename "$SRC")
echo "Session $SESSION"
[ "${#NAMES[@]}" -gt 0 ] && echo "  cameras: ${NAMES[*]}"

shopt -s nullglob
for f in "$SRC"/[0-9].mp4; do
    idx=$(basename "$f" .mp4)
    name="${NAMES[$idx]:-ch$idx}"
    convert_one "$f" "channel $idx ($name)" "$OUTDIR/${SESSION}-${idx}-${name}.mp4"
done

echo
echo "Done. Play them with:  celluloid $OUTDIR/  (or any player)"
