Register indexed media reads and retain only two working blocks
This commit is contained in:
1 parent
126aa9df10
commit
dc7cebaa65
2 files changed
+14
-10
No files matched your search
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user