[xiph-commits] r3169 - in liboggplay/trunk: plugin plugin/audio
src/liboggplay
shans at svn.annodex.net
shans at svn.annodex.net
Tue Jul 24 00:20:21 PDT 2007
Author: shans
Date: 2007-07-24 00:20:20 -0700 (Tue, 24 Jul 2007)
New Revision: 3169
Modified:
liboggplay/trunk/plugin/audio/sydney_audio_oss.c
liboggplay/trunk/plugin/plugin_gui_linux.c
liboggplay/trunk/src/liboggplay/oggplay_callback_info.c
Log:
(1) Audio buffering code to ensure we don't block on a write under OSS
(2) Fix to bigmammoth's problem: when audio is collected in large
packets then some video frames have no accompanying audio data. This
was showing up a bug in the code that decides to jump the presentation
time forward when some data is missing.
Modified: liboggplay/trunk/plugin/audio/sydney_audio_oss.c
===================================================================
--- liboggplay/trunk/plugin/audio/sydney_audio_oss.c 2007-07-23 06:36:29 UTC (rev 3168)
+++ liboggplay/trunk/plugin/audio/sydney_audio_oss.c 2007-07-24 07:20:20 UTC (rev 3169)
@@ -41,8 +41,8 @@
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
+#include <string.h>
-
#define SA_READ_PERIOD 0
#define SA_WRITE_PERIOD 2560 // 40 ms of 16-bit, stereo, 16kHz
#define SA_READ_BUFFER 0
@@ -70,6 +70,9 @@
int capture_handle;
int playback_handle;
int readN, writeN;
+ char *stored;
+ int stored_amount;
+ int stored_limit;
//int read_fd, write_fd;
};
@@ -137,7 +140,10 @@
dev->write_period = SA_WRITE_PERIOD;
dev->read_buffer = SA_READ_BUFFER;
dev->write_buffer = SA_WRITE_BUFFER;
- dev->device_name = "/dev/dsp";
+ dev->device_name = "/dev/dsp";
+ dev->stored = NULL;
+ dev->stored_amount = 0;
+ dev->stored_limit = 0;
*_dev = dev;
sa_print_handle_settings(dev);
@@ -163,6 +169,7 @@
//assert(0);
return SA_DEVICE_OOM;
}
+
// set the playback rate
if ((err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &(dev->rate))) < 0) {
fprintf(stderr,
@@ -189,6 +196,7 @@
//assert(0);
return SA_DEVICE_OOM;
}
+
dev->playback_handle = audio_fd;
}
@@ -202,6 +210,12 @@
return SA_DEVICE_SUCCESS;
}
+#define WRITE(data,amt) \
+ if ((err = write(dev->playback_handle, data, amt)) < 0) { \
+ fprintf(stderr, "Error writing data to audio device\n"); \
+ return SA_DEVICE_OOM; \
+ }
+
/*!
* \brief Interleaved write operation
* \param dev - device handle
@@ -209,19 +223,55 @@
* \param data - pointer to the buffer with audio samples
* \return
* */
-int sa_device_write(SAAudioHandle *dev, size_t nbytes, const void *data) {
- int err;
+int sa_device_write(SAAudioHandle *dev, size_t nbytes, const void *_data) {
+ int err;
+ audio_buf_info info;
+ int bytes;
+ char * data = (char *)_data;
/*
- audio_buf_info info;
ioctl(dev->playback_handle, SNDCTL_DSP_GETOSPACE, &info);
printf("fragment size: %d, nfrags: %d, free: %d wtw: %d\n", info.fragsize,
info.fragstotal, info.bytes, nbytes);
*/
+
+
+
if ((dev->playback_handle) > 0) {
- if ((err = write(dev->playback_handle, data, nbytes)) < 0) {
- fprintf(stderr, "Error writing data to audio device\n");
- return SA_DEVICE_OOM;
- }
+ ioctl(dev->playback_handle, SNDCTL_DSP_GETOSPACE, &info);
+ bytes = info.bytes;
+ if (dev->stored_amount > bytes) {
+ WRITE(dev->stored, bytes);
+ memmove(dev->stored, dev->stored + bytes, dev->stored_amount - bytes);
+ dev->stored_amount -= bytes;
+ } else if (dev->stored_amount > 0) {
+ WRITE(dev->stored, dev->stored_amount);
+ bytes -= dev->stored_amount;
+ dev->stored_amount = 0;
+ if (nbytes < bytes) {
+ WRITE(data, nbytes);
+ return SA_DEVICE_SUCCESS;
+ }
+ WRITE(data, bytes);
+ data += bytes;
+ nbytes -= bytes;
+ } else {
+ if (nbytes < bytes) {
+ WRITE(data, nbytes);
+ return SA_DEVICE_SUCCESS;
+ }
+ WRITE(data, bytes);
+ data += bytes;
+ nbytes -= bytes;
+ }
+
+ if (nbytes > 0) {
+ if (dev->stored_amount + nbytes > dev->stored_limit) {
+ dev->stored = realloc(dev->stored, dev->stored_amount + nbytes);
+ }
+
+ memcpy(dev->stored + dev->stored_amount, data, nbytes);
+ dev->stored_amount += nbytes;
+ }
}
return SA_DEVICE_SUCCESS;
}
@@ -234,9 +284,23 @@
* \return Sydney API error as in ::sa_pcm_error_t
**/
int sa_device_close(SAAudioHandle *dev) {
+ int err;
+
if (dev != NULL) {
- CLOSE_HANDLE(dev->playback_handle);
+ if (dev->stored_amount > 0) {
+ WRITE(dev->stored, dev->stored_amount);
+ }
+
+ if (dev->stored != NULL) {
+ free(dev->stored);
+ }
+
+ dev->stored = NULL;
+ dev->stored_amount = 0;
+ dev->stored_limit = 0;
+
+ CLOSE_HANDLE(dev->playback_handle);
CLOSE_HANDLE(dev->capture_handle);
printf("Closing audio device\n");
Modified: liboggplay/trunk/plugin/plugin_gui_linux.c
===================================================================
--- liboggplay/trunk/plugin/plugin_gui_linux.c 2007-07-23 06:36:29 UTC (rev 3168)
+++ liboggplay/trunk/plugin/plugin_gui_linux.c 2007-07-24 07:20:20 UTC (rev 3169)
@@ -245,6 +245,7 @@
}
/* clean up */
+
free_oggplay_frame(info->ogg_handle, &frame_data);
info->playback_target += get_callback_period(info->ogg_handle);
Modified: liboggplay/trunk/src/liboggplay/oggplay_callback_info.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_callback_info.c 2007-07-23 06:36:29 UTC (rev 3168)
+++ liboggplay/trunk/src/liboggplay/oggplay_callback_info.c 2007-07-24 07:20:20 UTC (rev 3169)
@@ -115,7 +115,7 @@
track_info->stream_info = track->stream_info;
}
- } else {
+ } else {
track_info->stream_info = OGGPLAY_STREAM_UNINITIALISED;
}
@@ -175,7 +175,11 @@
track_info->required_records == 0
&&
track->active == 1
+ &&
+ track->current_loc < me->target
) {
+ printf("track: %d current_loc: %lld target: %lld\n",
+ i, track->current_loc >> 32, me->target >> 32);
added_required_record = 0;
}
More information about the commits
mailing list