1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#pragma once
#include <al/str.h>
#include <al/array.h>
#include <nnwt/rpc2.h>
#include <nnwt/signal.h>
#include <nnwt/timer.h>
#include "../util/queue.h"
#include "../liana/client.h"
#include "../screen/screen.h"
#include "../buffer/clock.h"
#include "../buffer/audio.h"
#ifndef CAMU_SINK_NO_VIDEO
#include "../buffer/video.h"
#else
// Stub video_buffer usage within libsink only.
#include "../buffer/video_null.h"
#endif
enum {
CAMU_SINK_AUDIO = 0,
CAMU_SINK_VIDEO
};
enum {
CAMU_SINK_ADD_BUFFER = 0,
CAMU_SINK_REMOVE_BUFFER,
CAMU_SINK_START,
CAMU_SINK_STOP,
CAMU_SINK_REFRESH_VIDEO,
CAMU_SINK_CLEAR,
CAMU_SINK_MOCK_CLOSE,
CAMU_SINK_EXIT
};
enum {
CAMU_SINK_OK = 0
};
enum {
CAMU_SEEK_POS = 0,
CAMU_SEEK_RELATIVE,
CAMU_SEEK_PERCENT
};
struct camu_sink_entry {
struct lia_client client;
u64 id;
s32 sequence;
u16 lru;
bool disconnected;
bool ended;
u32 reset_token;
struct camu_clock clock;
bool paused;
struct {
u8 state;
// Don't stop audio on a BUFFER_PAUSED from this entry.
bool ignore_pause;
struct camu_audio_buffer buf;
struct lia_vcr_track *track;
} audio;
struct {
u8 state;
struct camu_video_buffer buf;
struct lia_vcr_track *track;
} video;
struct camu_sink *sink;
};
struct camu_sink_cmd {
u8 op;
union { s64 i; u64 u; f64 f; void *p; } v;
void *opaque;
};
struct camu_sink {
struct nn_event_loop *loop;
str name;
u8 type;
str addr;
u16 port;
bool local;
struct nn_rpc client;
struct nn_rpc_connection *conn;
bool closed;
bool connecting;
u16 connection_number;
struct nn_mutex lock;
struct nn_timer reconnect_timer;
struct nn_signal queue_signal;
queue(struct camu_sink_cmd) queue;
struct camu_sink_entry *current;
struct camu_sink_entry *target;
// If current was removed for a reconnect, it's "suspended".
struct camu_sink_entry *suspended;
array(struct camu_sink_entry *) previous;
array(struct camu_sink_entry *) entries;
struct nn_timer empty_timer;
u8 notify_status;
u16 lru;
struct {
u8 state;
struct camu_mixer *mixer;
} audio;
struct {
u8 state;
struct camu_renderer *renderer;
} video;
struct lia_prefs prefs;
array(struct lia_prefs) node_prefs;
str default_list;
u8 (*callback)(void *, u8, u8, void *);
void *userdata;
};
bool camu_sink_init(struct camu_sink *sink, struct nn_event_loop *loop,
struct camu_mixer *mixer, struct camu_renderer *renderer);
bool camu_sink_connect(struct camu_sink *sink, str *name, u8 type, str *addr, u16 port);
struct camu_sink_entry *camu_sink_get_current(struct camu_sink *sink);
void camu_sink_return_current(struct camu_sink *sink);
void camu_sink_add(struct camu_sink *sink, str *path);
void camu_sink_skip(struct camu_sink *sink, s32 n);
void camu_sink_toggle_pause(struct camu_sink *sink);
void camu_sink_seek(struct camu_sink *sink, void *value, u8 mode);
void camu_sink_reseek(struct camu_sink *sink);
void camu_sink_change_audio_track(struct camu_sink *sink, s32 n);
void camu_sink_change_subtitle_track(struct camu_sink *sink, s32 n);
void camu_sink_shuffle(struct camu_sink *sink);
void camu_sink_status(struct camu_sink *sink, struct camu_osd *osd);
void camu_sink_stop(struct camu_sink *sink);
void camu_sink_close(struct camu_sink *sink);
void camu_sink_free(struct camu_sink *sink);
|