You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

58 lines
3.7 KiB

/* Индекс медиапотока поверх общего RS-кольца: хранит только позиции/PTS, без копии кодированного потока.
* Один uasync-поток; store принадлежит stream-session, cursor — конкретному локальному reader.
* feed получает уже проверенные последовательные пачки; gap обозначает окончательно потерянный диапазон.
* Независимые audio/video позиции читают оригинал из кольца. Рабочая память cursor — один H264 кадр,
* один Opus-пакет и два scratch медиаблока. Курсоры ничего не закрепляют против вытеснения.
* read возвращает заимствованный packet до следующего read/destroy; frontend копирует только ближайшие записи.
* WAIT — материал ещё не готов/дальше lookahead. GAP/EXPIRED требуют новой точки KEY; END — весь материал выдан. */
#ifndef STREAM_MEDIA_BUFFER_H
#define STREAM_MEDIA_BUFFER_H
#include "stream_buffer.h"
#include "stream_media.h"
#ifdef __cplusplus
extern "C" {
#endif
#define STREAM_MEDIA_INDEX_BYTES (4u * 1024u * 1024u)
#define STREAM_MEDIA_READ_AHEAD_US 80000
#define STREAM_MEDIA_PREROLL_US 500000
#define STREAM_MEDIA_TRACK_VIDEO 1
#define STREAM_MEDIA_TRACK_AUDIO 2
struct stream_media_store;
struct stream_media_cursor;
enum stream_media_read_kind { STREAM_MEDIA_READ_VIDEO, STREAM_MEDIA_READ_AUDIO, STREAM_MEDIA_READ_END };
struct stream_media_packet {
enum stream_media_read_kind kind;
struct stream_media_format format;
struct stream_media_video video;
struct stream_media_audio audio;
};
struct stream_media_status {
int64_t ready_us, video_us, audio_us, start_us;
uint64_t generation;
int initialized, audio_enabled, finished, video_ended, audio_ended;
};
int stream_media_store_create(struct stream_media_store **out, struct stream_buffer *buffer, const struct stream_descriptor *descriptor);
void stream_media_store_destroy(struct stream_media_store *store);
int stream_media_store_feed(struct stream_media_store *store, uint64_t seq, const uint8_t *data, size_t length);
void stream_media_store_gap(struct stream_media_store *store, uint64_t first, uint64_t last);
void stream_media_store_finish(struct stream_media_store *store);
void stream_media_store_trim(struct stream_media_store *store);
int stream_media_cursor_create(struct stream_media_cursor **out, struct stream_media_store *store, unsigned tracks);
void stream_media_cursor_destroy(struct stream_media_cursor *cursor);
void stream_media_cursor_reset(struct stream_media_cursor *cursor);
int stream_media_cursor_status(struct stream_media_cursor *cursor, struct stream_media_status *status);
/* position_us<0 — старт: прогреть аудио перед выбранным KEY. Затем отдавать только до position_us+lookahead_us.
* При GAP/EXPIRED cursor сбрасывают отдельно: это позволяет frontend сначала обработать разрыв.
* Бюджет одного вызова ограничен; WAIT при сборке длинного кадра допускает повтор сразу/по следующему событию. */
int stream_media_cursor_read(struct stream_media_cursor *cursor, int64_t position_us, int64_t video_ahead_us, int64_t audio_ahead_us,
struct stream_media_packet *packet);
#ifdef __cplusplus
}
#endif
#endif