Browse Source

movies: return actual number of samples read in read_samples

Various codecs may only partially fill the buffer and fill the rest with zeroes, but it is useful to know how many samples were actually read.
rdb 6 years ago
parent
commit
c513342247

+ 2 - 1
panda/src/ffmpeg/ffmpegAudioCursor.cxx

@@ -462,7 +462,7 @@ seek(double t) {
  * read.  Your buffer must be equal in size to N * channels.  Multiple-channel
  * audio will be interleaved.
  */
-void FfmpegAudioCursor::
+int FfmpegAudioCursor::
 read_samples(int n, int16_t *data) {
   int desired = n * _audio_channels;
 
@@ -486,4 +486,5 @@ read_samples(int n, int16_t *data) {
 
   }
   _samples_read += n;
+  return n;
 }

+ 1 - 1
panda/src/ffmpeg/ffmpegAudioCursor.h

@@ -45,7 +45,7 @@ PUBLISHED:
   virtual void seek(double offset);
 
 public:
-  virtual void read_samples(int n, int16_t *data);
+  virtual int read_samples(int n, int16_t *data);
 
 protected:
   void fetch_packet();

+ 4 - 2
panda/src/movies/flacAudioCursor.cxx

@@ -118,8 +118,10 @@ seek(double t) {
  * read.  Your buffer must be equal in size to N * channels.  Multiple-channel
  * audio will be interleaved.
  */
-void FlacAudioCursor::
+int FlacAudioCursor::
 read_samples(int n, int16_t *data) {
   int desired = n * _audio_channels;
-  _samples_read += drflac_read_s16(_drflac, desired, data) / _audio_channels;
+  n = drflac_read_s16(_drflac, desired, data) / _audio_channels;
+  _samples_read += n;
+  return n;
 }

+ 1 - 1
panda/src/movies/flacAudioCursor.h

@@ -37,7 +37,7 @@ PUBLISHED:
   virtual void seek(double offset);
 
 public:
-  virtual void read_samples(int n, int16_t *data);
+  virtual int read_samples(int n, int16_t *data);
 
   bool _is_valid;
 

+ 3 - 2
panda/src/movies/microphoneAudioDS.cxx

@@ -91,7 +91,7 @@ public:
   int _samples_per_buffer;
 
 public:
-  virtual void read_samples(int n, int16_t *data);
+  virtual int read_samples(int n, int16_t *data);
   virtual int ready() const;
 
 public:
@@ -323,7 +323,7 @@ MicrophoneAudioCursorDS::
 /**
  *
  */
-void MicrophoneAudioCursorDS::
+int MicrophoneAudioCursorDS::
 read_samples(int n, int16_t *data) {
   int orign = n;
   if (_handle) {
@@ -373,6 +373,7 @@ read_samples(int n, int16_t *data) {
   if (n > 0) {
     memcpy(data, 0, n*2*_audio_channels);
   }
+  return orign - n;
 }
 
 /**

+ 3 - 2
panda/src/movies/movieAudioCursor.cxx

@@ -45,14 +45,14 @@ MovieAudioCursor::
  * read.  Your buffer must be equal in size to N * channels.  Multiple-channel
  * audio will be interleaved.
  */
-void MovieAudioCursor::
+int MovieAudioCursor::
 read_samples(int n, int16_t *data) {
 
   // This is the null implementation, which generates pure silence.  Normally,
   // this method will be overridden by a subclass.
 
   if (n <= 0) {
-    return;
+    return 0;
   }
 
   int desired = n * _audio_channels;
@@ -60,6 +60,7 @@ read_samples(int n, int16_t *data) {
     data[i] = 0;
   }
   _samples_read += n;
+  return n;
 }
 
 /**

+ 1 - 1
panda/src/movies/movieAudioCursor.h

@@ -51,7 +51,7 @@ PUBLISHED:
   std::string read_samples(int n);
 
 public:
-  virtual void read_samples(int n, int16_t *data);
+  virtual int read_samples(int n, int16_t *data);
 
 protected:
   PT(MovieAudio) _source;

+ 3 - 1
panda/src/movies/opusAudioCursor.cxx

@@ -228,7 +228,7 @@ seek(double t) {
  * read.  Your buffer must be equal in size to N * channels.  Multiple-channel
  * audio will be interleaved.
  */
-void OpusAudioCursor::
+int OpusAudioCursor::
 read_samples(int n, int16_t *data) {
   int16_t *end = data + (n * _audio_channels);
 
@@ -262,7 +262,9 @@ read_samples(int n, int16_t *data) {
   // Fill the rest of the buffer with silence.
   if (data < end) {
     memset(data, 0, (unsigned char *)end - (unsigned char *)data);
+    n -= (end - data) / _audio_channels;
   }
+  return n;
 }
 
 #endif // HAVE_OPUS

+ 1 - 1
panda/src/movies/opusAudioCursor.h

@@ -39,7 +39,7 @@ PUBLISHED:
   virtual void seek(double offset);
 
 public:
-  virtual void read_samples(int n, int16_t *data);
+  virtual int read_samples(int n, int16_t *data);
 
   bool _is_valid;
 

+ 6 - 3
panda/src/movies/userDataAudio.cxx

@@ -57,12 +57,14 @@ open() {
  * read.  Your buffer must be equal in size to N * channels.  Multiple-channel
  * audio will be interleaved.
  */
-void UserDataAudio::
+int UserDataAudio::
 read_samples(int n, int16_t *data) {
   int ready = (_data.size() / _desired_channels);
   int desired = n * _desired_channels;
-  int avail = ready * _desired_channels;
-  if (avail > desired) avail = desired;
+  if (n > ready) {
+    n = ready;
+  }
+  int avail = n * _desired_channels;
   for (int i=0; i<avail; i++) {
     data[i] = _data[i];
   }
@@ -72,6 +74,7 @@ read_samples(int n, int16_t *data) {
   for (int i=0; i<avail; i++) {
     _data.pop_front();
   }
+  return n;
 }
 
 /**

+ 1 - 1
panda/src/movies/userDataAudio.h

@@ -41,7 +41,7 @@ class EXPCL_PANDA_MOVIES UserDataAudio : public MovieAudio {
   void done(); // A promise not to write any more samples.
 
  private:
-  void read_samples(int n, int16_t *data);
+  int read_samples(int n, int16_t *data);
   void update_cursor();
   int _desired_rate;
   int _desired_channels;

+ 6 - 3
panda/src/movies/userDataAudioCursor.cxx

@@ -47,12 +47,12 @@ UserDataAudioCursor::
  * read.  Your buffer must be equal in size to N * channels.  Multiple-channel
  * audio will be interleaved.
  */
-void UserDataAudioCursor::
+int UserDataAudioCursor::
 read_samples(int n, int16_t *data) {
   UserDataAudio *source = (UserDataAudio*)(MovieAudio*)_source;
 
-  if(source->_remove_after_read) {
-    source->read_samples(n, data);
+  if (source->_remove_after_read) {
+    n = source->read_samples(n, data);
   }
   else {
     int offset = _samples_read * _audio_channels;
@@ -66,9 +66,12 @@ read_samples(int n, int16_t *data) {
     for (int i=avail; i<desired; i++) {
       data[i] = 0;
     }
+
+    n = avail / _audio_channels;
   }
 
   _samples_read += n;
+  return n;
 }
 
 /**

+ 1 - 1
panda/src/movies/userDataAudioCursor.h

@@ -33,7 +33,7 @@ PUBLISHED:
   virtual ~UserDataAudioCursor();
 
 public:
-  virtual void read_samples(int n, int16_t *data);
+  virtual int read_samples(int n, int16_t *data);
   virtual int ready() const;
   virtual void seek(double offset);
 

+ 2 - 1
panda/src/movies/vorbisAudioCursor.cxx

@@ -141,7 +141,7 @@ seek(double t) {
  * read.  Your buffer must be equal in size to N * channels.  Multiple-channel
  * audio will be interleaved.
  */
-void VorbisAudioCursor::
+int VorbisAudioCursor::
 read_samples(int n, int16_t *data) {
   int desired = n * _audio_channels;
 
@@ -186,6 +186,7 @@ read_samples(int n, int16_t *data) {
   }
 
   _samples_read += n;
+  return n;
 }
 
 /**

+ 1 - 1
panda/src/movies/vorbisAudioCursor.h

@@ -35,7 +35,7 @@ PUBLISHED:
   virtual void seek(double offset);
 
 public:
-  virtual void read_samples(int n, int16_t *data);
+  virtual int read_samples(int n, int16_t *data);
 
   bool _is_valid;
 

+ 5 - 3
panda/src/movies/wavAudioCursor.cxx

@@ -358,13 +358,13 @@ seek(double t) {
  * read.  Your buffer must be equal in size to N * channels.  Multiple-channel
  * audio will be interleaved.
  */
-void WavAudioCursor::
+int WavAudioCursor::
 read_samples(int n, int16_t *data) {
   int desired = n * _audio_channels;
   int read_samples = std::min(desired, ((int) (_data_size - _data_pos)) / _bytes_per_sample);
 
   if (read_samples <= 0) {
-    return;
+    return 0;
   }
 
   switch (_format) {
@@ -455,8 +455,10 @@ read_samples(int n, int16_t *data) {
   // Fill the rest of the buffer with silence.
   if (read_samples < desired) {
     memset(data + read_samples, 0, (desired - read_samples) * 2);
+    n = read_samples / _audio_channels;
   }
 
   _data_pos = _stream->tellg() - _data_start;
-  _samples_read += read_samples / _audio_channels;
+  _samples_read += n;
+  return n;
 }

+ 1 - 1
panda/src/movies/wavAudioCursor.h

@@ -31,7 +31,7 @@ PUBLISHED:
   virtual void seek(double offset);
 
 public:
-  virtual void read_samples(int n, int16_t *data);
+  virtual int read_samples(int n, int16_t *data);
 
   bool _is_valid;