#!/usr/bin/env python3
"""vcd_toc.py —— 用 SG_IO READ TOC(format 0) 读光盘轨道表（正确处理 8 字节描述符）
用法: sudo python3 vcd_toc.py [/dev/sr0]
"""
import os, struct, sys
sys.path.insert(0, "/home/zyw/Downloads/vcd-rip")
from sgio import sg_io, SG_DXFER_FROM_DEV

DEV = sys.argv[1] if len(sys.argv) > 1 else "/dev/sr0"
fd = os.open(DEV, os.O_RDONLY | os.O_NONBLOCK)
try:
    data, st, host, drv, sb, resid = sg_io(fd, [0x43, 0x00, 0x00, 0, 0, 0, 0x03, 0x40, 804 >> 8, 804 & 0xFF],
                                          804, SG_DXFER_FROM_DEV)
    if st != 0 or not data or len(data) < 4:
        print(f"READ TOC 失败 status={st} sense={sb.hex()}"); raise SystemExit(1)
    toc_len = struct.unpack(">H", data[0:2])[0]
    first, last = data[2], data[3]
    print(f"TOC 长度={toc_len}  首轨={first}  末轨={last}")
    print(f"{'轨':<6}{'类型':<8}{'LBA':>9}    {'MSF':<11}{'时长':>10}  ctrl")
    prev = None; tracks = []; lead = None
    off = 4
    while off + 8 <= min(len(data), toc_len + 2):
        sess = data[off]
        adr_ctrl = data[off + 1]
        tno = data[off + 2]        # 对 format 0 即 track number
        point = data[off + 3]
        m, s, f = data[off + 4], data[off + 5], data[off + 6]
        ctrl = (adr_ctrl >> 4) & 0xF
        kind = "audio" if (ctrl & 0x4) == 0 else "data"
        lba = (m * 60 + s) * 75 + f - 150
        dur = f"{(lba - prev) / 75:.1f}s" if prev is not None else "—"
        label = "LEAD-OUT" if tno == 0xAA else str(tno)
        print(f"{label:<6}{kind:<8}{lba:>9}    {m:02d}:{s:02d}:{f:02d}   {dur:>10}  0x{ctrl:x}")
        if tno == 0xAA: lead = lba
        else: tracks.append((tno, kind, lba))
        if tno != 0xAA: prev = lba
        off += 8
    # 容量
    d2, st2, *_ = sg_io(fd, [0x25, 0, 0, 0, 0, 0, 0, 0, 0], 8, SG_DXFER_FROM_DEV)
    if st2 == 0 and d2 and len(d2) == 8:
        last_lba, bs = struct.unpack(">II", d2)
        print(f"\n设备容量: 最后 LBA={last_lba} ({(last_lba+1)*2048/1e6:.1f} MB @2048B)")
    if lead: print(f"TOC lead-out: {lead}")
    data_n = sum(1 for t in tracks if t[1] == "data")
    print(f"汇总: {len(tracks)} 轨（data {data_n} / audio {len(tracks)-data_n}）")
    if tracks:
        print(f"首轨起始 LBA = {tracks[0][2]}（此前扇区属 lead-in，读不到是正常的）")
finally:
    os.close(fd)
