Files
gx fa6ab3069a Phase 7 audio mixing — attempt + rollback + lessons
Несколько сессий попыток реализовать audio mixing в композитор'е.
Не достигнуто sub-секундной latency со стабильным video+audio.
Откатано на parallel mode (cfc-grid video-only, live от pipeline с audio).

Полный набор выводов и pitfall'ов — docs/LESSONS-audio-mixing-attempts.md.

Главные lesson'ы для будущей попытки:
- mpegts mux libavformat авто-инсёртит h264_mp4toannexb BSF которому
  не нравится Annex-B + inline SPS/PPS — NVENC OUTPUT_SPSPPS per-frame ломает
- SPSC ring drop newest при full, не oldest (consumer's domain)
- av_new_packet (не av_malloc) для av_interleaved_write_frame ownership
- Monotonic PTS на counter (frame_idx, total_samples) — не wallclock
- mediamtx env-var path names не должны иметь '-' (parser limitation)
- Default mediamtx ReadTimeout=10s короткий для burst write'ов

Изменения в repo сохранены для будущей доработки:
- src/writer.c — mpegts backend с audio stream support
- src/audio.c — RTSP AAC consumer + lock-free SPSC ring
- include/cuframes_composer/{writer,audio}.h — public API
- examples/grid_record.c — --format=mpegts + --audio-source flags
- include/cuframes_composer/composer.h — consumer_prefix field
- docker/Dockerfile — libavformat-dev добавлен в builder/runtime

cfc-grid composer стабильно работает на видео (substantially лучше
монолитного pipeline'а с audio bag'ом). TV рекомендуется использовать
rtsp://...:554/cfc-grid + опционально rtsp://...:554/live-audio
parallel.
2026-06-03 14:29:56 +01:00

67 lines
2.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* cuframes-composer — audio consumer (Phase 7).
*
* Открывает RTSP-вход с AAC stream'ом (от cuda-grid-audio через mediamtx
* либо прямо с микрофона). В отдельном thread'е читает packet'ы и кладёт
* в lock-free SPSC ring buffer. Video-thread (composer main loop) drain'ит
* ring и пишет audio packet'ы в общий mpegts muxer через
* cfc_writer_write_audio.
*
* Architecture:
* audio_thread: avformat_open_input → av_read_frame loop → push to ring
* main thread (video): cfc_audio_drain → cfc_writer_write_audio loop
*
* Failure mode: если RTSP source падает, audio_thread пытается reconnect
* с exponential backoff. Video не блокируется.
*
* Лицензия: LGPL-2.1+
*/
#ifndef CUFRAMES_COMPOSER_AUDIO_H
#define CUFRAMES_COMPOSER_AUDIO_H
#include "writer.h"
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct cfc_audio_config {
const char *rtsp_url; /* "rtsp://mediamtx:8554/live-audio" */
int reconnect_min_ms; /* default 1000 */
int reconnect_max_ms; /* default 10000 */
} cfc_audio_config_t;
typedef struct cfc_audio cfc_audio_t;
/* Создать audio consumer + запустить background thread.
* Получает первый packet и сохраняет codec params (sample_rate, channels,
* extradata) — caller потом передаёт их в cfc_writer_config_t. */
int cfc_audio_create(const cfc_audio_config_t *cfg, cfc_audio_t **out);
/* Получить codec params (заполняется после первого успешного read).
* Возвращает 0 если params уже доступны, -1 если ещё нет. Caller может
* polling'ом ждать. */
int cfc_audio_get_codec_params(
cfc_audio_t *a,
int *sample_rate,
int *channels,
const uint8_t **extradata,
size_t *extradata_size
);
/* Drain до N audio packet'ов в writer. Не блокируется. Возвращает число
* записанных packet'ов. */
int cfc_audio_drain(cfc_audio_t *a, cfc_writer_t *writer, int max_packets);
/* Остановить thread + освободить ресурсы. */
int cfc_audio_destroy(cfc_audio_t *a);
#ifdef __cplusplus
}
#endif
#endif /* CUFRAMES_COMPOSER_AUDIO_H */