Commit graph

3 commits

Author SHA1 Message Date
Deivid Soto
63be565227 test(hls): cubrir -forced_idr de QSV en el rate-control 2026-06-10 12:00:33 +02:00
Deivid Soto
556c5cb05f fix(hls): forced-idr en NVENC/QSV — los segmentos ignoraban force_key_frames
NVENC (ffmpeg 6.1 + drivers actuales) emite los keyframes forzados por
-force_key_frames como I-frames NO-IDR; el muxer HLS solo corta en IDR,
así que cada segmento se estiraba en silencio al GOP por defecto
(250 frames ≈ 10.4 s @24fps) mientras la playlist server-side seguía
prometiendo 2 s por segmento. Con los PTS reales ~5× fuera del mapa de
la playlist, los seeks aterrizaban donde podían y los subtítulos se
desincronizaban en cuanto se mezclaban segmentos de runs distintos
(seek-restart) en el mismo dir.

Medido: 3 segmentos por 30 s de encode en vez de 15; con -forced-idr 1
exactamente 15, y post-fix seg-150/151/158 arrancan en 300.0/302.0/316.0
clavados. Afecta a TODO el HLS por NVENC histórico (no era del rate
control nuevo: la config de bitrate fijo producía lo mismo). QSV recibe
su grafía -forced_idr. Las entradas de caché viejas nunca llegaron a
sellarse (el conteo de segmentos no cuadraba), así que no hay migración:
solo sesiones vivas estaban afectadas.
2026-06-10 10:44:18 +02:00
Deivid Soto
9b97aedfe4 feat(hls): resume-aware first spawn + capped-CRF/CQ rate control
- HLSSessionConfig.StartSec (sync StreamSession.startSec): el primer
  ffmpeg arranca ya seekeado en el punto de resume (-ss +
  -output_ts_offset + -start_number, misma maquinaria que el
  seek-restart) en vez de encodear desde seg-0 para morir en el
  seek-restart inmediato del player (doble spawn, resume lento).
  readyMax se pre-siembra al índice de arranque; el ready-watcher
  compara ReadyCount() > WriterStartIdx() para no marcar "ready" antes
  del primer segmento real. startSec >= duración → arranque desde 0
  (resume obsoleto de un fichero reemplazado).
- Rate control: capped constant-quality donde el encoder lo hace bien —
  libx264 -crf 23, NVENC -cq 23 -b:v 0 — con el mismo -maxrate de
  siempre y -bufsize 2x (antes 1x estrangulaba picos). Escenas fáciles
  emiten muchos menos bits (menos stalls vía funnel/LTE); el peor caso
  no cambia. QSV/VideoToolbox/VAAPI conservan el triple de bitrate fijo
  probado (sus knobs de calidad tienen gotchas de vendor).
- Limpieza: wrapper buildHLSFFmpegArgs y guard startIdx<0 muertos.
2026-06-10 00:21:15 +02:00