mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-04-21 01:33:36 +00:00
The packet sink push_session() callback is optional, but it was called
unconditionnally even when not implemented, leading to a segfault.
Bug introduced by commit 78cba1b7c2.
Fixes #6687 <https://github.com/Genymobile/scrcpy/issues/6687>
88 lines
2.4 KiB
C
88 lines
2.4 KiB
C
#include "packet_source.h"
|
|
|
|
#include <assert.h>
|
|
|
|
void
|
|
sc_packet_source_init(struct sc_packet_source *source) {
|
|
source->sink_count = 0;
|
|
}
|
|
|
|
void
|
|
sc_packet_source_add_sink(struct sc_packet_source *source,
|
|
struct sc_packet_sink *sink) {
|
|
assert(source->sink_count < SC_PACKET_SOURCE_MAX_SINKS);
|
|
assert(sink);
|
|
assert(sink->ops);
|
|
source->sinks[source->sink_count++] = sink;
|
|
}
|
|
|
|
static void
|
|
sc_packet_source_sinks_close_firsts(struct sc_packet_source *source,
|
|
unsigned count) {
|
|
while (count) {
|
|
struct sc_packet_sink *sink = source->sinks[--count];
|
|
sink->ops->close(sink);
|
|
}
|
|
}
|
|
|
|
bool
|
|
sc_packet_source_sinks_open(struct sc_packet_source *source,
|
|
AVCodecContext *ctx,
|
|
const struct sc_stream_session *session) {
|
|
assert(source->sink_count);
|
|
for (unsigned i = 0; i < source->sink_count; ++i) {
|
|
struct sc_packet_sink *sink = source->sinks[i];
|
|
if (!sink->ops->open(sink, ctx, session)) {
|
|
sc_packet_source_sinks_close_firsts(source, i);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
sc_packet_source_sinks_close(struct sc_packet_source *source) {
|
|
assert(source->sink_count);
|
|
sc_packet_source_sinks_close_firsts(source, source->sink_count);
|
|
}
|
|
|
|
bool
|
|
sc_packet_source_sinks_push(struct sc_packet_source *source,
|
|
const AVPacket *packet) {
|
|
assert(source->sink_count);
|
|
for (unsigned i = 0; i < source->sink_count; ++i) {
|
|
struct sc_packet_sink *sink = source->sinks[i];
|
|
if (!sink->ops->push(sink, packet)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
sc_packet_source_sinks_push_session(struct sc_packet_source *source,
|
|
const struct sc_stream_session *session) {
|
|
assert(source->sink_count);
|
|
for (unsigned i = 0; i < source->sink_count; ++i) {
|
|
struct sc_packet_sink *sink = source->sinks[i];
|
|
if (sink->ops->push_session
|
|
&& !sink->ops->push_session(sink, session)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
sc_packet_source_sinks_disable(struct sc_packet_source *source) {
|
|
assert(source->sink_count);
|
|
for (unsigned i = 0; i < source->sink_count; ++i) {
|
|
struct sc_packet_sink *sink = source->sinks[i];
|
|
if (sink->ops->disable) {
|
|
sink->ops->disable(sink);
|
|
}
|
|
}
|
|
}
|