Describe stereo Opus in live media blocks

This commit is contained in:
evgeny committed 2026-10-13 14:14:24 +02:00
1 parent 5f0fff5fd6
commit 22b62699ac
3 files changed
+5 -4

No files matched your search

+2 -2
View File
@@ -19,7 +19,7 @@ struct stream_media_receiver {
static int media_validate(const struct stream_media_block *b, size_t *video_size, size_t *audio_size, uint32_t *first) {
if (!b || b->video_count > STREAM_MEDIA_MAX_ENTRIES || b->audio_count > STREAM_MEDIA_MAX_ENTRIES
|| !b->format.revision || (!b->video_count && !b->audio_count) || b->format.video_codec != STREAM_MEDIA_H264
|| b->format.audio_codec > STREAM_MEDIA_OPUS || !b->format.width || b->format.width > 4096
|| b->format.audio_codec > STREAM_MEDIA_OPUS_STEREO || !b->format.width || b->format.width > 4096
|| !b->format.height || b->format.height > 4096 || b->format.rotation > 270 || b->format.rotation % 90) {
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "media format/count invalid present=%d video=%u audio=%u codecs=%u/%u dimensions=%ux%u rotation=%u",
b != NULL, b ? b->video_count : 0, b ? b->audio_count : 0, b ? b->format.video_codec : 0,
@@ -54,7 +54,7 @@ static int media_validate(const struct stream_media_block *b, size_t *video_size
}
for (unsigned i = 0; i < b->audio_count; i++) {
const struct stream_media_audio *a = &b->audio[i];
if (b->format.audio_codec != STREAM_MEDIA_OPUS || !a->data || !a->length || a->length > STREAM_MEDIA_MAX_OPUS
if (!b->format.audio_codec || !a->data || !a->length || a->length > STREAM_MEDIA_MAX_OPUS
|| a->samples != 960 || a->pts_us > INT64_MAX || (i && a->pts_us <= b->audio[i - 1].pts_us)) {
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "media audio invalid entry=%u length=%u samples=%u", i, a->length, a->samples);
return STREAM_ERR_FORMAT;
+2 -1
View File
@@ -1,7 +1,7 @@
/* Медиаблок внутри одной FEC-пачки: big-endian, uAV1, fixed header(32),
* video descriptors(32 each), audio descriptors(16 each), video bytes, audio bytes.
* video descriptor: frame_id:8, PTS_us:8, frame_size:4, fragment_offset:4, length:4, flags:1, reserved:3.
* audio descriptor: PTS_us:8, length:4, samples:2, reserved:2. Opus: 48kHz mono, 960 samples.
* audio descriptor: PTS_us:8, length:4, samples:2, reserved:2. Opus: 48kHz mono/stereo, 960 frames/channel.
* H.264 Annex B; полный ключевой кадр включает SPS/PPS. Видео меняется по revision; аудиотрек фиксирован на source_epoch.
* first_frame_offset относится к video bytes; UINT32_MAX означает отсутствие начала кадра.
* Parser проверяет весь блок до публикации view. Receiver собирает один кадр, после GAP ждёт KEY.
@@ -25,6 +25,7 @@ extern "C" {
#define STREAM_MEDIA_KEY 1
#define STREAM_MEDIA_H264 1
#define STREAM_MEDIA_OPUS 1
#define STREAM_MEDIA_OPUS_STEREO 2
struct stream_media_format { uint16_t width, height, rotation; uint8_t video_codec, audio_codec; uint32_t revision; };
struct stream_media_video {
@@ -328,7 +328,7 @@ int android_stream_open(uint64_t id, uint64_t group, uint64_t source, unsigned w
} else if (media_schedule() == 0) {
*s = (struct android_media_session){.id = id, .group = group, .source = source, .expected_epoch = expected_epoch,
.opening = 1, .need_key = 1,
.format = {(uint16_t)width, (uint16_t)height, (uint16_t)rotation, STREAM_MEDIA_H264, audio ? STREAM_MEDIA_OPUS : 0, 1}};
.format = {(uint16_t)width, (uint16_t)height, (uint16_t)rotation, STREAM_MEDIA_H264, audio ? STREAM_MEDIA_OPUS_STEREO : 0, 1}};
result = 0;
}
pthread_mutex_unlock(&media_lock); return result;