Browse Source

Register indexed media reads and retain only two working blocks

master
evgeny 6 days ago
parent
commit
dc7cebaa65
  1. 2
      src/Makefile.am
  2. 22
      src/stream/stream_media_buffer.c

2
src/Makefile.am

@ -18,6 +18,8 @@ stream_core_files = \
stream/stream_proto.h \
stream/stream_media.h \
stream/stream_media.c \
stream/stream_media_buffer.h \
stream/stream_media_buffer.c \
stream/stream_playback_clock.h \
stream/stream_playback_clock.c \
stream/stream_block.h \

22
src/stream/stream_media_buffer.c

@ -3,6 +3,7 @@
#include "../../lib/debug_config.h"
#include "../../lib/mem.h"
#include "../../lib/u_async.h"
#include "stream_media_buffer.h"
struct media_position {
@ -35,6 +36,7 @@ struct stream_media_cursor {
uint8_t *scratch[2], *frame;
size_t scratch_capacity, frame_capacity;
uint64_t scratch_seq[2];
size_t scratch_length[2];
int scratch_valid[2];
unsigned scratch_next;
uint8_t opus[STREAM_MEDIA_MAX_OPUS];
@ -163,6 +165,11 @@ int stream_media_store_feed(struct stream_media_store *s, uint64_t seq, const ui
for (unsigned i = 0; i < b.video_count; i++) {
const struct stream_media_video *v = &b.video[i];
if (!v->offset) {
if (s->video_us >= 0 && ((int64_t)v->pts_us <= s->video_us || v->frame_id <= s->last_frame_id)) {
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "media index stale video seq=%llu frame=%llu pts=%llu",
(unsigned long long)seq, (unsigned long long)v->frame_id, (unsigned long long)v->pts_us);
continue;
}
if (s->pending_used) {
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "media index incomplete frame=%llu before frame=%llu; require KEY",
(unsigned long long)s->pending.frame_id, (unsigned long long)v->frame_id);
@ -281,16 +288,9 @@ static int cursor_block(struct stream_media_cursor *c, uint64_t seq, struct stre
slot = c->scratch_next++ % 2;
int result = stream_buffer_decode(s->buffer, seq, c->scratch[slot], c->scratch_capacity, &length);
if (result != STREAM_OK) return result == STREAM_REJECTED ? STREAM_GAP : result;
c->scratch_seq[slot] = seq; c->scratch_valid[slot] = 1;
c->scratch_seq[slot] = seq; c->scratch_length[slot] = length; c->scratch_valid[slot] = 1;
} else {
/* length сохраняется в первом поле зарезервированного хвоста не нужна: длину даёт metadata RS. */
const uint8_t *wire; uint64_t actual; size_t wire_length;
int found = STREAM_GAP;
for (unsigned sub = 0; sub < s->descriptor.n; sub++) {
found = stream_buffer_read(s->buffer, seq, (uint8_t)sub, &wire, &wire_length, &actual);
if (found == STREAM_OK) { length = (size_t)stream_read_be(wire + STREAM_BLOCK_LENGTH_OFF, 4); break; }
}
if (found != STREAM_OK) return found;
length = c->scratch_length[slot];
}
return stream_media_parse(c->scratch[slot], length, block);
}
@ -323,6 +323,8 @@ static int cursor_video(struct stream_media_cursor *c, struct stream_media_packe
int result = cursor_peek(c, &c->video, 1, &b, &pts);
if (result != STREAM_OK) return result;
const struct stream_media_video *v = &b.video[c->video.entry++];
if (!c->key_delivered && !c->pending.frame_size
&& (v->offset || !(v->flags & STREAM_MEDIA_KEY) || pts != c->start_us)) continue;
if (!v->offset) {
if (!c->key_delivered && (!(v->flags & STREAM_MEDIA_KEY) || pts != c->start_us)) continue;
if (v->frame_size > c->frame_capacity) {
@ -370,7 +372,7 @@ int stream_media_cursor_read(struct stream_media_cursor *c, int64_t position, in
if (c->audio.ended && c->video.ended) {
*packet = (struct stream_media_packet){.kind = STREAM_MEDIA_READ_END}; return STREAM_OK;
}
int64_t limit = position < 0 ? c->start_us : position + lookahead;
int64_t limit = position < 0 ? c->start_us : position > INT64_MAX - lookahead ? INT64_MAX : position + lookahead;
if (ar == STREAM_OK && audio_pts <= limit && (audio_pts < video_pts || vr != STREAM_OK)) {
/* video peek мог переиспользовать scratch аудио: заново взять ту же пачку из двухэлементного cache. */
result = cursor_block(c, c->audio.seq, &audio);

Loading…
Cancel
Save