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.
This commit is contained in:
rdb 2019-04-29 17:55:15 +02:00
parent 026c2bf619
commit c513342247
17 changed files with 42 additions and 26 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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