[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