Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/audaspace/plugins')
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp80
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.h17
-rw-r--r--extern/audaspace/plugins/pulseaudio/PulseAudioDevice.cpp19
-rw-r--r--extern/audaspace/plugins/pulseaudio/PulseAudioDevice.h2
4 files changed, 88 insertions, 30 deletions
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
index b46f65eddbf..afdc7fcfcc6 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
@@ -68,7 +68,7 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
for(int i = 0; i < m_frame->nb_samples; i++)
{
std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
- m_frame->data[channel] + i * single_size, single_size);
+ m_frame->data[channel] + i * single_size, single_size);
}
}
}
@@ -109,7 +109,7 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
for(int i = 0; i < m_frame->nb_samples; i++)
{
std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
- m_frame->data[channel] + i * single_size, single_size);
+ m_frame->data[channel] + i * single_size, single_size);
}
}
}
@@ -126,7 +126,10 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
void FFMPEGReader::init()
{
m_position = 0;
+ m_start_offset = 0.0f;
m_pkgbuf_left = 0;
+ m_st_time = 0;
+ m_duration = 0;
if(avformat_find_stream_info(m_formatCtx, nullptr) < 0)
AUD_THROW(FileException, "File couldn't be read, ffmpeg couldn't find the stream info.");
@@ -134,15 +137,41 @@ void FFMPEGReader::init()
// find audio stream and codec
m_stream = -1;
+ double dur_sec = 0;
+
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
{
#ifdef FFMPEG_OLD_CODE
- if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ if(m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
#else
- if((m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
+ if(m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
#endif
- && (m_stream < 0))
{
+ AVStream *audio_stream = m_formatCtx->streams[i];
+ double audio_timebase = av_q2d(audio_stream->time_base);
+
+ if (audio_stream->start_time != AV_NOPTS_VALUE)
+ {
+ m_st_time = audio_stream->start_time;
+ }
+
+ int64_t ctx_start_time = 0;
+ if (m_formatCtx->start_time != AV_NOPTS_VALUE) {
+ ctx_start_time = m_formatCtx->start_time;
+ }
+
+ m_start_offset = m_st_time * audio_timebase - (double)ctx_start_time / AV_TIME_BASE;
+
+ if(audio_stream->duration != AV_NOPTS_VALUE)
+ {
+ dur_sec = audio_stream->duration * audio_timebase;
+ }
+ else
+ {
+ /* If the audio starts after the stream start time, subract this from the total duration. */
+ dur_sec = (double)m_formatCtx->duration / AV_TIME_BASE - m_start_offset;
+ }
+
m_stream=i;
break;
}
@@ -213,6 +242,7 @@ void FFMPEGReader::init()
}
m_specs.rate = (SampleRate) m_codecCtx->sample_rate;
+ m_duration = lround(dur_sec * m_codecCtx->sample_rate);
}
FFMPEGReader::FFMPEGReader(std::string filename) :
@@ -338,21 +368,17 @@ void FFMPEGReader::seek(int position)
{
if(position >= 0)
{
- uint64_t st_time = m_formatCtx->start_time;
- uint64_t seek_pos = ((uint64_t)position) * ((uint64_t)AV_TIME_BASE) / ((uint64_t)m_specs.rate);
+ double pts_time_base =
+ av_q2d(m_formatCtx->streams[m_stream]->time_base);
- if(st_time != AV_NOPTS_VALUE) {
- seek_pos += st_time;
- }
+ uint64_t seek_pts = (((uint64_t)position) / ((uint64_t)m_specs.rate)) / pts_time_base;
- double pts_time_base =
- av_q2d(m_formatCtx->streams[m_stream]->time_base);
- uint64_t pts_st_time =
- ((st_time != AV_NOPTS_VALUE) ? st_time : 0)
- / pts_time_base / (uint64_t) AV_TIME_BASE;
+ if(m_st_time != AV_NOPTS_VALUE) {
+ seek_pts += m_st_time;
+ }
// a value < 0 tells us that seeking failed
- if(av_seek_frame(m_formatCtx, -1, seek_pos,
+ if(av_seek_frame(m_formatCtx, m_stream, seek_pts,
AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
{
avcodec_flush_buffers(m_codecCtx);
@@ -374,7 +400,7 @@ void FFMPEGReader::seek(int position)
if(packet.pts != AV_NOPTS_VALUE)
{
// calculate real position, and read to frame!
- m_position = (packet.pts - pts_st_time) * pts_time_base * m_specs.rate;
+ m_position = (packet.pts - m_st_time) * pts_time_base * m_specs.rate;
if(m_position < position)
{
@@ -405,8 +431,7 @@ void FFMPEGReader::seek(int position)
int FFMPEGReader::getLength() const
{
// return approximated remaning size
- return (int)((m_formatCtx->duration * m_codecCtx->sample_rate)
- / AV_TIME_BASE)-m_position;
+ return m_duration - m_position;
}
int FFMPEGReader::getPosition() const
@@ -414,6 +439,11 @@ int FFMPEGReader::getPosition() const
return m_position;
}
+double FFMPEGReader::getStartOffset() const
+{
+ return m_start_offset;
+}
+
Specs FFMPEGReader::getSpecs() const
{
return m_specs.specs;
@@ -450,11 +480,13 @@ void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
// decode the package
pkgbuf_pos = decode(packet, m_pkgbuf);
- // copy to output buffer
- data_size = std::min(pkgbuf_pos, left * sample_size);
- m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
- buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size / sample_size;
+ if (packet.pts >= m_st_time) {
+ // copy to output buffer
+ data_size = std::min(pkgbuf_pos, left * sample_size);
+ m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
+ left -= data_size / sample_size;
+ }
}
av_packet_unref(&packet);
}
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
index f62436ac83b..d613457c220 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
@@ -55,6 +55,22 @@ private:
int m_position;
/**
+ * The start offset in seconds relative to the media container start time.
+ * IE how much the sound should be delayed to be kept in sync with the rest of the containter streams.
+ */
+ double m_start_offset;
+
+ /**
+ * The start time pts of the stream. All packets before this timestamp shouldn't be played back (only decoded).
+ */
+ int64_t m_st_time;
+
+ /**
+ * The duration of the audio stream in samples.
+ */
+ int64_t m_duration;
+
+ /**
* The specification of the audio data.
*/
DeviceSpecs m_specs;
@@ -182,6 +198,7 @@ public:
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
+ virtual double getStartOffset() const;
virtual Specs getSpecs() const;
virtual void read(int& length, bool& eos, sample_t* buffer);
};
diff --git a/extern/audaspace/plugins/pulseaudio/PulseAudioDevice.cpp b/extern/audaspace/plugins/pulseaudio/PulseAudioDevice.cpp
index cbfb5e96e6c..bf3fad82620 100644
--- a/extern/audaspace/plugins/pulseaudio/PulseAudioDevice.cpp
+++ b/extern/audaspace/plugins/pulseaudio/PulseAudioDevice.cpp
@@ -32,17 +32,24 @@ void PulseAudioDevice::PulseAudio_state_callback(pa_context *context, void *data
device->m_state = AUD_pa_context_get_state(context);
}
-void PulseAudioDevice::PulseAudio_request(pa_stream *stream, size_t num_bytes, void *data)
+void PulseAudioDevice::PulseAudio_request(pa_stream *stream, size_t total_bytes, void *data)
{
PulseAudioDevice* device = (PulseAudioDevice*)data;
void* buffer;
- AUD_pa_stream_begin_write(stream, &buffer, &num_bytes);
+ while(total_bytes > 0)
+ {
+ size_t num_bytes = total_bytes;
+
+ AUD_pa_stream_begin_write(stream, &buffer, &num_bytes);
+
+ device->mix((data_t*)buffer, num_bytes / AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
- device->mix((data_t*)buffer, num_bytes / AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
+ AUD_pa_stream_write(stream, buffer, num_bytes, nullptr, 0, PA_SEEK_RELATIVE);
- AUD_pa_stream_write(stream, buffer, num_bytes, nullptr, 0, PA_SEEK_RELATIVE);
+ total_bytes -= num_bytes;
+ }
}
void PulseAudioDevice::PulseAudio_underflow(pa_stream *stream, void *data)
@@ -96,7 +103,6 @@ void PulseAudioDevice::runMixingThread()
PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize) :
m_state(PA_CONTEXT_UNCONNECTED),
- m_buffersize(buffersize),
m_underflows(0)
{
m_mainloop = AUD_pa_mainloop_new();
@@ -187,6 +193,9 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
AUD_pa_stream_set_write_callback(m_stream, PulseAudio_request, this);
AUD_pa_stream_set_underflow_callback(m_stream, PulseAudio_underflow, this);
+ buffersize *= AUD_DEVICE_SAMPLE_SIZE(m_specs);
+ m_buffersize = buffersize;
+
pa_buffer_attr buffer_attr;
buffer_attr.fragsize = -1U;
diff --git a/extern/audaspace/plugins/pulseaudio/PulseAudioDevice.h b/extern/audaspace/plugins/pulseaudio/PulseAudioDevice.h
index be34cc9032b..45b813a5755 100644
--- a/extern/audaspace/plugins/pulseaudio/PulseAudioDevice.h
+++ b/extern/audaspace/plugins/pulseaudio/PulseAudioDevice.h
@@ -59,7 +59,7 @@ private:
* \param num_bytes The length in bytes to be supplied.
* \param data The PulseAudio device.
*/
- AUD_LOCAL static void PulseAudio_request(pa_stream* stream, size_t num_bytes, void* data);
+ AUD_LOCAL static void PulseAudio_request(pa_stream* stream, size_t total_bytes, void* data);
/**
* Reports an underflow from the PulseAudio server.