Rename stream to sc_demuxer
For consistency with recorder and decoder, name the component which demuxes a "demuxer". And add the missing sc_ prefix.
This commit is contained in:
parent
4ee62abe1d
commit
7dec225ceb
4 changed files with 142 additions and 91 deletions
|
@ -9,6 +9,7 @@ src = [
|
||||||
'src/control_msg.c',
|
'src/control_msg.c',
|
||||||
'src/controller.c',
|
'src/controller.c',
|
||||||
'src/decoder.c',
|
'src/decoder.c',
|
||||||
|
'src/demuxer.c',
|
||||||
'src/device_msg.c',
|
'src/device_msg.c',
|
||||||
'src/icon.c',
|
'src/icon.c',
|
||||||
'src/file_pusher.c',
|
'src/file_pusher.c',
|
||||||
|
@ -24,7 +25,6 @@ src = [
|
||||||
'src/scrcpy.c',
|
'src/scrcpy.c',
|
||||||
'src/screen.c',
|
'src/screen.c',
|
||||||
'src/server.c',
|
'src/server.c',
|
||||||
'src/stream.c',
|
|
||||||
'src/video_buffer.c',
|
'src/video_buffer.c',
|
||||||
'src/util/acksync.c',
|
'src/util/acksync.c',
|
||||||
'src/util/file.c',
|
'src/util/file.c',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "stream.h"
|
#include "demuxer.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libavutil/time.h>
|
#include <libavutil/time.h>
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
#define NO_PTS UINT64_C(-1)
|
#define NO_PTS UINT64_C(-1)
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
stream_recv_packet(struct stream *stream, AVPacket *packet) {
|
sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) {
|
||||||
// The video stream contains raw packets, without time information. When we
|
// The video stream contains raw packets, without time information. When we
|
||||||
// record, we retrieve the timestamps separately, from a "meta" header
|
// record, we retrieve the timestamps separately, from a "meta" header
|
||||||
// added by the server before each raw packet.
|
// added by the server before each raw packet.
|
||||||
|
@ -30,7 +30,7 @@ stream_recv_packet(struct stream *stream, AVPacket *packet) {
|
||||||
// It is followed by <packet_size> bytes containing the packet/frame.
|
// It is followed by <packet_size> bytes containing the packet/frame.
|
||||||
|
|
||||||
uint8_t header[HEADER_SIZE];
|
uint8_t header[HEADER_SIZE];
|
||||||
ssize_t r = net_recv_all(stream->socket, header, HEADER_SIZE);
|
ssize_t r = net_recv_all(demuxer->socket, header, HEADER_SIZE);
|
||||||
if (r < HEADER_SIZE) {
|
if (r < HEADER_SIZE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ stream_recv_packet(struct stream *stream, AVPacket *packet) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = net_recv_all(stream->socket, packet->data, len);
|
r = net_recv_all(demuxer->socket, packet->data, len);
|
||||||
if (r < 0 || ((uint32_t) r) < len) {
|
if (r < 0 || ((uint32_t) r) < len) {
|
||||||
av_packet_unref(packet);
|
av_packet_unref(packet);
|
||||||
return false;
|
return false;
|
||||||
|
@ -57,9 +57,9 @@ stream_recv_packet(struct stream *stream, AVPacket *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
push_packet_to_sinks(struct stream *stream, const AVPacket *packet) {
|
push_packet_to_sinks(struct sc_demuxer *demuxer, const AVPacket *packet) {
|
||||||
for (unsigned i = 0; i < stream->sink_count; ++i) {
|
for (unsigned i = 0; i < demuxer->sink_count; ++i) {
|
||||||
struct sc_packet_sink *sink = stream->sinks[i];
|
struct sc_packet_sink *sink = demuxer->sinks[i];
|
||||||
if (!sink->ops->push(sink, packet)) {
|
if (!sink->ops->push(sink, packet)) {
|
||||||
LOGE("Could not send config packet to sink %d", i);
|
LOGE("Could not send config packet to sink %d", i);
|
||||||
return false;
|
return false;
|
||||||
|
@ -70,12 +70,12 @@ push_packet_to_sinks(struct stream *stream, const AVPacket *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
stream_parse(struct stream *stream, AVPacket *packet) {
|
sc_demuxer_parse(struct sc_demuxer *demuxer, AVPacket *packet) {
|
||||||
uint8_t *in_data = packet->data;
|
uint8_t *in_data = packet->data;
|
||||||
int in_len = packet->size;
|
int in_len = packet->size;
|
||||||
uint8_t *out_data = NULL;
|
uint8_t *out_data = NULL;
|
||||||
int out_len = 0;
|
int out_len = 0;
|
||||||
int r = av_parser_parse2(stream->parser, stream->codec_ctx,
|
int r = av_parser_parse2(demuxer->parser, demuxer->codec_ctx,
|
||||||
&out_data, &out_len, in_data, in_len,
|
&out_data, &out_len, in_data, in_len,
|
||||||
AV_NOPTS_VALUE, AV_NOPTS_VALUE, -1);
|
AV_NOPTS_VALUE, AV_NOPTS_VALUE, -1);
|
||||||
|
|
||||||
|
@ -84,13 +84,13 @@ stream_parse(struct stream *stream, AVPacket *packet) {
|
||||||
(void) r;
|
(void) r;
|
||||||
assert(out_len == in_len);
|
assert(out_len == in_len);
|
||||||
|
|
||||||
if (stream->parser->key_frame == 1) {
|
if (demuxer->parser->key_frame == 1) {
|
||||||
packet->flags |= AV_PKT_FLAG_KEY;
|
packet->flags |= AV_PKT_FLAG_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet->dts = packet->pts;
|
packet->dts = packet->pts;
|
||||||
|
|
||||||
bool ok = push_packet_to_sinks(stream, packet);
|
bool ok = push_packet_to_sinks(demuxer, packet);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LOGE("Could not process packet");
|
LOGE("Could not process packet");
|
||||||
return false;
|
return false;
|
||||||
|
@ -100,57 +100,57 @@ stream_parse(struct stream *stream, AVPacket *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
stream_push_packet(struct stream *stream, AVPacket *packet) {
|
sc_demuxer_push_packet(struct sc_demuxer *demuxer, AVPacket *packet) {
|
||||||
bool is_config = packet->pts == AV_NOPTS_VALUE;
|
bool is_config = packet->pts == AV_NOPTS_VALUE;
|
||||||
|
|
||||||
// A config packet must not be decoded immediately (it contains no
|
// A config packet must not be decoded immediately (it contains no
|
||||||
// frame); instead, it must be concatenated with the future data packet.
|
// frame); instead, it must be concatenated with the future data packet.
|
||||||
if (stream->pending || is_config) {
|
if (demuxer->pending || is_config) {
|
||||||
size_t offset;
|
size_t offset;
|
||||||
if (stream->pending) {
|
if (demuxer->pending) {
|
||||||
offset = stream->pending->size;
|
offset = demuxer->pending->size;
|
||||||
if (av_grow_packet(stream->pending, packet->size)) {
|
if (av_grow_packet(demuxer->pending, packet->size)) {
|
||||||
LOG_OOM();
|
LOG_OOM();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
stream->pending = av_packet_alloc();
|
demuxer->pending = av_packet_alloc();
|
||||||
if (!stream->pending) {
|
if (!demuxer->pending) {
|
||||||
LOG_OOM();
|
LOG_OOM();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (av_new_packet(stream->pending, packet->size)) {
|
if (av_new_packet(demuxer->pending, packet->size)) {
|
||||||
LOG_OOM();
|
LOG_OOM();
|
||||||
av_packet_free(&stream->pending);
|
av_packet_free(&demuxer->pending);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(stream->pending->data + offset, packet->data, packet->size);
|
memcpy(demuxer->pending->data + offset, packet->data, packet->size);
|
||||||
|
|
||||||
if (!is_config) {
|
if (!is_config) {
|
||||||
// prepare the concat packet to send to the decoder
|
// prepare the concat packet to send to the decoder
|
||||||
stream->pending->pts = packet->pts;
|
demuxer->pending->pts = packet->pts;
|
||||||
stream->pending->dts = packet->dts;
|
demuxer->pending->dts = packet->dts;
|
||||||
stream->pending->flags = packet->flags;
|
demuxer->pending->flags = packet->flags;
|
||||||
packet = stream->pending;
|
packet = demuxer->pending;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_config) {
|
if (is_config) {
|
||||||
// config packet
|
// config packet
|
||||||
bool ok = push_packet_to_sinks(stream, packet);
|
bool ok = push_packet_to_sinks(demuxer, packet);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// data packet
|
// data packet
|
||||||
bool ok = stream_parse(stream, packet);
|
bool ok = sc_demuxer_parse(demuxer, packet);
|
||||||
|
|
||||||
if (stream->pending) {
|
if (demuxer->pending) {
|
||||||
// the pending packet must be discarded (consumed or error)
|
// the pending packet must be discarded (consumed or error)
|
||||||
av_packet_free(&stream->pending);
|
av_packet_free(&demuxer->pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
|
@ -161,25 +161,25 @@ stream_push_packet(struct stream *stream, AVPacket *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stream_close_first_sinks(struct stream *stream, unsigned count) {
|
sc_demuxer_close_first_sinks(struct sc_demuxer *demuxer, unsigned count) {
|
||||||
while (count) {
|
while (count) {
|
||||||
struct sc_packet_sink *sink = stream->sinks[--count];
|
struct sc_packet_sink *sink = demuxer->sinks[--count];
|
||||||
sink->ops->close(sink);
|
sink->ops->close(sink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
stream_close_sinks(struct stream *stream) {
|
sc_demuxer_close_sinks(struct sc_demuxer *demuxer) {
|
||||||
stream_close_first_sinks(stream, stream->sink_count);
|
sc_demuxer_close_first_sinks(demuxer, demuxer->sink_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
stream_open_sinks(struct stream *stream, const AVCodec *codec) {
|
sc_demuxer_open_sinks(struct sc_demuxer *demuxer, const AVCodec *codec) {
|
||||||
for (unsigned i = 0; i < stream->sink_count; ++i) {
|
for (unsigned i = 0; i < demuxer->sink_count; ++i) {
|
||||||
struct sc_packet_sink *sink = stream->sinks[i];
|
struct sc_packet_sink *sink = demuxer->sinks[i];
|
||||||
if (!sink->ops->open(sink, codec)) {
|
if (!sink->ops->open(sink, codec)) {
|
||||||
LOGE("Could not open packet sink %d", i);
|
LOGE("Could not open packet sink %d", i);
|
||||||
stream_close_first_sinks(stream, i);
|
sc_demuxer_close_first_sinks(demuxer, i);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,8 +188,8 @@ stream_open_sinks(struct stream *stream, const AVCodec *codec) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
run_stream(void *data) {
|
run_demuxer(void *data) {
|
||||||
struct stream *stream = data;
|
struct sc_demuxer *demuxer = data;
|
||||||
|
|
||||||
const AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
const AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
||||||
if (!codec) {
|
if (!codec) {
|
||||||
|
@ -197,26 +197,26 @@ run_stream(void *data) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->codec_ctx = avcodec_alloc_context3(codec);
|
demuxer->codec_ctx = avcodec_alloc_context3(codec);
|
||||||
if (!stream->codec_ctx) {
|
if (!demuxer->codec_ctx) {
|
||||||
LOG_OOM();
|
LOG_OOM();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stream_open_sinks(stream, codec)) {
|
if (!sc_demuxer_open_sinks(demuxer, codec)) {
|
||||||
LOGE("Could not open stream sinks");
|
LOGE("Could not open demuxer sinks");
|
||||||
goto finally_free_codec_ctx;
|
goto finally_free_codec_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->parser = av_parser_init(AV_CODEC_ID_H264);
|
demuxer->parser = av_parser_init(AV_CODEC_ID_H264);
|
||||||
if (!stream->parser) {
|
if (!demuxer->parser) {
|
||||||
LOGE("Could not initialize parser");
|
LOGE("Could not initialize parser");
|
||||||
goto finally_close_sinks;
|
goto finally_close_sinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We must only pass complete frames to av_parser_parse2()!
|
// We must only pass complete frames to av_parser_parse2()!
|
||||||
// It's more complicated, but this allows to reduce the latency by 1 frame!
|
// It's more complicated, but this allows to reduce the latency by 1 frame!
|
||||||
stream->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
|
demuxer->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
|
||||||
|
|
||||||
AVPacket *packet = av_packet_alloc();
|
AVPacket *packet = av_packet_alloc();
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
|
@ -225,13 +225,13 @@ run_stream(void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bool ok = stream_recv_packet(stream, packet);
|
bool ok = sc_demuxer_recv_packet(demuxer, packet);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
// end of stream
|
// end of stream
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = stream_push_packet(stream, packet);
|
ok = sc_demuxer_push_packet(demuxer, packet);
|
||||||
av_packet_unref(packet);
|
av_packet_unref(packet);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
// cannot process packet (error already logged)
|
// cannot process packet (error already logged)
|
||||||
|
@ -241,58 +241,58 @@ run_stream(void *data) {
|
||||||
|
|
||||||
LOGD("End of frames");
|
LOGD("End of frames");
|
||||||
|
|
||||||
if (stream->pending) {
|
if (demuxer->pending) {
|
||||||
av_packet_free(&stream->pending);
|
av_packet_free(&demuxer->pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
av_packet_free(&packet);
|
av_packet_free(&packet);
|
||||||
finally_close_parser:
|
finally_close_parser:
|
||||||
av_parser_close(stream->parser);
|
av_parser_close(demuxer->parser);
|
||||||
finally_close_sinks:
|
finally_close_sinks:
|
||||||
stream_close_sinks(stream);
|
sc_demuxer_close_sinks(demuxer);
|
||||||
finally_free_codec_ctx:
|
finally_free_codec_ctx:
|
||||||
avcodec_free_context(&stream->codec_ctx);
|
avcodec_free_context(&demuxer->codec_ctx);
|
||||||
end:
|
end:
|
||||||
stream->cbs->on_eos(stream, stream->cbs_userdata);
|
demuxer->cbs->on_eos(demuxer, demuxer->cbs_userdata);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
stream_init(struct stream *stream, sc_socket socket,
|
sc_demuxer_init(struct sc_demuxer *demuxer, sc_socket socket,
|
||||||
const struct stream_callbacks *cbs, void *cbs_userdata) {
|
const struct sc_demuxer_callbacks *cbs, void *cbs_userdata) {
|
||||||
stream->socket = socket;
|
demuxer->socket = socket;
|
||||||
stream->pending = NULL;
|
demuxer->pending = NULL;
|
||||||
stream->sink_count = 0;
|
demuxer->sink_count = 0;
|
||||||
|
|
||||||
assert(cbs && cbs->on_eos);
|
assert(cbs && cbs->on_eos);
|
||||||
|
|
||||||
stream->cbs = cbs;
|
demuxer->cbs = cbs;
|
||||||
stream->cbs_userdata = cbs_userdata;
|
demuxer->cbs_userdata = cbs_userdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
stream_add_sink(struct stream *stream, struct sc_packet_sink *sink) {
|
sc_demuxer_add_sink(struct sc_demuxer *demuxer, struct sc_packet_sink *sink) {
|
||||||
assert(stream->sink_count < STREAM_MAX_SINKS);
|
assert(demuxer->sink_count < SC_DEMUXER_MAX_SINKS);
|
||||||
assert(sink);
|
assert(sink);
|
||||||
assert(sink->ops);
|
assert(sink->ops);
|
||||||
stream->sinks[stream->sink_count++] = sink;
|
demuxer->sinks[demuxer->sink_count++] = sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
stream_start(struct stream *stream) {
|
sc_demuxer_start(struct sc_demuxer *demuxer) {
|
||||||
LOGD("Starting stream thread");
|
LOGD("Starting demuxer thread");
|
||||||
|
|
||||||
bool ok =
|
bool ok = sc_thread_create(&demuxer->thread, run_demuxer, "scrcpy-demuxer",
|
||||||
sc_thread_create(&stream->thread, run_stream, "scrcpy-stream", stream);
|
demuxer);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LOGC("Could not start stream thread");
|
LOGC("Could not start demuxer thread");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
stream_join(struct stream *stream) {
|
sc_demuxer_join(struct sc_demuxer *demuxer) {
|
||||||
sc_thread_join(&stream->thread, NULL);
|
sc_thread_join(&demuxer->thread, NULL);
|
||||||
}
|
}
|
51
app/src/demuxer.h
Normal file
51
app/src/demuxer.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef SC_DEMUXER_H
|
||||||
|
#define SC_DEMUXER_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavformat/avformat.h>
|
||||||
|
|
||||||
|
#include "trait/packet_sink.h"
|
||||||
|
#include "util/net.h"
|
||||||
|
#include "util/thread.h"
|
||||||
|
|
||||||
|
#define SC_DEMUXER_MAX_SINKS 2
|
||||||
|
|
||||||
|
struct sc_demuxer {
|
||||||
|
sc_socket socket;
|
||||||
|
sc_thread thread;
|
||||||
|
|
||||||
|
struct sc_packet_sink *sinks[SC_DEMUXER_MAX_SINKS];
|
||||||
|
unsigned sink_count;
|
||||||
|
|
||||||
|
AVCodecContext *codec_ctx;
|
||||||
|
AVCodecParserContext *parser;
|
||||||
|
// successive packets may need to be concatenated, until a non-config
|
||||||
|
// packet is available
|
||||||
|
AVPacket *pending;
|
||||||
|
|
||||||
|
const struct sc_demuxer_callbacks *cbs;
|
||||||
|
void *cbs_userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sc_demuxer_callbacks {
|
||||||
|
void (*on_eos)(struct sc_demuxer *demuxer, void *userdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_demuxer_init(struct sc_demuxer *demuxer, sc_socket socket,
|
||||||
|
const struct sc_demuxer_callbacks *cbs, void *cbs_userdata);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_demuxer_add_sink(struct sc_demuxer *demuxer, struct sc_packet_sink *sink);
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_demuxer_start(struct sc_demuxer *demuxer);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_demuxer_join(struct sc_demuxer *demuxer);
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "decoder.h"
|
#include "decoder.h"
|
||||||
|
#include "demuxer.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "file_pusher.h"
|
#include "file_pusher.h"
|
||||||
#include "keyboard_inject.h"
|
#include "keyboard_inject.h"
|
||||||
|
@ -22,7 +23,6 @@
|
||||||
#include "recorder.h"
|
#include "recorder.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "stream.h"
|
|
||||||
#ifdef HAVE_USB
|
#ifdef HAVE_USB
|
||||||
# include "usb/aoa_hid.h"
|
# include "usb/aoa_hid.h"
|
||||||
# include "usb/hid_keyboard.h"
|
# include "usb/hid_keyboard.h"
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
struct scrcpy {
|
struct scrcpy {
|
||||||
struct sc_server server;
|
struct sc_server server;
|
||||||
struct sc_screen screen;
|
struct sc_screen screen;
|
||||||
struct stream stream;
|
struct sc_demuxer demuxer;
|
||||||
struct sc_decoder decoder;
|
struct sc_decoder decoder;
|
||||||
struct sc_recorder recorder;
|
struct sc_recorder recorder;
|
||||||
#ifdef HAVE_V4L2
|
#ifdef HAVE_V4L2
|
||||||
|
@ -231,8 +231,8 @@ av_log_callback(void *avcl, int level, const char *fmt, va_list vl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stream_on_eos(struct stream *stream, void *userdata) {
|
sc_demuxer_on_eos(struct sc_demuxer *demuxer, void *userdata) {
|
||||||
(void) stream;
|
(void) demuxer;
|
||||||
(void) userdata;
|
(void) userdata;
|
||||||
|
|
||||||
PUSH_EVENT(EVENT_STREAM_STOPPED);
|
PUSH_EVENT(EVENT_STREAM_STOPPED);
|
||||||
|
@ -285,7 +285,7 @@ scrcpy(struct scrcpy_options *options) {
|
||||||
#ifdef HAVE_V4L2
|
#ifdef HAVE_V4L2
|
||||||
bool v4l2_sink_initialized = false;
|
bool v4l2_sink_initialized = false;
|
||||||
#endif
|
#endif
|
||||||
bool stream_started = false;
|
bool demuxer_started = false;
|
||||||
#ifdef HAVE_USB
|
#ifdef HAVE_USB
|
||||||
bool aoa_hid_initialized = false;
|
bool aoa_hid_initialized = false;
|
||||||
bool hid_keyboard_initialized = false;
|
bool hid_keyboard_initialized = false;
|
||||||
|
@ -395,17 +395,17 @@ scrcpy(struct scrcpy_options *options) {
|
||||||
|
|
||||||
av_log_set_callback(av_log_callback);
|
av_log_set_callback(av_log_callback);
|
||||||
|
|
||||||
static const struct stream_callbacks stream_cbs = {
|
static const struct sc_demuxer_callbacks demuxer_cbs = {
|
||||||
.on_eos = stream_on_eos,
|
.on_eos = sc_demuxer_on_eos,
|
||||||
};
|
};
|
||||||
stream_init(&s->stream, s->server.video_socket, &stream_cbs, NULL);
|
sc_demuxer_init(&s->demuxer, s->server.video_socket, &demuxer_cbs, NULL);
|
||||||
|
|
||||||
if (dec) {
|
if (dec) {
|
||||||
stream_add_sink(&s->stream, &dec->packet_sink);
|
sc_demuxer_add_sink(&s->demuxer, &dec->packet_sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rec) {
|
if (rec) {
|
||||||
stream_add_sink(&s->stream, &rec->packet_sink);
|
sc_demuxer_add_sink(&s->demuxer, &rec->packet_sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sc_controller *controller = NULL;
|
struct sc_controller *controller = NULL;
|
||||||
|
@ -625,21 +625,21 @@ aoa_hid_end:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// now we consumed the header values, the socket receives the video stream
|
// now we consumed the header values, the socket receives the video stream
|
||||||
// start the stream
|
// start the demuxer
|
||||||
if (!stream_start(&s->stream)) {
|
if (!sc_demuxer_start(&s->demuxer)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
stream_started = true;
|
demuxer_started = true;
|
||||||
|
|
||||||
ret = event_loop(s);
|
ret = event_loop(s);
|
||||||
LOGD("quit...");
|
LOGD("quit...");
|
||||||
|
|
||||||
// Close the window immediately on closing, because screen_destroy() may
|
// Close the window immediately on closing, because screen_destroy() may
|
||||||
// only be called once the stream thread is joined (it may take time)
|
// only be called once the demuxer thread is joined (it may take time)
|
||||||
sc_screen_hide_window(&s->screen);
|
sc_screen_hide_window(&s->screen);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
// The stream is not stopped explicitly, because it will stop by itself on
|
// The demuxer is not stopped explicitly, because it will stop by itself on
|
||||||
// end-of-stream
|
// end-of-stream
|
||||||
#ifdef HAVE_USB
|
#ifdef HAVE_USB
|
||||||
if (aoa_hid_initialized) {
|
if (aoa_hid_initialized) {
|
||||||
|
@ -671,10 +671,10 @@ end:
|
||||||
sc_server_stop(&s->server);
|
sc_server_stop(&s->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now that the sockets are shutdown, the stream and controller are
|
// now that the sockets are shutdown, the demuxer and controller are
|
||||||
// interrupted, we can join them
|
// interrupted, we can join them
|
||||||
if (stream_started) {
|
if (demuxer_started) {
|
||||||
stream_join(&s->stream);
|
sc_demuxer_join(&s->demuxer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_V4L2
|
#ifdef HAVE_V4L2
|
||||||
|
@ -693,7 +693,7 @@ end:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Destroy the screen only after the stream is guaranteed to be finished,
|
// Destroy the screen only after the demuxer is guaranteed to be finished,
|
||||||
// because otherwise the screen could receive new frames after destruction
|
// because otherwise the screen could receive new frames after destruction
|
||||||
if (screen_initialized) {
|
if (screen_initialized) {
|
||||||
sc_screen_join(&s->screen);
|
sc_screen_join(&s->screen);
|
||||||
|
|
Loading…
Reference in a new issue