/* cuframes-composer — обвязка вокруг NVIDIA NVENC API. * * Динамически грузит libnvidia-encode.so через dlopen, чтобы пакет * cuframes-composer оставался под LGPL-2.1+ без статической линковки * проприетарного SDK. См. дизайн-документ часть 1.6. * * Принимает на вход CUdeviceptr на NV12 frame (zero-copy через * NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR + nvEncRegisterResource). * Выдаёт сжатый H.264 bitstream через callback (caller записывает его * в файл / RTP-пакетизирует / etc). * * Lifecycle: * create(cfg) — open session, init encoder * encode_frame(...) — на каждый входной кадр (один CUdeviceptr) * flush(...) — в конце потока, чтобы вытащить остатки B-кадров * destroy(...) — закрыть session, выгрузить SDK * * Поток должен быть single-threaded для одного encoder'а (NVENC API * не реентрабельный для одной сессии). * * Лицензия: LGPL-2.1+ */ #ifndef CUFRAMES_COMPOSER_NVENC_H #define CUFRAMES_COMPOSER_NVENC_H #include #include #include #ifdef __cplusplus extern "C" { #endif /* Параметры кодировщика. Для Phase 1 минимальный набор; в будущих фазах * будут расширяться для RTSP (rate control, GOP, intra-refresh, и т.п.). */ typedef struct cfc_encoder_config { CUcontext cuda_ctx; /* CUDA-контекст, в котором лежат входные VMM-буферы */ int32_t width; /* ширина кадра в пикселях */ int32_t height; /* высота кадра в пикселях */ int32_t fps_num; /* числитель частоты кадров (25) */ int32_t fps_den; /* знаменатель частоты кадров (1) */ int32_t bitrate_kbps; /* битрейт в килобитах в секунду (5000 = 5 Мбит/с) */ int32_t gop_size; /* интервал между keyframe'ами в кадрах (25 = 1 IDR в секунду) */ int32_t num_b_frames; /* B-кадры (0 для low-latency RTSP) */ /* Пресет — соответствует NV_ENC_TUNING_INFO + preset GUID. * "ll" = low-latency, "p4" = preset P4 (баланс), "p7" = highest quality. */ const char *preset; /* "ll", "p4", "p7" — по умолчанию "ll" */ } cfc_encoder_config_t; typedef struct cfc_encoder cfc_encoder_t; /* Callback для записанного H.264 bitstream'а. Вызывается синхронно из * cfc_encoder_encode_frame / cfc_encoder_flush. Указатель действителен только * на время вызова (буфер NVENC будет разблокирован после возврата). */ typedef void (*cfc_encoder_output_cb)( const uint8_t *bitstream, /* данные H.264 (Annex B byte stream) */ size_t size, /* размер в байтах */ int64_t pts_ns, /* presentation timestamp (передан в encode_frame) */ int is_idr, /* 1 если кадр IDR (keyframe) */ void *user /* user data, переданный в encode_frame */ ); /* Создать encoder. Возвращает 0 при успехе. */ int cfc_encoder_create(const cfc_encoder_config_t *cfg, cfc_encoder_t **out); /* Закодировать один кадр. ptr — CUdeviceptr на начало NV12 frame в VRAM, * pitch — ширина строки в байтах (для NV12 равна width). * * Callback может быть вызван 0 или 1 раз для одного encode_frame: NVENC * может буферизовать кадры внутри (особенно при B-кадрах). Чтобы вытащить * последние буферизованные — вызвать flush в конце потока. */ int cfc_encoder_encode_frame( cfc_encoder_t *enc, CUdeviceptr ptr, int pitch, int64_t pts_ns, cfc_encoder_output_cb cb, void *user ); /* Завершить поток. Передаёт NVENC флаг end-of-stream, выдаёт оставшиеся * закодированные кадры через callback. После flush encoder можно либо * destroy, либо использовать снова с новым GOP'ом. */ int cfc_encoder_flush( cfc_encoder_t *enc, cfc_encoder_output_cb cb, void *user ); /* Выдать SPS/PPS — заголовки H.264 sequence/picture parameter sets. * Нужны для записи в начало MP4-контейнера или для отправки в SDP при RTSP. */ int cfc_encoder_get_sequence_params( cfc_encoder_t *enc, uint8_t *out, /* буфер caller'а */ size_t *inout_size /* при вызове — размер буфера, при возврате — реальный размер */ ); /* Закрыть encoder, выгрузить SDK. */ int cfc_encoder_destroy(cfc_encoder_t *enc); #ifdef __cplusplus } #endif #endif /* CUFRAMES_COMPOSER_NVENC_H */