/* attachment_send — подготовить голос/видео и отправить в зафиксированный канал или DM. Вызывать trampoline * через uasync_post. Request и PCM/compressor переходят во владение задачи; * pcm_release освобождает pcm_owner, NULL означает PCM из u_malloc. * Qt/Android используют общий результат подготовки, доставка остаётся в chat/dm. * req выделяется u_calloc; caller заполняет target/is_dm, info и source либо PCM. inst должен жить до done. * Подготовка выполняется в media_async worker, публикация и attachment-события — в uasync. * output/id/error заполняет задача; temporary_source разрешает удалить принадлежащий приложению source. */ #ifndef ATTACHMENT_SEND_H #define ATTACHMENT_SEND_H #include "attachment.h" struct UTUN_INSTANCE; struct audio_compressor; #ifdef __cplusplus extern "C" { #endif struct attachment_send_req { struct UTUN_INSTANCE* inst; 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; 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; 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 attachment_send_trampoline(void* arg); #ifdef __cplusplus } #endif #endif