Browse Source

Test frozen clock decoding and single Android read responses

master
evgeny 5 days ago
parent
commit
049480408a
  1. 23
      tests/test_android_stream.c
  2. 26
      tests/test_stream_playback.c

23
tests/test_android_stream.c

@ -39,7 +39,7 @@ static void chat_event(struct UTUN_INSTANCE *inst, int type, const uint8_t *data
static uint8_t *wait_event(uint64_t id, int kind, size_t *size) {
for (unsigned i = 0; i < 1000; i++) {
if (id == 2 && kind == 5) CHECK(android_stream_read_request(id, 1000000, 80000, 80000) == 0);
if (id == 2) CHECK(android_stream_read_request(id, kind == 5 ? 1000000 : -1, 1, 80000) == 0);
uint8_t *data = android_stream_pull(id, size);
if (data && data[0] == kind) return data;
u_free(data); test_clock_poll(ua, 100);
@ -91,7 +91,7 @@ int main(void) {
CHECK(feed(1, 0, 100000, 0, (const uint8_t *)"ops", 3) == 1);
uint8_t *output = NULL; int video_seen = 0, audio_seen = 0;
for (unsigned i = 0; i < 1000 && (!video_seen || !audio_seen); i++) {
CHECK(android_stream_read_request(2, 100000, 80000, 80000) == 0);
CHECK(android_stream_read_request(2, 100000, 1, 80000) == 0);
output = android_stream_pull(2, &size);
if (output && output[0] == 1) {
CHECK(size == sizeof(video) + ANDROID_STREAM_HEADER_SIZE && stream_read_be(output + 8, 8) == 100000 && !memcmp(output + ANDROID_STREAM_HEADER_SIZE, video, sizeof(video)));
@ -115,7 +115,7 @@ int main(void) {
next_format.video_codec = STREAM_MEDIA_H265;
video_seen = audio_seen = 0;
for (unsigned i = 0; i < 1000 && (!video_seen || !audio_seen); i++) {
CHECK(android_stream_read_request(2, 300000, 80000, 80000) == 0);
CHECK(android_stream_read_request(2, 300000, 1, 80000) == 0);
output = android_stream_pull(2, &size);
if (output && output[0] == 1) {
CHECK(stream_read_be(output + 8, 8) == 300000 && stream_read_be(output + 20, 4) == 2 && output[24] == STREAM_MEDIA_H265);
@ -135,7 +135,7 @@ int main(void) {
CHECK(feed(1, 0, audio_pts, 0, (const uint8_t *)"ops", 3) == 1);
video_seen = audio_seen = 0;
for (unsigned i = 0; i < 1000 && (!video_seen || !audio_seen); i++) {
CHECK(android_stream_read_request(2, (int64_t)video_pts, 80000, 80000) == 0);
CHECK(android_stream_read_request(2, (int64_t)video_pts, 1, 80000) == 0);
output = android_stream_pull(2, &size);
if (output && output[0] == 1) {
CHECK(stream_read_be(output + 8, 8) == video_pts && stream_read_be(output + 20, 4) == next_format.revision);
@ -150,6 +150,21 @@ int main(void) {
struct stream_member_state after_switch;
CHECK(stream_member_load(inst, group, inst->node_id, &after_switch, NULL) == STREAM_OK);
CHECK(after_switch.published && after_switch.source.source_epoch == member.source.source_epoch);
/* Повторные запросы готовят один ответ; получение ответа не создаёт скрытую следующую копию. */
for (unsigned i = 0; i < 5; i++)
CHECK(android_stream_feed(1, 1, 800000 + i * 40000, 0, video, sizeof(video), &next_format) == 1);
for (unsigned i = 0; i < 50; i++) { CHECK(android_stream_read_request(2, 700000, 1, -1) == 0); test_clock_poll(ua, 100); }
output = android_stream_pull(2, &size); CHECK(output && output[0] == 1 && stream_read_be(output + 8, 8) == 800000); u_free(output);
test_clock_run_for(ua, 1000); CHECK(!android_stream_pull(2, &size));
CHECK(android_stream_read_request(2, 700000, 0, -1) == 0); test_clock_run_for(ua, 1000);
CHECK(!android_stream_pull(2, &size));
for (unsigned frame = 1; frame < 5; frame++) {
output = NULL;
for (unsigned i = 0; i < 1000 && !output; i++) {
CHECK(android_stream_read_request(2, 700000, 1, -1) == 0); test_clock_poll(ua, 100); output = android_stream_pull(2, &size);
}
CHECK(output && output[0] == 1 && stream_read_be(output + 8, 8) == 800000 + frame * 40000); u_free(output);
}
android_stream_stop(1); u_free(wait_event(2, 5, &size)); android_stream_stop(2); u_free(wait_event(1, 5, &size));
while ((output = android_stream_pull(2, &size))) u_free(output);
CHECK(!strcmp(source_snapshot, "[]"));

26
tests/test_stream_playback.c

@ -155,6 +155,30 @@ static void test_shared_media_ring(void) {
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "[PASS] media ring: independent readers, authenticated frozen parts, lookahead, expiry, GAP and EOF");
}
/* Конвейер decoder получает восемь кадров при неподвижных часах; запрет видео сохраняет его cursor. */
static void test_decoder_demand(void) {
uint8_t key[32] = {4}; struct stream_encoder *encoder = NULL; struct stream_buffer *buffer = NULL;
struct stream_media_store *store = NULL; struct stream_media_cursor *cursor = NULL;
CHECK(stream_encoder_create(&encoder, &descriptor, key) == STREAM_OK);
CHECK(stream_buffer_create(&buffer, &descriptor, stream_encoder_public_key(encoder), 256 * 1300) == STREAM_OK);
CHECK(stream_media_store_create(&store, buffer, &descriptor) == STREAM_OK);
CHECK(stream_media_cursor_create(&cursor, store, 3) == STREAM_OK);
for (unsigned i = 0; i < 8; i++) append_media(encoder, buffer, store, i, i * 66666u, i ? 0 : STREAM_MEDIA_KEY, 0);
struct stream_media_packet packet;
CHECK(stream_media_cursor_read(cursor, 0, 0, -1, &packet) == STREAM_WAIT);
for (unsigned i = 0; i < 8; i++) {
CHECK(stream_media_cursor_read(cursor, 0, 1, -1, &packet) == STREAM_OK && packet.kind == STREAM_MEDIA_READ_VIDEO);
CHECK(packet.video.pts_us == i * 66666u);
if (i == 2) {
CHECK(stream_media_cursor_read(cursor, 0, 0, 0, &packet) == STREAM_OK && packet.kind == STREAM_MEDIA_READ_AUDIO);
CHECK(packet.audio.pts_us == 0);
}
}
CHECK(stream_media_cursor_read(cursor, 0, 2, -1, &packet) == STREAM_ERR_ARGUMENT);
stream_media_cursor_destroy(cursor); stream_media_store_destroy(store); stream_buffer_destroy(buffer); stream_encoder_destroy(encoder);
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "[PASS] decoder demand: eight frames beyond 80ms at frozen PTS, independent audio and disabled video cursor");
}
/* Полный кадр уже в общем кольце: MORE продолжает ограниченную сборку без новых сетевых событий. */
static void test_large_frame_budget(void) {
uint8_t key[32] = {2}; struct stream_encoder *encoder = NULL; struct stream_buffer *buffer = NULL;
@ -239,7 +263,7 @@ int main(void) {
size_t allocations = u_get_allocated_count();
for (unsigned i = 0; i < sizeof(video_bytes); i++) video_bytes[i] = (uint8_t)(i * 71 + 3);
test_history_correction(); test_catchup_device_queue(); test_invalid_and_sampling_gap(); test_shared_media_ring();
test_large_frame_budget(); test_media_discontinuity();
test_decoder_demand(); test_large_frame_budget(); test_media_discontinuity();
CHECK(u_get_allocated_count() == allocations);
return 0;
}

Loading…
Cancel
Save