|
|
|
@ -46,6 +46,7 @@ static struct media_queue video_queue, audio_queue, output_queue; |
|
|
|
static uint64_t list_group, cached_group, list_updated; |
|
|
|
static uint64_t list_group, cached_group, list_updated; |
|
|
|
static char *source_list; |
|
|
|
static char *source_list; |
|
|
|
static void media_process(void *arg); |
|
|
|
static void media_process(void *arg); |
|
|
|
|
|
|
|
static void media_close(struct android_media_session *s, int kind); |
|
|
|
|
|
|
|
|
|
|
|
/* Очереди обмена pthread: LL_QUEUE принадлежит uasync и сюда не подходит. */ |
|
|
|
/* Очереди обмена pthread: LL_QUEUE принадлежит uasync и сюда не подходит. */ |
|
|
|
static void queue_append(struct media_queue *q, struct media_record *record) { |
|
|
|
static void queue_append(struct media_queue *q, struct media_record *record) { |
|
|
|
@ -134,16 +135,18 @@ static void media_event(struct UTUN_INSTANCE *inst, const struct stream_event *e |
|
|
|
&& !viewer.stopping && (event->type != STREAM_EVENT_CLOSED || !stream_handle_active(viewer.handle))) { |
|
|
|
&& !viewer.stopping && (event->type != STREAM_EVENT_CLOSED || !stream_handle_active(viewer.handle))) { |
|
|
|
if (event->type == STREAM_EVENT_DATA) { |
|
|
|
if (event->type == STREAM_EVENT_DATA) { |
|
|
|
int result = stream_media_receiver_feed(viewer.receiver, event->data, event->length); |
|
|
|
int result = stream_media_receiver_feed(viewer.receiver, event->data, event->length); |
|
|
|
if (result != STREAM_OK || viewer.rx_overflow) { |
|
|
|
if (result != STREAM_OK) { |
|
|
|
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "Android viewer malformed/unsupported media id=%llu result=%d; closing", |
|
|
|
|
|
|
|
(unsigned long long)viewer.id, result); |
|
|
|
|
|
|
|
media_close(&viewer, 6); |
|
|
|
|
|
|
|
} else if (viewer.rx_overflow) { |
|
|
|
stream_media_receiver_gap(viewer.receiver); viewer.rx_overflow = 0; |
|
|
|
stream_media_receiver_gap(viewer.receiver); viewer.rx_overflow = 0; |
|
|
|
media_output(viewer.id, 3, NULL, 0, 0, NULL, 0); |
|
|
|
media_output(viewer.id, 3, NULL, 0, 0, NULL, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (event->type == STREAM_EVENT_GAP) { |
|
|
|
} else if (event->type == STREAM_EVENT_GAP) { |
|
|
|
stream_media_receiver_gap(viewer.receiver); media_output(viewer.id, 3, NULL, 0, 0, NULL, 0); |
|
|
|
stream_media_receiver_gap(viewer.receiver); media_output(viewer.id, 3, NULL, 0, 0, NULL, 0); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
media_output(viewer.id, event->type == STREAM_EVENT_END ? 5 : 6, NULL, 0, event->reason, NULL, 0); |
|
|
|
media_close(&viewer, event->type == STREAM_EVENT_END ? 5 : 6); |
|
|
|
stream_close(viewer.handle); viewer.handle = NULL; |
|
|
|
|
|
|
|
stream_media_receiver_destroy(viewer.receiver); viewer.receiver = NULL; viewer.stopping = 1; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
pthread_mutex_unlock(&media_lock); |
|
|
|
pthread_mutex_unlock(&media_lock); |
|
|
|
|