Mercurial > libavformat.hg
annotate beosaudio.cpp @ 1960:c0289552590f libavformat
Change the vhook code to send real timestamps to the filters instead of the
current time of day, which is useless, and which the filters could just as
easily query for themselves.
patch by Bobby Bingham, uhmmmm gmail com
author | diego |
---|---|
date | Thu, 29 Mar 2007 05:24:35 +0000 |
parents | 62792a60f740 |
children | bbfeec27c98c |
rev | line source |
---|---|
0 | 1 /* |
2 * BeOS audio play interface | |
3 * Copyright (c) 2000, 2001 Fabrice Bellard. | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1167
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1167
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1167
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1167
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1167
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1167
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
833
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
21 | |
22 #include <signal.h> | |
23 #include <stdlib.h> | |
24 #include <stdio.h> | |
25 #include <string.h> | |
26 #include <unistd.h> | |
27 #include <sys/time.h> | |
28 | |
29 #include <Application.h> | |
30 #include <SoundPlayer.h> | |
31 | |
32 extern "C" { | |
33 #include "avformat.h" | |
34 } | |
35 | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
36 #ifdef HAVE_BSOUNDRECORDER |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
37 #include <SoundRecorder.h> |
153
41d4f3a86c98
cleanup; BSoundRecorder moved to Experimental namespace
mmu_man
parents:
108
diff
changeset
|
38 using namespace BPrivate::Media::Experimental; |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
39 #endif |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
40 |
0 | 41 /* enable performance checks */ |
42 //#define PERF_CHECK | |
43 | |
108
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
44 /* enable Media Kit latency checks */ |
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
45 //#define LATENCY_CHECK |
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
46 |
0 | 47 #define AUDIO_BLOCK_SIZE 4096 |
48 #define AUDIO_BLOCK_COUNT 8 | |
49 | |
50 #define AUDIO_BUFFER_SIZE (AUDIO_BLOCK_SIZE*AUDIO_BLOCK_COUNT) | |
51 | |
52 typedef struct { | |
95 | 53 int fd; // UNUSED |
0 | 54 int sample_rate; |
55 int channels; | |
56 int frame_size; /* in bytes ! */ | |
57 CodecID codec_id; | |
66
ad9bcf041e8e
Looks like this one was forgotten in the INT -> int_t move
mmu_man
parents:
30
diff
changeset
|
58 uint8_t buffer[AUDIO_BUFFER_SIZE]; |
0 | 59 int buffer_ptr; |
60 /* ring buffer */ | |
61 sem_id input_sem; | |
62 int input_index; | |
63 sem_id output_sem; | |
64 int output_index; | |
65 BSoundPlayer *player; | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
66 #ifdef HAVE_BSOUNDRECORDER |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
67 BSoundRecorder *recorder; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
68 #endif |
0 | 69 int has_quit; /* signal callbacks not to wait */ |
70 volatile bigtime_t starve_time; | |
71 } AudioData; | |
72 | |
73 static thread_id main_thid; | |
74 static thread_id bapp_thid; | |
75 static int own_BApp_created = 0; | |
76 static int refcount = 0; | |
77 | |
78 /* create the BApplication and Run() it */ | |
79 static int32 bapp_thread(void *arg) | |
80 { | |
81 new BApplication("application/x-vnd.ffmpeg"); | |
82 own_BApp_created = 1; | |
83 be_app->Run(); | |
84 /* kill the process group */ | |
85 // kill(0, SIGINT); | |
86 // kill(main_thid, SIGHUP); | |
87 return B_OK; | |
88 } | |
89 | |
90 /* create the BApplication only if needed */ | |
91 static void create_bapp_if_needed(void) | |
92 { | |
93 if (refcount++ == 0) { | |
94 /* needed by libmedia */ | |
95 if (be_app == NULL) { | |
96 bapp_thid = spawn_thread(bapp_thread, "ffmpeg BApplication", B_NORMAL_PRIORITY, NULL); | |
97 resume_thread(bapp_thid); | |
98 while (!own_BApp_created) | |
99 snooze(50000); | |
100 } | |
101 } | |
102 } | |
103 | |
104 static void destroy_bapp_if_needed(void) | |
105 { | |
106 if (--refcount == 0 && own_BApp_created) { | |
107 be_app->Lock(); | |
108 be_app->Quit(); | |
109 be_app = NULL; | |
110 } | |
111 } | |
112 | |
113 /* called back by BSoundPlayer */ | |
114 static void audioplay_callback(void *cookie, void *buffer, size_t bufferSize, const media_raw_audio_format &format) | |
115 { | |
116 AudioData *s; | |
117 size_t len, amount; | |
118 unsigned char *buf = (unsigned char *)buffer; | |
119 | |
120 s = (AudioData *)cookie; | |
121 if (s->has_quit) | |
122 return; | |
123 while (bufferSize > 0) { | |
124 #ifdef PERF_CHECK | |
125 bigtime_t t; | |
126 t = system_time(); | |
127 #endif | |
128 len = MIN(AUDIO_BLOCK_SIZE, bufferSize); | |
129 if (acquire_sem_etc(s->output_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) { | |
130 s->has_quit = 1; | |
131 s->player->SetHasData(false); | |
132 return; | |
133 } | |
134 amount = MIN(len, (AUDIO_BUFFER_SIZE - s->output_index)); | |
135 memcpy(buf, &s->buffer[s->output_index], amount); | |
136 s->output_index += amount; | |
137 if (s->output_index >= AUDIO_BUFFER_SIZE) { | |
138 s->output_index %= AUDIO_BUFFER_SIZE; | |
139 memcpy(buf + amount, &s->buffer[s->output_index], len - amount); | |
140 s->output_index += len-amount; | |
141 s->output_index %= AUDIO_BUFFER_SIZE; | |
142 } | |
143 release_sem_etc(s->input_sem, len, 0); | |
144 #ifdef PERF_CHECK | |
145 t = system_time() - t; | |
146 s->starve_time = MAX(s->starve_time, t); | |
147 #endif | |
148 buf += len; | |
149 bufferSize -= len; | |
150 } | |
151 } | |
152 | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
153 #ifdef HAVE_BSOUNDRECORDER |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
154 /* called back by BSoundRecorder */ |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
155 static void audiorecord_callback(void *cookie, bigtime_t timestamp, void *buffer, size_t bufferSize, const media_multi_audio_format &format) |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
156 { |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
157 AudioData *s; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
158 size_t len, amount; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
159 unsigned char *buf = (unsigned char *)buffer; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
160 |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
161 s = (AudioData *)cookie; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
162 if (s->has_quit) |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
163 return; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
164 |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
165 while (bufferSize > 0) { |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
166 len = MIN(bufferSize, AUDIO_BLOCK_SIZE); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
167 //printf("acquire_sem(input, %d)\n", len); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
168 if (acquire_sem_etc(s->input_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) { |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
169 s->has_quit = 1; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
170 return; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
171 } |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
172 amount = MIN(len, (AUDIO_BUFFER_SIZE - s->input_index)); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
173 memcpy(&s->buffer[s->input_index], buf, amount); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
174 s->input_index += amount; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
175 if (s->input_index >= AUDIO_BUFFER_SIZE) { |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
176 s->input_index %= AUDIO_BUFFER_SIZE; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
177 memcpy(&s->buffer[s->input_index], buf + amount, len - amount); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
178 s->input_index += len - amount; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
179 } |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
180 release_sem_etc(s->output_sem, len, 0); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
181 //printf("release_sem(output, %d)\n", len); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
182 buf += len; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
183 bufferSize -= len; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
184 } |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
185 } |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
186 #endif |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
187 |
97
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
188 static int audio_open(AudioData *s, int is_output, const char *audio_device) |
0 | 189 { |
190 int p[2]; | |
191 int ret; | |
192 media_raw_audio_format format; | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
193 media_multi_audio_format iformat; |
0 | 194 |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
195 #ifndef HAVE_BSOUNDRECORDER |
0 | 196 if (!is_output) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
197 return AVERROR(EIO); /* not for now */ |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
198 #endif |
0 | 199 s->input_sem = create_sem(AUDIO_BUFFER_SIZE, "ffmpeg_ringbuffer_input"); |
200 if (s->input_sem < B_OK) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
201 return AVERROR(EIO); |
0 | 202 s->output_sem = create_sem(0, "ffmpeg_ringbuffer_output"); |
203 if (s->output_sem < B_OK) { | |
204 delete_sem(s->input_sem); | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
205 return AVERROR(EIO); |
0 | 206 } |
207 s->input_index = 0; | |
208 s->output_index = 0; | |
209 create_bapp_if_needed(); | |
210 s->frame_size = AUDIO_BLOCK_SIZE; | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
211 /* bump up the priority (avoid realtime though) */ |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
212 set_thread_priority(find_thread(NULL), B_DISPLAY_PRIORITY+1); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
213 #ifdef HAVE_BSOUNDRECORDER |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
214 if (!is_output) { |
97
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
215 bool wait_for_input = false; |
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
216 if (audio_device && !strcmp(audio_device, "wait:")) |
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
217 wait_for_input = true; |
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
218 s->recorder = new BSoundRecorder(&iformat, wait_for_input, "ffmpeg input", audiorecord_callback); |
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
219 if (wait_for_input && (s->recorder->InitCheck() == B_OK)) { |
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
220 s->recorder->WaitForIncomingConnection(&iformat); |
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
221 } |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
222 if (s->recorder->InitCheck() != B_OK || iformat.format != media_raw_audio_format::B_AUDIO_SHORT) { |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
223 delete s->recorder; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
224 s->recorder = NULL; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
225 if (s->input_sem) |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
226 delete_sem(s->input_sem); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
227 if (s->output_sem) |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
228 delete_sem(s->output_sem); |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
229 return AVERROR(EIO); |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
230 } |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
231 s->codec_id = (iformat.byte_order == B_MEDIA_LITTLE_ENDIAN)?CODEC_ID_PCM_S16LE:CODEC_ID_PCM_S16BE; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
232 s->channels = iformat.channel_count; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
233 s->sample_rate = (int)iformat.frame_rate; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
234 s->frame_size = iformat.buffer_size; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
235 s->recorder->SetCookie(s); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
236 s->recorder->SetVolume(1.0); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
237 s->recorder->Start(); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
238 return 0; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
239 } |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
240 #endif |
0 | 241 format = media_raw_audio_format::wildcard; |
242 format.format = media_raw_audio_format::B_AUDIO_SHORT; | |
243 format.byte_order = B_HOST_IS_LENDIAN ? B_MEDIA_LITTLE_ENDIAN : B_MEDIA_BIG_ENDIAN; | |
244 format.channel_count = s->channels; | |
245 format.buffer_size = s->frame_size; | |
246 format.frame_rate = s->sample_rate; | |
247 s->player = new BSoundPlayer(&format, "ffmpeg output", audioplay_callback); | |
248 if (s->player->InitCheck() != B_OK) { | |
249 delete s->player; | |
250 s->player = NULL; | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
251 if (s->input_sem) |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
252 delete_sem(s->input_sem); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
253 if (s->output_sem) |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
254 delete_sem(s->output_sem); |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
255 return AVERROR(EIO); |
0 | 256 } |
257 s->player->SetCookie(s); | |
258 s->player->SetVolume(1.0); | |
259 s->player->Start(); | |
260 s->player->SetHasData(true); | |
261 return 0; | |
262 } | |
263 | |
264 static int audio_close(AudioData *s) | |
265 { | |
266 if (s->input_sem) | |
267 delete_sem(s->input_sem); | |
268 if (s->output_sem) | |
269 delete_sem(s->output_sem); | |
270 s->has_quit = 1; | |
271 if (s->player) { | |
272 s->player->Stop(); | |
273 } | |
274 if (s->player) | |
275 delete s->player; | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
276 #ifdef HAVE_BSOUNDRECORDER |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
277 if (s->recorder) |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
278 delete s->recorder; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
279 #endif |
0 | 280 destroy_bapp_if_needed(); |
281 return 0; | |
282 } | |
283 | |
284 /* sound output support */ | |
285 static int audio_write_header(AVFormatContext *s1) | |
286 { | |
287 AudioData *s = (AudioData *)s1->priv_data; | |
288 AVStream *st; | |
289 int ret; | |
290 | |
291 st = s1->streams[0]; | |
833 | 292 s->sample_rate = st->codec->sample_rate; |
293 s->channels = st->codec->channels; | |
97
265d01c2248f
the media node now won't connect itself to the default audio input with -ad wait:
mmu_man
parents:
96
diff
changeset
|
294 ret = audio_open(s, 1, NULL); |
0 | 295 if (ret < 0) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
296 return AVERROR(EIO); |
0 | 297 return 0; |
298 } | |
299 | |
300 static int audio_write_packet(AVFormatContext *s1, int stream_index, | |
246
8c55237af288
64 bit pts for writing - more const usage (don't forget me !)
mmu_man
parents:
153
diff
changeset
|
301 const uint8_t *buf, int size, int64_t force_pts) |
0 | 302 { |
303 AudioData *s = (AudioData *)s1->priv_data; | |
304 int len, ret; | |
108
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
305 #ifdef LATENCY_CHECK |
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
306 bigtime_t lat1, lat2; |
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
307 lat1 = s->player->Latency(); |
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
308 #endif |
0 | 309 #ifdef PERF_CHECK |
310 bigtime_t t = s->starve_time; | |
311 s->starve_time = 0; | |
312 printf("starve_time: %lld \n", t); | |
313 #endif | |
314 while (size > 0) { | |
315 int amount; | |
316 len = MIN(size, AUDIO_BLOCK_SIZE); | |
317 if (acquire_sem_etc(s->input_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
318 return AVERROR(EIO); |
0 | 319 amount = MIN(len, (AUDIO_BUFFER_SIZE - s->input_index)); |
320 memcpy(&s->buffer[s->input_index], buf, amount); | |
321 s->input_index += amount; | |
322 if (s->input_index >= AUDIO_BUFFER_SIZE) { | |
323 s->input_index %= AUDIO_BUFFER_SIZE; | |
324 memcpy(&s->buffer[s->input_index], buf + amount, len - amount); | |
325 s->input_index += len - amount; | |
326 } | |
327 release_sem_etc(s->output_sem, len, 0); | |
328 buf += len; | |
329 size -= len; | |
330 } | |
108
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
331 #ifdef LATENCY_CHECK |
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
332 lat2 = s->player->Latency(); |
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
333 printf("#### BSoundPlayer::Latency(): before= %lld, after= %lld\n", lat1, lat2); |
c1c8a0777bdb
Add latency check, the Media Kit shoul repport it, but this seems broken.
mmu_man
parents:
97
diff
changeset
|
334 #endif |
0 | 335 return 0; |
336 } | |
337 | |
338 static int audio_write_trailer(AVFormatContext *s1) | |
339 { | |
340 AudioData *s = (AudioData *)s1->priv_data; | |
341 | |
342 audio_close(s); | |
343 return 0; | |
344 } | |
345 | |
346 /* grab support */ | |
347 | |
348 static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |
349 { | |
350 AudioData *s = (AudioData *)s1->priv_data; | |
351 AVStream *st; | |
352 int ret; | |
353 | |
354 if (!ap || ap->sample_rate <= 0 || ap->channels <= 0) | |
355 return -1; | |
356 | |
357 st = av_new_stream(s1, 0); | |
358 if (!st) { | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
359 return AVERROR(ENOMEM); |
0 | 360 } |
361 s->sample_rate = ap->sample_rate; | |
362 s->channels = ap->channels; | |
363 | |
1795
62792a60f740
implement new grabbing interface, as described here:
gpoirier
parents:
1787
diff
changeset
|
364 ret = audio_open(s, 0, s1->filename); |
0 | 365 if (ret < 0) { |
366 av_free(st); | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
367 return AVERROR(EIO); |
0 | 368 } |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
369 /* take real parameters */ |
833 | 370 st->codec->codec_type = CODEC_TYPE_AUDIO; |
371 st->codec->codec_id = s->codec_id; | |
372 st->codec->sample_rate = s->sample_rate; | |
373 st->codec->channels = s->channels; | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
374 return 0; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
375 av_set_pts_info(s1, 48, 1, 1000000); /* 48 bits pts in us */ |
0 | 376 } |
377 | |
378 static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) | |
379 { | |
380 AudioData *s = (AudioData *)s1->priv_data; | |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
381 int size; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
382 size_t len, amount; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
383 unsigned char *buf; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
384 status_t err; |
0 | 385 |
386 if (av_new_packet(pkt, s->frame_size) < 0) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
387 return AVERROR(EIO); |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
388 buf = (unsigned char *)pkt->data; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
389 size = pkt->size; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
390 while (size > 0) { |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
391 len = MIN(AUDIO_BLOCK_SIZE, size); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
392 //printf("acquire_sem(output, %d)\n", len); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
393 while ((err=acquire_sem_etc(s->output_sem, len, B_CAN_INTERRUPT, 0LL)) == B_INTERRUPTED); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
394 if (err < B_OK) { |
0 | 395 av_free_packet(pkt); |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1358
diff
changeset
|
396 return AVERROR(EIO); |
0 | 397 } |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
398 amount = MIN(len, (AUDIO_BUFFER_SIZE - s->output_index)); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
399 memcpy(buf, &s->buffer[s->output_index], amount); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
400 s->output_index += amount; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
401 if (s->output_index >= AUDIO_BUFFER_SIZE) { |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
402 s->output_index %= AUDIO_BUFFER_SIZE; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
403 memcpy(buf + amount, &s->buffer[s->output_index], len - amount); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
404 s->output_index += len-amount; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
405 s->output_index %= AUDIO_BUFFER_SIZE; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
406 } |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
407 release_sem_etc(s->input_sem, len, 0); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
408 //printf("release_sem(input, %d)\n", len); |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
409 buf += len; |
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
410 size -= len; |
0 | 411 } |
96
2d3083edb99f
experimental BeOS audio input support. (needs unreleased library)
mmu_man
parents:
95
diff
changeset
|
412 //XXX: add pts info |
0 | 413 return 0; |
414 } | |
415 | |
416 static int audio_read_close(AVFormatContext *s1) | |
417 { | |
418 AudioData *s = (AudioData *)s1->priv_data; | |
419 | |
420 audio_close(s); | |
421 return 0; | |
422 } | |
423 | |
1167 | 424 static AVInputFormat audio_demuxer = { |
0 | 425 "audio_device", |
426 "audio grab and output", | |
427 sizeof(AudioData), | |
428 NULL, | |
429 audio_read_header, | |
430 audio_read_packet, | |
431 audio_read_close, | |
432 NULL, | |
433 AVFMT_NOFILE, | |
434 }; | |
435 | |
1167 | 436 AVOutputFormat audio_muxer = { |
0 | 437 "audio_device", |
438 "audio grab and output", | |
439 "", | |
440 "", | |
441 sizeof(AudioData), | |
442 #ifdef WORDS_BIGENDIAN | |
443 CODEC_ID_PCM_S16BE, | |
444 #else | |
445 CODEC_ID_PCM_S16LE, | |
446 #endif | |
447 CODEC_ID_NONE, | |
448 audio_write_header, | |
449 audio_write_packet, | |
450 audio_write_trailer, | |
451 AVFMT_NOFILE, | |
452 }; | |
453 | |
454 extern "C" { | |
455 | |
456 int audio_init(void) | |
457 { | |
458 main_thid = find_thread(NULL); | |
1167 | 459 av_register_input_format(&audio_demuxer); |
460 av_register_output_format(&audio_muxer); | |
0 | 461 return 0; |
462 } | |
463 | |
464 } // "C" | |
465 |