|
|
|
|
@ -151,7 +151,7 @@ static void media_event(struct UTUN_INSTANCE *inst, const struct stream_event *e
|
|
|
|
|
|
|
|
|
|
/* Publisher держит конечное окно выдачи после FIN; abrupt detach ничего не обещает получателям. */ |
|
|
|
|
static void media_close(struct android_media_session *s, int kind) { |
|
|
|
|
media_output(s->id, kind, NULL, 0, 0, NULL, 0); |
|
|
|
|
if (kind) media_output(s->id, kind, NULL, 0, 0, NULL, 0); |
|
|
|
|
if (s->handle) stream_close(s->handle); |
|
|
|
|
stream_media_receiver_destroy(s->receiver); |
|
|
|
|
if (s == &publisher) { queue_clear(&video_queue); queue_clear(&audio_queue); } |
|
|
|
|
@ -217,8 +217,8 @@ static void media_list_sources(void) {
|
|
|
|
|
struct stream_member_state state; |
|
|
|
|
if (stream_member_load(media_inst, group_id, node, &state, NULL) != STREAM_OK || !state.published) continue; |
|
|
|
|
if (count >= 256) { DEBUG_WARN(DEBUG_CATEGORY_STREAM, "Android stream source list truncated group=%llx", (unsigned long long)group_id); break; } |
|
|
|
|
if (strbuf_addf(&json, "%s{\"id\":\"%llu\",\"epoch\":\"%016llx\",\"name\":", count ? "," : "", |
|
|
|
|
(unsigned long long)node, (unsigned long long)state.source.source_epoch) < 0 |
|
|
|
|
if (strbuf_addf(&json, "%s{\"id\":\"%llu\",\"epoch\":\"%016llx\",\"self\":%d,\"name\":", count ? "," : "", |
|
|
|
|
(unsigned long long)node, (unsigned long long)state.source.source_epoch, node == media_inst->node_id) < 0 |
|
|
|
|
|| strbuf_add_json_string(&json, (const char *)sqlite3_column_text(statement, 1)) < 0 |
|
|
|
|
|| strbuf_addf(&json, "}") < 0) { failed = 1; break; } |
|
|
|
|
count++; |
|
|
|
|
@ -316,8 +316,9 @@ void android_stream_detach(struct UTUN_INSTANCE *inst) {
|
|
|
|
|
if (media_timer) uasync_cancel_timeout(inst->ua, media_timer); |
|
|
|
|
media_post = NULL; media_timer = NULL; |
|
|
|
|
stream_set_event_callback(inst, NULL, NULL); |
|
|
|
|
if (publisher.id) media_close(&publisher, 6); |
|
|
|
|
if (viewer.id) media_close(&viewer, 6); |
|
|
|
|
queue_clear(&output_queue); |
|
|
|
|
if (publisher.id) media_close(&publisher, 0); |
|
|
|
|
if (viewer.id) media_close(&viewer, 0); |
|
|
|
|
media_inst = NULL; |
|
|
|
|
u_free(source_list); source_list = NULL; list_group = cached_group = list_updated = 0; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "Android stream bridge detached; producers rejected"); |
|
|
|
|
|