|
|
|
@ -59,6 +59,13 @@ void output(StreamRecord record) { |
|
|
|
|
|
|
|
|
|
|
|
/* Только uasync под lock; снимает собственное владение подпиской, не транспорт других владельцев. */ |
|
|
|
/* Только uasync под lock; снимает собственное владение подпиской, не транспорт других владельцев. */ |
|
|
|
void closeViewer(StreamRecordKind kind, int reason) { |
|
|
|
void closeViewer(StreamRecordKind kind, int reason) { |
|
|
|
|
|
|
|
if (kind == StreamRecordKind::Closed) { |
|
|
|
|
|
|
|
for (auto i = bridge.output.begin(); i != bridge.output.end();) { |
|
|
|
|
|
|
|
if (i->id == bridge.viewer.id && (i->kind == StreamRecordKind::Video || i->kind == StreamRecordKind::Audio)) { |
|
|
|
|
|
|
|
bridge.bytes -= static_cast<size_t>(i->data.size()); i = bridge.output.erase(i); |
|
|
|
|
|
|
|
} else ++i; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if (bridge.viewer.id) output({bridge.viewer.id, 0, kind, {}, 0, reason}); |
|
|
|
if (bridge.viewer.id) output({bridge.viewer.id, 0, kind, {}, 0, reason}); |
|
|
|
if (bridge.handle) stream_close(bridge.handle); |
|
|
|
if (bridge.handle) stream_close(bridge.handle); |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop viewer released id=%llu reason=%d", |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop viewer released id=%llu reason=%d", |
|
|
|
@ -144,10 +151,16 @@ void process(void*) { |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop media index failed result=%d", statusResult); |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop media index failed result=%d", statusResult); |
|
|
|
closeViewer(StreamRecordKind::Closed, STREAM_CLOSE_FAILED); return; |
|
|
|
closeViewer(StreamRecordKind::Closed, STREAM_CLOSE_FAILED); return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!bridge.wantRead || bridge.output.size() >= 2 || bridge.bytes + STREAM_MEDIA_MAX_FRAME > 4u * 1024u * 1024u) return; |
|
|
|
unsigned prepared = 0; |
|
|
|
|
|
|
|
for (const auto& record : bridge.output) |
|
|
|
|
|
|
|
if (record.id == bridge.viewer.id && (record.kind == StreamRecordKind::Video || record.kind == StreamRecordKind::Audio)) prepared++; |
|
|
|
|
|
|
|
if (!bridge.wantRead || prepared >= 2 || bridge.bytes + STREAM_MEDIA_MAX_FRAME > 4u * 1024u * 1024u) return; |
|
|
|
bridge.wantRead = false; |
|
|
|
bridge.wantRead = false; |
|
|
|
stream_media_packet packet{}; |
|
|
|
stream_media_packet packet{}; |
|
|
|
int result = stream_media_read(bridge.handle, bridge.position, bridge.videoAhead, bridge.audioAhead, &packet); |
|
|
|
int result = stream_media_read(bridge.handle, bridge.position, bridge.videoAhead, bridge.audioAhead, &packet); |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop media read id=%llu PTS=%lld ahead=%lld/%lld result=%d kind=%d prepared=%u records=%zu", |
|
|
|
|
|
|
|
(unsigned long long)bridge.viewer.id, (long long)bridge.position, (long long)bridge.videoAhead, |
|
|
|
|
|
|
|
(long long)bridge.audioAhead, result, result == STREAM_OK ? (int)packet.kind : -1, prepared, bridge.output.size()); |
|
|
|
if (stream_media_get_status(bridge.handle, &bridge.status) < 0) result = STREAM_ERR_FORMAT; |
|
|
|
if (stream_media_get_status(bridge.handle, &bridge.status) < 0) result = STREAM_ERR_FORMAT; |
|
|
|
if (result == STREAM_OK) { |
|
|
|
if (result == STREAM_OK) { |
|
|
|
if (packet.kind == STREAM_MEDIA_READ_END) closeViewer(StreamRecordKind::End, 0); |
|
|
|
if (packet.kind == STREAM_MEDIA_READ_END) closeViewer(StreamRecordKind::End, 0); |
|
|
|
|