Files
utun2/tools/chatgui-android/libutun_lite/stream_bridge.h
T

84 lines
8.0 KiB
C
Raw 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.
/* Android-очереди live media: attach/detach только в uasync, вне callbacks.
* UI/кодировщики используют только session_id, никогда не сохраняют inst/ua.
* Один publisher и независимые viewers, TX <=2MiB/128 records/250мс, RX — ограниченный батч на viewer.
* Data принимает полные access units пяти кодеков uAV2 (KEY: config_length:4/config/frame) и Opus 48k mono/stereo/20ms.
* pull передаёт u_malloc-буфер последовательных записей:
* kind:1,flags:1,width:2,height:2,rotation:2,PTS_us:8,length:4,revision:4,codec:1,reserved:3,data.
* kinds: video=1,audio=2,gap=3,opened=4,ended=5,error=6,video_end=7,audio_end=8; error.flags = stream_close_reason.
* Конец трека следует за его media; GAP/error отменяют старые записи. Числа big-endian.
* Медиаданные передаются через pull, не через общий чатовый event bus; полученный буфер освобождает caller через u_free.
* Команды/снимки защищены bridge mutex, signal имеет свой mutex; callers используют API из frontend/media workers.
* После detach команды получают отказ/пустой результат, read_request с допустимыми параметрами возвращает 0. */
#ifndef ANDROID_STREAM_BRIDGE_H
#define ANDROID_STREAM_BRIDGE_H
#include <stddef.h>
#include <stdint.h>
#include "../../../src/stream/stream_buffer.h"
struct UTUN_INSTANCE;
struct stream_media_format;
struct stream_media_status;
struct stream_viewer_telemetry;
struct android_stream_signal;
#define ANDROID_STREAM_HEADER_SIZE 28
struct android_stream_tx_stats {
/* ID сеанса, время снимка в мкс; video/audio/stream — очереди publisher, transport/inflight/acked_1s — всего instance.
* total_bytes — сумма video/audio/stream/transport/inflight; байты ACK за 1с в неё не входят. */
uint64_t id, sample_us, video_bytes, audio_bytes, stream_bytes, transport_bytes, inflight_bytes, acked_1s, total_bytes;
/* Число соединений в общем ETCP-снимке. */
unsigned connections;
/* Позиции получателей в кольце, обновляются раз в 500мс. */
struct stream_buffer_positions buffer;
};
/* Снимок publisher обновляется в uasync каждые 100мс; getter копирует под mutex. 0/-1, ошибка не меняет stats. */
int android_stream_tx_snapshot(uint64_t id, struct android_stream_tx_stats *stats);
/* 0 attached, -1 invalid/busy: нельзя передать singleton другому ядру до detach старого. */
int android_stream_attach(struct UTUN_INSTANCE *inst);
/* Тот же inst: отменить watch, закрыть managers/сеансы и снять привязку; повтор допустим. */
void android_stream_detach(struct UTUN_INSTANCE *inst);
/* id/group ненулевые. source=0 — publisher: width/height=1..4096, rotation=0/90/180/270, codec=H264..H266.
* source!=0 — viewer с обязательным expected_epoch; размеры/rotation игнорируются. codec проверяется в обоих режимах.
* audio включает Opus stereo у publisher либо получение аудио viewer. 0 — команда принята, -1 — отказ; результат через pull.
* Publisher ID занят до получения ended/error через pull; viewer ID — до обработки stop в uasync. */
int android_stream_open(uint64_t id, uint64_t group, uint64_t source, unsigned width, unsigned height,
unsigned rotation, int audio, uint64_t expected_epoch, unsigned codec);
/* Наблюдение канала через CHAT_EVT_STREAM_SOURCES; group=0 снимает его. 0 — поставлено, -1 — отказ;
* несколько команд до исполнения сливаются в последнюю. */
int android_stream_watch(uint64_t group);
/* Publisher: 0 — команда mute/unmute принята, -1 — нет сеанса/аудиотрека; codec/эпоха не меняются.
* Producer сам заглушает PCM; эта команда только публикует состояние. */
int android_stream_set_audio_enabled(uint64_t id, int enabled);
/* Publisher: pts — мкс <=INT64_MAX, строго растёт отдельно по трекам; data копируется на вызове.
* Видео требует format с revision/размером/поворотом; новая revision принимается атомарно с KEY.
* Для аудио format/key игнорируются. 1 — принято в очередь, 0 — drop (video: запросить KEY), -1 — отказ. */
int android_stream_feed(uint64_t id, int video, uint64_t pts, int key, const uint8_t *data, size_t length,
const struct stream_media_format *format);
/* Асинхронный stop: publisher дренирует очередь и держит FIN 2с; viewer снимает reader и notify.
* Уже выданный pull-буфер остаётся у caller. Старый/нулевой ID допустим. */
void android_stream_stop(uint64_t id);
/* Передать owned батч; length обязателен, NULL/length=0 — сейчас нет данных либо ошибка.
* Publisher выдаёт opened/ended/error без demand; viewer — также media по read_request. */
uint8_t *android_stream_pull(uint64_t id, size_t *length);
/* Один батч на запрос: до video кадров и records записей, звук до position_us+audio_ahead_us.
* video=0..records, records=1..16; audio_ahead_us=-1 выключает звук, иначе 0..60000000; position_us<0 — прогрев до KEY.
* Повторный demand заменяет прежний. 0 — параметры допустимы (даже для неизвестного ID/после detach), -1 — неверные параметры.
* CLOSED/END доступны pull после закрытия cursor; указатели кольца остаются в uasync. */
int android_stream_read_request(uint64_t id, int64_t position_us, unsigned video, int64_t audio_ahead_us, unsigned records);
/* Viewer-снимки: 0 — скопировано, -1 — неверные аргументы/ID; ошибка не меняет выход. */
int android_stream_get_status(uint64_t id, struct stream_media_status *status);
int android_stream_get_telemetry(uint64_t id, struct stream_viewer_telemetry *telemetry);
/* Viewer: очистить старый батч и искать ближайший KEY; 0 — принято, -1 — отказ. */
int android_stream_resync(uint64_t id);
/* Worker владеет signal; create привязывает его к открытому viewer. Готовность/stop/detach будят wait.
* signal также будит worker после расходования PCM. Уведомления сливаются, но не теряются до wait.
* create возвращает NULL при ошибке. На viewer допускается один signal/notify.
* destroy — только после stream_stop или detach и остановки всех внешних signal/wait callers. */
struct android_stream_signal *android_stream_signal_create(uint64_t id);
void android_stream_signal_notify(struct android_stream_signal *signal);
/* 1 — уведомление, 0 — deadline, -1 — ошибка; timeout_ms 0..50, ожидание не держит mutex ядра/bridge. */
int android_stream_signal_wait(struct android_stream_signal *signal, unsigned timeout_ms);
void android_stream_signal_destroy(struct android_stream_signal *signal);
#endif