docs(media): clarify preparation ownership and active protocol commands
This commit is contained in:
1 parent
28bbd62d74
commit
f331d177ca
3 files changed
+32
-23
No files matched your search
@@ -1,10 +1,15 @@
|
||||
/* attachment_send — подготовить голос/видео и отправить в зафиксированный канал или DM. Вызывать trampoline
|
||||
* через uasync_post. Request и PCM/compressor переходят во владение задачи;
|
||||
* pcm_release освобождает pcm_owner, NULL означает PCM из u_malloc.
|
||||
/* attachment_send — подготовить вложение и передать его публикации в зафиксированный канал или DM.
|
||||
* Trampoline вызывается в uasync (обычно через uasync_post), забирает req и PCM/compressor, включая отказ запуска.
|
||||
* Если сам uasync_post не принят, request и его ресурсы остаются у вызывающего.
|
||||
* pcm_release освобождает pcm_owner, NULL означает PCM из u_malloc; release может быть в worker
|
||||
* или в uasync при отказе/отмене без work. Нельзя использовать GUI-объекты, требующие освобождения в UI-потоке.
|
||||
* Qt/Android используют общий результат подготовки, доставка остаётся в chat/dm.
|
||||
* req выделяется u_calloc; caller заполняет target/is_dm, info и source либо PCM. inst должен жить до done.
|
||||
* req выделяется u_calloc; caller заполняет target/is_dm, info и source либо PCM/compressor, строки NUL-терминированы.
|
||||
* inst/config/media_async/uasync живут до завершения задачи. После вызова req нельзя читать или освобождать.
|
||||
* Исходник не изменять во время подготовки; temporary_source разрешает удалить только собственный временный source.
|
||||
* Подготовка выполняется в media_async worker, публикация и attachment-события — в uasync.
|
||||
* output/id/error заполняет задача; temporary_source разрешает удалить принадлежащий приложению source. */
|
||||
* Attachment-события 0/1/2 означают начало/готовность/ошибку подготовки, не подтверждение доставки сообщения.
|
||||
* Подготовленный output затем забирает chat/dm; собственные пути и PCM освобождаются также при отмене. */
|
||||
#ifndef ATTACHMENT_SEND_H
|
||||
#define ATTACHMENT_SEND_H
|
||||
#include "attachment.h"
|
||||
@@ -18,22 +23,23 @@ struct attachment_send_req {
|
||||
char target[64]; /* Десятичный channel_id либо conv_id без префикса dm:, зафиксированный до подготовки. */
|
||||
int is_dm;
|
||||
int encrypted; /* Отдельный случайный ключ группового вложения с ручной выдачей. */
|
||||
char content_type[32]; /* Необязательный исходный MIME (например image/png). */
|
||||
uint64_t dm_generation; /* Захватывается до подготовки и сохраняется во всех её стадиях. */
|
||||
unsigned dm_paths_held;
|
||||
char content_type[32]; /* Исходный MIME только для encrypted channel; пусто → MIME по kind. */
|
||||
uint64_t dm_generation; /* Поколение беседы до подготовки; 0 → захват в trampoline. Удалённое поколение не публикуется. */
|
||||
unsigned dm_paths_held; /* Внутренние holds output/source; caller оставляет 0. */
|
||||
uint8_t reply_to[32]; /* Оригинал канального ответа, зафиксированный до подготовки. */
|
||||
uint64_t request_id; /* CHAT_EVT_MSG_SUBMITTED после публикации либо ошибки. */
|
||||
struct attachment_info info;
|
||||
uint8_t id[16];
|
||||
char source[1024], output[1024];
|
||||
int transcode, temporary_source;
|
||||
uint64_t request_id; /* Только канал: CHAT_EVT_MSG_SUBMITTED после публикации либо ошибки. Для DM — 0. */
|
||||
struct attachment_info info; /* kind обязателен; пустое name заменяется UUID.opus/mp4; для copy нужны готовые метаданные. */
|
||||
uint8_t id[16]; /* Внутренний UUID подготовки для attachment-событий; не UUID конечного media_index/DM. */
|
||||
char source[1024], output[1024]; /* source задаёт caller; output — внутреннее случайное назначение задачи. */
|
||||
int transcode, temporary_source; /* transcode только VIDEO: отдельный FFmpeg worker; иначе файл копируется. */
|
||||
const int16_t* pcm;
|
||||
size_t pcm_count; /* Для voice: int16, 48 кГц моно, число отсчётов. */
|
||||
void* pcm_owner;
|
||||
void (*pcm_release)(void* owner);
|
||||
struct audio_compressor* compressor;
|
||||
int preset, error;
|
||||
void* pcm_owner; /* Аргумент собственного pcm_release. */
|
||||
void (*pcm_release)(void* owner); /* NULL → u_free(pcm); задача вызывает не более одного раза. */
|
||||
struct audio_compressor* compressor; /* Альтернатива PCM: задача flush/читает output/destroy, внешние обращения прекращены. */
|
||||
int preset, error; /* preset: 0..2 для voice; error заполняет worker. */
|
||||
};
|
||||
/* arg — собственный struct attachment_send_req; завершается событиями chat/dm и освобождением req. NULL — no-op. */
|
||||
void attachment_send_trampoline(void* arg);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ struct UTUN_INSTANCE;
|
||||
#define MEDIA_REPL_POLL_TB 300000 // периодическая сверка 30s, включая потерю CHANGED
|
||||
#define MEDIA_REPL_WATCHDOG_TB 2000 // контроль дедлайна/очереди/CM каждые 200ms
|
||||
#define MEDIA_QUERY_TIMEOUT_TB 20000 // таймаут QUERY 2s
|
||||
#define MEDIA_HAVE_BLOCK_TIMEOUT_TB 20000 // таймаут HAVE_BLOCK_ACK 2s
|
||||
#define MEDIA_HAVE_BLOCK_TIMEOUT_TB 20000 // объявлен 2s; текущий HAVE_BLOCK не ждёт ACK и не ставит этот таймер
|
||||
#define MEDIA_DL_STALL_TIMEOUT_TB 20000 // таймаут простоя загрузки 2s (0.1ms)
|
||||
#define MEDIA_DL_MAX_ATTEMPTS 3 // попыток на блок до ошибки
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/* media_delivery_proto — wire-структуры и подкоманды доставки блоков медиа CHAT-группы.
|
||||
* Описывает запросы держателей, чанки, подтверждения наличия и репликацию между суперузлами.
|
||||
* Это формат payload сервиса router, без группового маршрутизационного заголовка; обработчики — media_delivery/download. */
|
||||
* Это формат payload сервиса router, без группового маршрутизационного заголовка; обработчики — media_delivery/download.
|
||||
* Числа SYNC кодируются little endian; остальные packed-поля — native byte order текущего формата.
|
||||
* SERVE_REG/LEAVE меняют только вспомогательный served_nodes; текущий загрузчик их не посылает.
|
||||
* SERVE_ACK сейчас не отправляется, входящие SERVE_ACK/HAVE_BLOCK_ACK игнорируются; ожидания ACK и его retry нет. */
|
||||
#ifndef MEDIA_DELIVERY_PROTO_H
|
||||
#define MEDIA_DELIVERY_PROTO_H
|
||||
|
||||
@@ -13,9 +16,9 @@ extern "C" {
|
||||
/* ── подкоманды (первый байт данных после etcp_router) ── */
|
||||
|
||||
enum {
|
||||
MEDIA_SUBCMD_SERVE_REG = 0x01, // req-узел→суперузел: обслуживай меня
|
||||
MEDIA_SUBCMD_SERVE_ACK = 0x02, // суперузел→req-узел: подтверждение
|
||||
MEDIA_SUBCMD_SERVE_LEAVE = 0x03, // req-узел→суперузел: отключение
|
||||
MEDIA_SUBCMD_SERVE_REG = 0x01, // вспомогательный учёт узла в served_nodes
|
||||
MEDIA_SUBCMD_SERVE_ACK = 0x02, // объявлен, но не отправляется; приём игнорируется
|
||||
MEDIA_SUBCMD_SERVE_LEAVE = 0x03, // удалить вспомогательную запись served_nodes
|
||||
MEDIA_SUBCMD_QUERY = 0x04, // req-узел→суперузел: кто имеет блоки?
|
||||
MEDIA_SUBCMD_QUERY_RESP = 0x05, // суперузел→req-узел: список узлов
|
||||
MEDIA_SUBCMD_HAVE_BLOCK = 0x06, // узел→суперузел: у меня есть блок
|
||||
@@ -34,7 +37,7 @@ enum {
|
||||
|
||||
/* ── ответные статусы ── */
|
||||
|
||||
#define MEDIA_ERR_NOT_SUPERNODE 0xFE
|
||||
#define MEDIA_ERR_NOT_SUPERNODE 0xFE /* Объявлен, в текущих ответах не используется. */
|
||||
|
||||
/* Один QUERY — одна полная пачка результатов, включая блоки без держателей.
|
||||
* Группу и end-to-end отправителя задаёт router. Пределы общие для обеих сторон. */
|
||||
|
||||
Reference in new issue
Block a user