Mercurial > mplayer.hg
annotate libao2/ao_jack.c @ 29938:eb6c70e2cbea
Very preliminary code to allow selecting the OpenGL backend at runtime.
Works in the currently supported cases for only Win32 and only X11,
the mixed case is not working yet though.
But applied anyway since the code is slightly less messy than the current one.
author | reimar |
---|---|
date | Tue, 08 Dec 2009 06:42:46 +0000 |
parents | 2eff450157cd |
children | 32725ca88fed |
rev | line source |
---|---|
27509
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
1 /* |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
2 * JACK audio output driver for MPlayer |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
3 * |
23734 | 4 * Copyleft 2001 by Felix Bünemann (atmosfear@users.sf.net) |
5 * and Reimar Döffinger (Reimar.Doeffinger@stud.uni-karlsruhe.de) | |
27509
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
6 * |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
7 * This file is part of MPlayer. |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
8 * |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
9 * MPlayer is free software; you can redistribute it and/or modify |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
10 * it under the terms of the GNU General Public License as published by |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
11 * the Free Software Foundation; either version 2 of the License, or |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
12 * (at your option) any later version. |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
13 * |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
14 * MPlayer is distributed in the hope that it will be useful, |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
17 * GNU General Public License for more details. |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
18 * |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
19 * You should have received a copy of the GNU General Public License along |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
20 * along with MPlayer; if not, write to the Free Software |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25650
diff
changeset
|
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
22 */ |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
23 |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
24 #include <stdio.h> |
15605 | 25 #include <stdlib.h> |
26 #include <string.h> | |
15641
1bb5111490cd
Create a unique client name so that multiple instances work.
reimar
parents:
15630
diff
changeset
|
27 #include <unistd.h> |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
28 |
14479 | 29 #include "config.h" |
15605 | 30 #include "mp_msg.h" |
31 #include "help_mp.h" | |
32 | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
33 #include "audio_out.h" |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
34 #include "audio_out_internal.h" |
14245 | 35 #include "libaf/af_format.h" |
15605 | 36 #include "osdep/timer.h" |
37 #include "subopt-helper.h" | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
38 |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
39 #include "libavutil/fifo.h" |
15605 | 40 |
41 #include <jack/jack.h> | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
42 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29126
diff
changeset
|
43 static const ao_info_t info = |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
44 { |
15605 | 45 "JACK audio output", |
46 "jack", | |
23734 | 47 "Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>", |
15605 | 48 "based on ao_sdl.c" |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
49 }; |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
50 |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
51 LIBAO_EXTERN(jack) |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
52 |
15605 | 53 //! maximum number of channels supported, avoids lots of mallocs |
54 #define MAX_CHANS 6 | |
55 static jack_port_t *ports[MAX_CHANS]; | |
56 static int num_ports; ///< Number of used ports == number of channels | |
57 static jack_client_t *client; | |
15630 | 58 static float jack_latency; |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
59 static int estimate; |
15605 | 60 static volatile int paused = 0; ///< set if paused |
61 static volatile int underrun = 0; ///< signals if an underrun occured | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
62 |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
63 static volatile float callback_interval = 0; |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
64 static volatile float callback_time = 0; |
15605 | 65 |
66 //! size of one chunk, if this is too small MPlayer will start to "stutter" | |
67 //! after a short time of playback | |
68 #define CHUNK_SIZE (16 * 1024) | |
69 //! number of "virtual" chunks the buffer consists of | |
70 #define NUM_CHUNKS 8 | |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
71 #define BUFFSIZE (NUM_CHUNKS * CHUNK_SIZE) |
15605 | 72 |
73 //! buffer for audio data | |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
74 static AVFifoBuffer *buffer; |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
75 |
15605 | 76 /** |
77 * \brief insert len bytes into buffer | |
78 * \param data data to insert | |
79 * \param len length of data | |
80 * \return number of bytes inserted into buffer | |
81 * | |
82 * If there is not enough room, the buffer is filled up | |
83 */ | |
84 static int write_buffer(unsigned char* data, int len) { | |
29126 | 85 int free = av_fifo_space(buffer); |
15605 | 86 if (len > free) len = free; |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
87 return av_fifo_generic_write(buffer, data, len, NULL); |
15605 | 88 } |
13012
2d188ebe0f3b
Update ao_jack for new bio2jack API, improve check in configure.
diego
parents:
12702
diff
changeset
|
89 |
25648
2438052a176e
Another small simplification. Slightly worse performance in the case
reimar
parents:
25647
diff
changeset
|
90 static void silence(float **bufs, int cnt, int num_bufs); |
2438052a176e
Another small simplification. Slightly worse performance in the case
reimar
parents:
25647
diff
changeset
|
91 |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
92 struct deinterleave { |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
93 float **bufs; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
94 int num_bufs; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
95 int cur_buf; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
96 int pos; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
97 }; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
98 |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
99 static void deinterleave(void *info, void *src, int len) { |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
100 struct deinterleave *di = info; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
101 float *s = src; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
102 int i; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
103 len /= sizeof(float); |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
104 for (i = 0; i < len; i++) { |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
105 di->bufs[di->cur_buf++][di->pos] = s[i]; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
106 if (di->cur_buf >= di->num_bufs) { |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
107 di->cur_buf = 0; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
108 di->pos++; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
109 } |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
110 } |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
111 } |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
112 |
15605 | 113 /** |
114 * \brief read data from buffer and splitting it into channels | |
115 * \param bufs num_bufs float buffers, each will contain the data of one channel | |
116 * \param cnt number of samples to read per channel | |
117 * \param num_bufs number of channels to split the data into | |
118 * \return number of samples read per channel, equals cnt unless there was too | |
119 * little data in the buffer | |
120 * | |
121 * Assumes the data in the buffer is of type float, the number of bytes | |
122 * read is res * num_bufs * sizeof(float), where res is the return value. | |
18808
cb83184bdc70
respect AOPLAY_FINAL_CHUNK and do not discard samples read from buffer
reimar
parents:
18807
diff
changeset
|
123 * If there is not enough data in the buffer remaining parts will be filled |
cb83184bdc70
respect AOPLAY_FINAL_CHUNK and do not discard samples read from buffer
reimar
parents:
18807
diff
changeset
|
124 * with silence. |
15605 | 125 */ |
126 static int read_buffer(float **bufs, int cnt, int num_bufs) { | |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
127 struct deinterleave di = {bufs, num_bufs, 0, 0}; |
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
128 int buffered = av_fifo_size(buffer); |
25647 | 129 if (cnt * sizeof(float) * num_bufs > buffered) { |
25648
2438052a176e
Another small simplification. Slightly worse performance in the case
reimar
parents:
25647
diff
changeset
|
130 silence(bufs, cnt, num_bufs); |
15605 | 131 cnt = buffered / sizeof(float) / num_bufs; |
25647 | 132 } |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
133 av_fifo_generic_read(buffer, &di, cnt * num_bufs * sizeof(float), deinterleave); |
15605 | 134 return cnt; |
135 } | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
136 |
15605 | 137 // end ring buffer stuff |
138 | |
139 static int control(int cmd, void *arg) { | |
140 return CONTROL_UNKNOWN; | |
141 } | |
142 | |
143 /** | |
144 * \brief fill the buffers with silence | |
145 * \param bufs num_bufs float buffers, each will contain the data of one channel | |
146 * \param cnt number of samples in each buffer | |
147 * \param num_bufs number of buffers | |
148 */ | |
149 static void silence(float **bufs, int cnt, int num_bufs) { | |
25646 | 150 int i; |
151 for (i = 0; i < num_bufs; i++) | |
152 memset(bufs[i], 0, cnt * sizeof(float)); | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
153 } |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
154 |
15605 | 155 /** |
156 * \brief JACK Callback function | |
157 * \param nframes number of frames to fill into buffers | |
158 * \param arg unused | |
159 * \return currently always 0 | |
160 * | |
161 * Write silence into buffers if paused or an underrun occured | |
162 */ | |
163 static int outputaudio(jack_nframes_t nframes, void *arg) { | |
164 float *bufs[MAX_CHANS]; | |
165 int i; | |
166 for (i = 0; i < num_ports; i++) | |
167 bufs[i] = jack_port_get_buffer(ports[i], nframes); | |
18808
cb83184bdc70
respect AOPLAY_FINAL_CHUNK and do not discard samples read from buffer
reimar
parents:
18807
diff
changeset
|
168 if (paused || underrun) |
cb83184bdc70
respect AOPLAY_FINAL_CHUNK and do not discard samples read from buffer
reimar
parents:
18807
diff
changeset
|
169 silence(bufs, nframes, num_ports); |
cb83184bdc70
respect AOPLAY_FINAL_CHUNK and do not discard samples read from buffer
reimar
parents:
18807
diff
changeset
|
170 else |
15605 | 171 if (read_buffer(bufs, nframes, num_ports) < nframes) |
172 underrun = 1; | |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
173 if (estimate) { |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
174 float now = (float)GetTimer() / 1000000.0; |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
175 float diff = callback_time + callback_interval - now; |
16140 | 176 if ((diff > -0.002) && (diff < 0.002)) |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
177 callback_time += callback_interval; |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
178 else |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
179 callback_time = now; |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
180 callback_interval = (float)nframes / (float)ao_data.samplerate; |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
181 } |
15605 | 182 return 0; |
183 } | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
184 |
15605 | 185 /** |
186 * \brief print suboption usage help | |
187 */ | |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
18885
diff
changeset
|
188 static void print_help (void) |
15605 | 189 { |
190 mp_msg (MSGT_AO, MSGL_FATAL, | |
191 "\n-ao jack commandline help:\n" | |
192 "Example: mplayer -ao jack:port=myout\n" | |
193 " connects MPlayer to the jack ports named myout\n" | |
194 "\nOptions:\n" | |
195 " port=<port name>\n" | |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
196 " Connects to the given ports instead of the default physical ones\n" |
16253 | 197 " name=<client name>\n" |
198 " Client name to pass to JACK\n" | |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
199 " estimate\n" |
28206
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
200 " Estimates the amount of data in buffers (experimental)\n" |
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
201 " autostart\n" |
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
202 " Automatically start JACK server if necessary\n" |
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
203 ); |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
204 } |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
205 |
15605 | 206 static int init(int rate, int channels, int format, int flags) { |
207 const char **matching_ports = NULL; | |
208 char *port_name = NULL; | |
16253 | 209 char *client_name = NULL; |
28206
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
210 int autostart = 0; |
29586
2eff450157cd
The suboption parser now takes a const options list, so mark them all const.
reimar
parents:
29263
diff
changeset
|
211 const opt_t subopts[] = { |
15605 | 212 {"port", OPT_ARG_MSTRZ, &port_name, NULL}, |
16253 | 213 {"name", OPT_ARG_MSTRZ, &client_name, NULL}, |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
214 {"estimate", OPT_ARG_BOOL, &estimate, NULL}, |
28206
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
215 {"autostart", OPT_ARG_BOOL, &autostart, NULL}, |
15605 | 216 {NULL} |
217 }; | |
28206
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
218 jack_options_t open_options = JackUseExactName; |
15605 | 219 int port_flags = JackPortIsInput; |
220 int i; | |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
221 estimate = 1; |
15605 | 222 if (subopt_parse(ao_subdevice, subopts) != 0) { |
223 print_help(); | |
224 return 0; | |
225 } | |
226 if (channels > MAX_CHANS) { | |
227 mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] Invalid number of channels: %i\n", channels); | |
228 goto err_out; | |
229 } | |
16253 | 230 if (!client_name) { |
18885 | 231 client_name = malloc(40); |
25645 | 232 sprintf(client_name, "MPlayer [%d]", getpid()); |
16253 | 233 } |
28206
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
234 if (!autostart) |
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
235 open_options |= JackNoStartServer; |
678a664a79ea
Replace deprecated jack_client_new with jack_client_open.
reimar
parents:
27509
diff
changeset
|
236 client = jack_client_open(client_name, open_options, NULL); |
15605 | 237 if (!client) { |
238 mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n"); | |
239 goto err_out; | |
240 } | |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
241 buffer = av_fifo_alloc(BUFFSIZE); |
15605 | 242 jack_set_process_callback(client, outputaudio, 0); |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
243 |
15605 | 244 // list matching ports |
245 if (!port_name) | |
246 port_flags |= JackPortIsPhysical; | |
247 matching_ports = jack_get_ports(client, port_name, NULL, port_flags); | |
25649 | 248 if (!matching_ports || !matching_ports[0]) { |
15605 | 249 mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] no physical ports available\n"); |
250 goto err_out; | |
251 } | |
25650 | 252 i = 1; |
253 while (matching_ports[i]) i++; | |
254 if (channels > i) channels = i; | |
15605 | 255 num_ports = channels; |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
256 |
15605 | 257 // create out output ports |
258 for (i = 0; i < num_ports; i++) { | |
259 char pname[30]; | |
260 snprintf(pname, 30, "out_%d", i); | |
261 ports[i] = jack_port_register(client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |
262 if (!ports[i]) { | |
263 mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] not enough ports available\n"); | |
264 goto err_out; | |
265 } | |
266 } | |
267 if (jack_activate(client)) { | |
268 mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] activate failed\n"); | |
269 goto err_out; | |
270 } | |
271 for (i = 0; i < num_ports; i++) { | |
272 if (jack_connect(client, jack_port_name(ports[i]), matching_ports[i])) { | |
273 mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] connecting failed\n"); | |
274 goto err_out; | |
275 } | |
276 } | |
15630 | 277 rate = jack_get_sample_rate(client); |
278 jack_latency = (float)(jack_port_get_total_latency(client, ports[0]) + | |
279 jack_get_buffer_size(client)) / (float)rate; | |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
280 callback_interval = 0; |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
281 |
15605 | 282 ao_data.channels = channels; |
15630 | 283 ao_data.samplerate = rate; |
15605 | 284 ao_data.format = AF_FORMAT_FLOAT_NE; |
285 ao_data.bps = channels * rate * sizeof(float); | |
15630 | 286 ao_data.buffersize = CHUNK_SIZE * NUM_CHUNKS; |
15605 | 287 ao_data.outburst = CHUNK_SIZE; |
288 free(matching_ports); | |
289 free(port_name); | |
16253 | 290 free(client_name); |
15605 | 291 return 1; |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
292 |
15605 | 293 err_out: |
294 free(matching_ports); | |
295 free(port_name); | |
16253 | 296 free(client_name); |
15605 | 297 if (client) |
298 jack_client_close(client); | |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
299 av_fifo_free(buffer); |
15605 | 300 buffer = NULL; |
301 return 0; | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
302 } |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
303 |
15605 | 304 // close audio device |
305 static void uninit(int immed) { | |
306 if (!immed) | |
307 usec_sleep(get_delay() * 1000 * 1000); | |
308 // HACK, make sure jack doesn't loop-output dirty buffers | |
15868 | 309 reset(); |
15605 | 310 usec_sleep(100 * 1000); |
311 jack_client_close(client); | |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
312 av_fifo_free(buffer); |
15605 | 313 buffer = NULL; |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
314 } |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
315 |
15605 | 316 /** |
317 * \brief stop playing and empty buffers (for seeking/pause) | |
318 */ | |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
18885
diff
changeset
|
319 static void reset(void) { |
15605 | 320 paused = 1; |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
321 av_fifo_reset(buffer); |
15605 | 322 paused = 0; |
323 } | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
324 |
15605 | 325 /** |
326 * \brief stop playing, keep buffers (for pause) | |
327 */ | |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
18885
diff
changeset
|
328 static void audio_pause(void) { |
15605 | 329 paused = 1; |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
330 } |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
331 |
15605 | 332 /** |
333 * \brief resume playing, after audio_pause() | |
334 */ | |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
18885
diff
changeset
|
335 static void audio_resume(void) { |
15605 | 336 paused = 0; |
337 } | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
338 |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
18885
diff
changeset
|
339 static int get_space(void) { |
29126 | 340 return av_fifo_space(buffer); |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
341 } |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
342 |
15605 | 343 /** |
344 * \brief write data into buffer and reset underrun flag | |
345 */ | |
346 static int play(void *data, int len, int flags) { | |
18808
cb83184bdc70
respect AOPLAY_FINAL_CHUNK and do not discard samples read from buffer
reimar
parents:
18807
diff
changeset
|
347 if (!(flags & AOPLAY_FINAL_CHUNK)) |
25645 | 348 len -= len % ao_data.outburst; |
15605 | 349 underrun = 0; |
350 return write_buffer(data, len); | |
12662
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
351 } |
05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
alex
parents:
diff
changeset
|
352 |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
18885
diff
changeset
|
353 static float get_delay(void) { |
28882
15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
reimar
parents:
28823
diff
changeset
|
354 int buffered = av_fifo_size(buffer); // could be less |
15630 | 355 float in_jack = jack_latency; |
16104
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
356 if (estimate && callback_interval > 0) { |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
357 float elapsed = (float)GetTimer() / 1000000.0 - callback_time; |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
358 in_jack += callback_interval - elapsed; |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
359 if (in_jack < 0) in_jack = 0; |
fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
reimar
parents:
15868
diff
changeset
|
360 } |
15605 | 361 return (float)buffered / (float)ao_data.bps + in_jack; |
362 } | |
363 |