1 // LiVES - vjack playback engine
2 // (c) G. Finch 2006 - 2008 <salsaman@xs4all.nl,salsaman@gmail.com>
3 // released under the GNU GPL 3 or later
4 // see file COPYING or www.gnu.org for details
5
6 #include "videoplugin.h"
7
8 #include <stdio.h>
9
10 /////////////////////////////////////////////////////////////////
11
12 static char plugin_version[64] = "LiVES videojack output client 1.1";
13 static char fps_list[256];
14 static int palette_list[2];
15 static int mypalette;
16
17 //////////////////////////////////////////////////////////////////
18
19 #include <jack/jack.h>
20 #include <jack/video.h>
21 #include <jack/ringbuffer.h>
22
23 static jack_ringbuffer_t *rb;
24 static size_t frame_size;
25 static jack_port_t *output_port;
26 static jack_client_t *client;
27
server_process(jack_nframes_t nframes,void * arg)28 int server_process(jack_nframes_t nframes, void *arg) {
29 // jack calls this
30 uint8_t *in;
31
32 if (rb == NULL) return 0;
33
34 in = jack_port_get_buffer(output_port, nframes);
35 while (jack_ringbuffer_read_space(rb) >= frame_size) {
36 jack_ringbuffer_read(rb, (void *) in, frame_size);
37 }
38 return 0;
39 }
40
41 //////////////////////////////////////////////
get_fps_list(int palette)42 const char *get_fps_list(int palette) {
43 double fps = (double)jack_get_sample_rate(client);
44 snprintf(fps_list, 256, "%.8f", fps);
45 return fps_list;
46 }
47
module_check_init(void)48 const char *module_check_init(void) {
49 const char *client_name = "LiVES";
50 jack_options_t options = JackNullOption;
51 jack_status_t status;
52 const char *server_name = NULL; // set to "video0" if running with audio on "default"
53
54 // connect to vjack
55 client = jack_client_open(client_name, options, &status, server_name);
56 if (client == NULL) {
57 fprintf(stderr, "jack_client_open() failed, "
58 "status = 0x%2.0x\n", status);
59 if (status & JackServerFailed) {
60 fprintf(stderr, "vjack_output: Unable to connect to JACK server\n");
61 }
62 return "unable to connect";
63 }
64 if (status & JackServerStarted) {
65 fprintf(stderr, "JACK server started\n");
66 }
67 if (status & JackNameNotUnique) {
68 client_name = jack_get_client_name(client);
69 fprintf(stderr, "unique name `%s' assigned\n", client_name);
70 }
71
72 fprintf(stderr, "engine sample rate: %" PRIu32 "\n",
73 jack_get_sample_rate(client));
74
75 output_port = jack_port_register(client,
76 "video_out",
77 JACK_DEFAULT_VIDEO_TYPE,
78 JackPortIsOutput,
79 0);
80
81 if (output_port == NULL) {
82 fprintf(stderr, "vjack_output: no more JACK ports available\n");
83 return "no jack ports available";
84 }
85
86 rb = NULL;
87
88 // set process callback and start
89 jack_set_process_callback(client, server_process, NULL);
90
91 // and start the processing
92 if (jack_activate(client)) {
93 fprintf(stderr, "vjack_output: cannot activate client\n");
94 return "cannot activate client";
95 }
96
97 return NULL;
98 }
99
version(void)100 const char *version(void) {
101 return plugin_version;
102 }
103
get_description(void)104 const char *get_description(void) {
105 return "The vjack_output plugin allows sending frames to videojack.\nThis is an experimental plugin\n";
106 }
107
get_capabilities(int palette)108 uint64_t get_capabilities(int palette) {
109 return 0;
110 }
111
get_palette_list(void)112 int *get_palette_list(void) {
113 palette_list[0] = WEED_PALETTE_RGBA32;
114 palette_list[1] = WEED_PALETTE_END;
115 return palette_list;
116 }
117
set_palette(int palette)118 boolean set_palette(int palette) {
119 if (palette == WEED_PALETTE_RGBA32) {
120 mypalette = palette;
121 return TRUE;
122 }
123 // invalid palette
124 return FALSE;
125 }
126
init_screen(int width,int height,boolean fullscreen,uint64_t window_id,int argc,char ** argv)127 boolean init_screen(int width, int height, boolean fullscreen, uint64_t window_id, int argc, char **argv) {
128 jack_video_set_width_and_height(client, output_port, width, height);
129 frame_size = width * height * 4;
130 rb = jack_ringbuffer_create(16 * frame_size);
131 return TRUE;
132 }
133
render_frame(int hsize,int vsize,int64_t tc,void ** pixel_data,void ** return_data)134 boolean render_frame(int hsize, int vsize, int64_t tc, void **pixel_data, void **return_data) {
135 // hsize and vsize are in pixels (n-byte)
136
137 jack_ringbuffer_write(rb, pixel_data[0], frame_size);
138 return TRUE;
139 }
140
exit_screen(int16_t mouse_x,int16_t mouse_y)141 void exit_screen(int16_t mouse_x, int16_t mouse_y) {
142 if (rb != NULL) jack_ringbuffer_free(rb);
143 rb = NULL;
144 }
145
module_unload(void)146 void module_unload(void) {
147 if (jack_deactivate(client)) {
148 fprintf(stderr, "vjack_output error: cannot deactivate client\n");
149 }
150
151 // disconnect from vjack
152 jack_client_close(client);
153 fprintf(stderr, "vjack_output: jack port unregistered\n");
154 }
155