Mercurial > libavformat.hg
comparison beosaudio.cpp @ 95:89e992063014 libavformat
cleanup; unused pipe() stuff removed.
| author | mmu_man |
|---|---|
| date | Thu, 27 Mar 2003 13:37:47 +0000 |
| parents | ad9bcf041e8e |
| children | 2d3083edb99f |
comparison
equal
deleted
inserted
replaced
| 94:79b7d70d6c37 | 95:89e992063014 |
|---|---|
| 32 } | 32 } |
| 33 | 33 |
| 34 /* enable performance checks */ | 34 /* enable performance checks */ |
| 35 //#define PERF_CHECK | 35 //#define PERF_CHECK |
| 36 | 36 |
| 37 /* Pipes are 4k in BeOS IIRC */ | |
| 38 #define AUDIO_BLOCK_SIZE 4096 | 37 #define AUDIO_BLOCK_SIZE 4096 |
| 39 //#define AUDIO_BLOCK_SIZE 2048 | 38 //#define AUDIO_BLOCK_SIZE 2048 |
| 40 #define AUDIO_BLOCK_COUNT 8 | 39 #define AUDIO_BLOCK_COUNT 8 |
| 41 | 40 |
| 42 #define AUDIO_BUFFER_SIZE (AUDIO_BLOCK_SIZE*AUDIO_BLOCK_COUNT) | 41 #define AUDIO_BUFFER_SIZE (AUDIO_BLOCK_SIZE*AUDIO_BLOCK_COUNT) |
| 43 | 42 |
| 44 /* pipes suck for realtime */ | |
| 45 #define USE_RING_BUFFER 1 | |
| 46 | |
| 47 typedef struct { | 43 typedef struct { |
| 48 int fd; | 44 int fd; // UNUSED |
| 49 int sample_rate; | 45 int sample_rate; |
| 50 int channels; | 46 int channels; |
| 51 int frame_size; /* in bytes ! */ | 47 int frame_size; /* in bytes ! */ |
| 52 CodecID codec_id; | 48 CodecID codec_id; |
| 53 int flip_left : 1; | |
| 54 uint8_t buffer[AUDIO_BUFFER_SIZE]; | 49 uint8_t buffer[AUDIO_BUFFER_SIZE]; |
| 55 int buffer_ptr; | 50 int buffer_ptr; |
| 56 int pipefd; /* the other end of the pipe */ | |
| 57 /* ring buffer */ | 51 /* ring buffer */ |
| 58 sem_id input_sem; | 52 sem_id input_sem; |
| 59 int input_index; | 53 int input_index; |
| 60 sem_id output_sem; | 54 sem_id output_sem; |
| 61 int output_index; | 55 int output_index; |
| 118 while (bufferSize > 0) { | 112 while (bufferSize > 0) { |
| 119 #ifdef PERF_CHECK | 113 #ifdef PERF_CHECK |
| 120 bigtime_t t; | 114 bigtime_t t; |
| 121 t = system_time(); | 115 t = system_time(); |
| 122 #endif | 116 #endif |
| 123 #ifdef USE_RING_BUFFER | |
| 124 len = MIN(AUDIO_BLOCK_SIZE, bufferSize); | 117 len = MIN(AUDIO_BLOCK_SIZE, bufferSize); |
| 125 if (acquire_sem_etc(s->output_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) { | 118 if (acquire_sem_etc(s->output_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) { |
| 126 s->has_quit = 1; | 119 s->has_quit = 1; |
| 127 s->player->SetHasData(false); | 120 s->player->SetHasData(false); |
| 128 return; | 121 return; |
| 135 memcpy(buf + amount, &s->buffer[s->output_index], len - amount); | 128 memcpy(buf + amount, &s->buffer[s->output_index], len - amount); |
| 136 s->output_index += len-amount; | 129 s->output_index += len-amount; |
| 137 s->output_index %= AUDIO_BUFFER_SIZE; | 130 s->output_index %= AUDIO_BUFFER_SIZE; |
| 138 } | 131 } |
| 139 release_sem_etc(s->input_sem, len, 0); | 132 release_sem_etc(s->input_sem, len, 0); |
| 140 #else | |
| 141 len = read(s->pipefd, buf, bufferSize); | |
| 142 #endif | |
| 143 #ifdef PERF_CHECK | 133 #ifdef PERF_CHECK |
| 144 t = system_time() - t; | 134 t = system_time() - t; |
| 145 s->starve_time = MAX(s->starve_time, t); | 135 s->starve_time = MAX(s->starve_time, t); |
| 146 #endif | 136 #endif |
| 147 #ifndef USE_RING_BUFFER | |
| 148 if (len < B_OK) { | |
| 149 puts("EPIPE"); | |
| 150 s->player->SetHasData(false); | |
| 151 snooze(100000); | |
| 152 return; | |
| 153 } | |
| 154 if (len == 0) { | |
| 155 s->player->SetHasData(false); | |
| 156 snooze(100000); | |
| 157 return; | |
| 158 } | |
| 159 #endif | |
| 160 buf += len; | 137 buf += len; |
| 161 bufferSize -= len; | 138 bufferSize -= len; |
| 162 } | 139 } |
| 163 } | 140 } |
| 164 | 141 |
| 168 int ret; | 145 int ret; |
| 169 media_raw_audio_format format; | 146 media_raw_audio_format format; |
| 170 | 147 |
| 171 if (!is_output) | 148 if (!is_output) |
| 172 return -EIO; /* not for now */ | 149 return -EIO; /* not for now */ |
| 173 #ifdef USE_RING_BUFFER | |
| 174 s->input_sem = create_sem(AUDIO_BUFFER_SIZE, "ffmpeg_ringbuffer_input"); | 150 s->input_sem = create_sem(AUDIO_BUFFER_SIZE, "ffmpeg_ringbuffer_input"); |
| 175 // s->input_sem = create_sem(AUDIO_BLOCK_SIZE, "ffmpeg_ringbuffer_input"); | 151 // s->input_sem = create_sem(AUDIO_BLOCK_SIZE, "ffmpeg_ringbuffer_input"); |
| 176 if (s->input_sem < B_OK) | 152 if (s->input_sem < B_OK) |
| 177 return -EIO; | 153 return -EIO; |
| 178 s->output_sem = create_sem(0, "ffmpeg_ringbuffer_output"); | 154 s->output_sem = create_sem(0, "ffmpeg_ringbuffer_output"); |
| 181 return -EIO; | 157 return -EIO; |
| 182 } | 158 } |
| 183 s->input_index = 0; | 159 s->input_index = 0; |
| 184 s->output_index = 0; | 160 s->output_index = 0; |
| 185 s->queued = 0; | 161 s->queued = 0; |
| 186 #else | |
| 187 ret = pipe(p); | |
| 188 if (ret < 0) | |
| 189 return -EIO; | |
| 190 s->fd = p[is_output?1:0]; | |
| 191 s->pipefd = p[is_output?0:1]; | |
| 192 if (s->fd < 0) { | |
| 193 perror(is_output?"audio out":"audio in"); | |
| 194 return -EIO; | |
| 195 } | |
| 196 #endif | |
| 197 create_bapp_if_needed(); | 162 create_bapp_if_needed(); |
| 198 /* non blocking mode */ | |
| 199 // fcntl(s->fd, F_SETFL, O_NONBLOCK); | |
| 200 // fcntl(s->pipefd, F_SETFL, O_NONBLOCK); | |
| 201 s->frame_size = AUDIO_BLOCK_SIZE; | 163 s->frame_size = AUDIO_BLOCK_SIZE; |
| 202 format = media_raw_audio_format::wildcard; | 164 format = media_raw_audio_format::wildcard; |
| 203 format.format = media_raw_audio_format::B_AUDIO_SHORT; | 165 format.format = media_raw_audio_format::B_AUDIO_SHORT; |
| 204 format.byte_order = B_HOST_IS_LENDIAN ? B_MEDIA_LITTLE_ENDIAN : B_MEDIA_BIG_ENDIAN; | 166 format.byte_order = B_HOST_IS_LENDIAN ? B_MEDIA_LITTLE_ENDIAN : B_MEDIA_BIG_ENDIAN; |
| 205 format.channel_count = s->channels; | 167 format.channel_count = s->channels; |
| 207 format.frame_rate = s->sample_rate; | 169 format.frame_rate = s->sample_rate; |
| 208 s->player = new BSoundPlayer(&format, "ffmpeg output", audioplay_callback); | 170 s->player = new BSoundPlayer(&format, "ffmpeg output", audioplay_callback); |
| 209 if (s->player->InitCheck() != B_OK) { | 171 if (s->player->InitCheck() != B_OK) { |
| 210 delete s->player; | 172 delete s->player; |
| 211 s->player = NULL; | 173 s->player = NULL; |
| 212 #ifdef USE_RING_BUFFER | |
| 213 if (s->input_sem) | 174 if (s->input_sem) |
| 214 delete_sem(s->input_sem); | 175 delete_sem(s->input_sem); |
| 215 if (s->output_sem) | 176 if (s->output_sem) |
| 216 delete_sem(s->output_sem); | 177 delete_sem(s->output_sem); |
| 217 #else | |
| 218 close(s->fd); | |
| 219 close(s->pipefd); | |
| 220 #endif | |
| 221 return -EIO; | 178 return -EIO; |
| 222 } | 179 } |
| 223 s->player->SetCookie(s); | 180 s->player->SetCookie(s); |
| 224 s->player->SetVolume(1.0); | 181 s->player->SetVolume(1.0); |
| 225 s->player->Start(); | 182 s->player->Start(); |
| 229 return 0; | 186 return 0; |
| 230 } | 187 } |
| 231 | 188 |
| 232 static int audio_close(AudioData *s) | 189 static int audio_close(AudioData *s) |
| 233 { | 190 { |
| 234 #ifdef USE_RING_BUFFER | |
| 235 if (s->input_sem) | 191 if (s->input_sem) |
| 236 delete_sem(s->input_sem); | 192 delete_sem(s->input_sem); |
| 237 if (s->output_sem) | 193 if (s->output_sem) |
| 238 delete_sem(s->output_sem); | 194 delete_sem(s->output_sem); |
| 239 #endif | |
| 240 s->has_quit = 1; | 195 s->has_quit = 1; |
| 241 if (s->player) { | 196 if (s->player) { |
| 242 s->player->Stop(); | 197 s->player->Stop(); |
| 243 } | 198 } |
| 244 if (s->player) | 199 if (s->player) |
| 245 delete s->player; | 200 delete s->player; |
| 246 #ifndef USE_RING_BUFFER | |
| 247 close(s->pipefd); | |
| 248 close(s->fd); | |
| 249 #endif | |
| 250 destroy_bapp_if_needed(); | 201 destroy_bapp_if_needed(); |
| 251 return 0; | 202 return 0; |
| 252 } | 203 } |
| 253 | 204 |
| 254 /* sound output support */ | 205 /* sound output support */ |
| 275 #ifdef PERF_CHECK | 226 #ifdef PERF_CHECK |
| 276 bigtime_t t = s->starve_time; | 227 bigtime_t t = s->starve_time; |
| 277 s->starve_time = 0; | 228 s->starve_time = 0; |
| 278 printf("starve_time: %lld \n", t); | 229 printf("starve_time: %lld \n", t); |
| 279 #endif | 230 #endif |
| 280 #ifdef USE_RING_BUFFER | |
| 281 while (size > 0) { | 231 while (size > 0) { |
| 282 int amount; | 232 int amount; |
| 283 len = MIN(size, AUDIO_BLOCK_SIZE); | 233 len = MIN(size, AUDIO_BLOCK_SIZE); |
| 284 if (acquire_sem_etc(s->input_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) | 234 if (acquire_sem_etc(s->input_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) |
| 285 return -EIO; | 235 return -EIO; |
| 293 } | 243 } |
| 294 release_sem_etc(s->output_sem, len, 0); | 244 release_sem_etc(s->output_sem, len, 0); |
| 295 buf += len; | 245 buf += len; |
| 296 size -= len; | 246 size -= len; |
| 297 } | 247 } |
| 298 #else | |
| 299 while (size > 0) { | |
| 300 len = AUDIO_BLOCK_SIZE - s->buffer_ptr; | |
| 301 if (len > size) | |
| 302 len = size; | |
| 303 memcpy(s->buffer + s->buffer_ptr, buf, len); | |
| 304 s->buffer_ptr += len; | |
| 305 if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) { | |
| 306 for(;;) { | |
| 307 //snooze(1000); | |
| 308 ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE); | |
| 309 if (ret != 0) | |
| 310 break; | |
| 311 if (ret < 0 && (errno != EAGAIN && errno != EINTR)) | |
| 312 return -EIO; | |
| 313 } | |
| 314 s->buffer_ptr = 0; | |
| 315 } | |
| 316 buf += len; | |
| 317 size -= len; | |
| 318 } | |
| 319 #endif | |
| 320 return 0; | 248 return 0; |
| 321 } | 249 } |
| 322 | 250 |
| 323 static int audio_write_trailer(AVFormatContext *s1) | 251 static int audio_write_trailer(AVFormatContext *s1) |
| 324 { | 252 { |
| 380 av_free_packet(pkt); | 308 av_free_packet(pkt); |
| 381 return -EIO; | 309 return -EIO; |
| 382 } | 310 } |
| 383 } | 311 } |
| 384 pkt->size = ret; | 312 pkt->size = ret; |
| 385 if (s->flip_left && s->channels == 2) { | |
| 386 int i; | |
| 387 short *p = (short *) pkt->data; | |
| 388 | |
| 389 for (i = 0; i < ret; i += 4) { | |
| 390 *p = ~*p; | |
| 391 p += 2; | |
| 392 } | |
| 393 } | |
| 394 return 0; | 313 return 0; |
| 395 } | 314 } |
| 396 | 315 |
| 397 static int audio_read_close(AVFormatContext *s1) | 316 static int audio_read_close(AVFormatContext *s1) |
| 398 { | 317 { |
