You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Fixed bugs in new AudioReaderSource class. Also fixed a few small issues in the FFmpegReader class.
This commit is contained in:
@@ -54,15 +54,16 @@ namespace openshot
|
||||
class AudioReaderSource : public PositionableAudioSource
|
||||
{
|
||||
private:
|
||||
int position;
|
||||
int start;
|
||||
bool repeat;
|
||||
AudioSampleBuffer *buffer;
|
||||
int position; /// The position of the audio source (index of buffer)
|
||||
bool repeat; /// Repeat the audio source when finished
|
||||
int size; /// The size of the internal buffer
|
||||
AudioSampleBuffer *buffer; /// The audio sample buffer
|
||||
|
||||
int size; /// The size of the buffer
|
||||
ReaderBase *reader; /// The reader to pull samples from
|
||||
int64 frame_number; /// The current frame to read from
|
||||
int64 original_frame_number; /// The current frame to read from
|
||||
int64 frame_number; /// The current frame number
|
||||
tr1::shared_ptr<Frame> frame; /// The current frame object that is being read
|
||||
int frame_position; /// The position of the current frame's buffer
|
||||
|
||||
/// Get more samples from the reader
|
||||
void GetMoreSamplesFromReader();
|
||||
|
||||
@@ -32,7 +32,8 @@ using namespace openshot;
|
||||
|
||||
// Constructor that reads samples from a reader
|
||||
AudioReaderSource::AudioReaderSource(ReaderBase *audio_reader, int64 starting_frame_number, int buffer_size)
|
||||
: reader(audio_reader), frame_number(starting_frame_number), size(buffer_size) {
|
||||
: reader(audio_reader), frame_number(starting_frame_number), original_frame_number(starting_frame_number),
|
||||
size(buffer_size), position(0), frame_position(0) {
|
||||
|
||||
// Initialize an audio buffer (based on reader)
|
||||
buffer = new juce::AudioSampleBuffer(reader->info.channels, size);
|
||||
@@ -51,55 +52,86 @@ AudioReaderSource::~AudioReaderSource()
|
||||
|
||||
// Get more samples from the reader
|
||||
void AudioReaderSource::GetMoreSamplesFromReader() {
|
||||
|
||||
// Determine the amount of samples needed to fill up this buffer
|
||||
int amount_needed = start; // replace these used samples
|
||||
int amount_remaining = size - start;
|
||||
int amount_needed = position; // replace these used samples
|
||||
int amount_remaining = size - amount_needed; // these are unused samples, and need to be carried forward
|
||||
if (!frame) {
|
||||
// If no frame, load entire buffer
|
||||
amount_needed = size;
|
||||
amount_remaining = size;
|
||||
amount_remaining = 0;
|
||||
}
|
||||
|
||||
// Init new buffer
|
||||
juce::AudioSampleBuffer *new_buffer = new juce::AudioSampleBuffer(reader->info.channels, size);
|
||||
new_buffer->clear();
|
||||
|
||||
// Move the remaining samples into new buffer (if any)
|
||||
if (start > 0) {
|
||||
if (amount_remaining > 0) {
|
||||
for (int channel = 0; channel < buffer->getNumChannels(); channel++)
|
||||
new_buffer->copyFrom(channel, 0, *buffer, channel, start, amount_remaining);
|
||||
start = amount_remaining;
|
||||
}
|
||||
new_buffer->addFrom(channel, 0, *buffer, channel, position, amount_remaining);
|
||||
position = amount_remaining;
|
||||
} else
|
||||
// reset position to 0
|
||||
position = 0;
|
||||
|
||||
// Loop through frames until buffer filled
|
||||
int fill_start = start;
|
||||
while (amount_needed > 0) {
|
||||
|
||||
// Get the next frame
|
||||
try {
|
||||
frame = reader->GetFrame(frame_number++);
|
||||
} catch (const ReaderClosed & e) {
|
||||
break;
|
||||
} catch (const TooManySeeks & e) {
|
||||
break;
|
||||
} catch (const OutOfBoundsFrame & e) {
|
||||
break;
|
||||
}
|
||||
// Get the next frame (if position is zero)
|
||||
if (frame_position == 0) {
|
||||
try {
|
||||
// Get frame object
|
||||
frame = reader->GetFrame(frame_number++);
|
||||
|
||||
// Is buffer big enough to hold entire frame
|
||||
if (fill_start + frame->GetAudioSamplesCount() > size) {
|
||||
// Increase size of buffer
|
||||
new_buffer->setSize(frame->GetAudioChannelsCount(), fill_start + frame->GetAudioSamplesCount(), true, true, false);
|
||||
size = new_buffer->getNumSamples();
|
||||
} catch (const ReaderClosed & e) {
|
||||
break;
|
||||
} catch (const TooManySeeks & e) {
|
||||
break;
|
||||
} catch (const OutOfBoundsFrame & e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Load all of its samples into the buffer
|
||||
for (int channel = 0; channel < new_buffer->getNumChannels(); channel++)
|
||||
new_buffer->copyFrom(channel, fill_start, *frame->GetAudioSampleBuffer(), channel, 0, frame->GetAudioSamplesCount());
|
||||
bool frame_completed = false;
|
||||
int amount_to_copy = frame->GetAudioSamplesCount();
|
||||
if (amount_to_copy > amount_needed) {
|
||||
// Don't copy too many samples (we don't want to overflow the buffer)
|
||||
amount_to_copy = amount_needed;
|
||||
amount_needed = 0;
|
||||
} else {
|
||||
// Not enough to fill the buffer (so use the entire frame)
|
||||
amount_needed -= amount_to_copy;
|
||||
frame_completed = true;
|
||||
}
|
||||
|
||||
if (frame->number > 200) {
|
||||
frame->DisplayWaveform();
|
||||
for (int y = 0; y < frame->GetAudioSamplesCount(); y++)
|
||||
cout << y << ": " << frame->GetAudioSampleBuffer()->getSampleData(0)[y] << endl;
|
||||
|
||||
// Load all of its samples into the buffer
|
||||
for (int channel = 0; channel < new_buffer->getNumChannels(); channel++)
|
||||
new_buffer->addFrom(channel, position, *frame->GetAudioSampleBuffer(), channel, frame_position, amount_to_copy);
|
||||
}
|
||||
|
||||
// Adjust remaining samples
|
||||
amount_remaining -= fill_start + frame->GetAudioSamplesCount();
|
||||
fill_start += frame->GetAudioSamplesCount();
|
||||
position += amount_to_copy;
|
||||
if (frame_completed)
|
||||
// Reset frame buffer position (which will load a new frame on the next loop)
|
||||
frame_position = 0;
|
||||
else
|
||||
// Continue tracking the current frame's position
|
||||
frame_position += amount_to_copy;
|
||||
}
|
||||
|
||||
// Delete old buffer
|
||||
buffer->clear();
|
||||
delete buffer;
|
||||
|
||||
// Replace buffer and reset position
|
||||
buffer = new_buffer;
|
||||
position = 0;
|
||||
}
|
||||
|
||||
// Get the next block of audio samples
|
||||
|
||||
@@ -1290,7 +1290,7 @@ tr1::shared_ptr<Frame> FFmpegReader::CreateFrame(int requested_frame)
|
||||
else
|
||||
{
|
||||
// Create a new frame on the working cache
|
||||
tr1::shared_ptr<Frame> f(new Frame(requested_frame, info.width, info.height, "#000000", 0, info.channels));
|
||||
tr1::shared_ptr<Frame> f(new Frame(requested_frame, info.width, info.height, "#000000", Frame::GetSamplesPerFrame(requested_frame, info.fps, info.sample_rate), info.channels));
|
||||
f->SetPixelRatio(info.pixel_ratio.num, info.pixel_ratio.den);
|
||||
|
||||
working_cache.Add(requested_frame, f);
|
||||
|
||||
22
src/Main.cpp
22
src/Main.cpp
@@ -40,11 +40,23 @@ using namespace tr1;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FFmpegReader r99("/home/jonathan/Videos/sintel_trailer-720p.mp4");
|
||||
r99.Open();
|
||||
for (int count99 = 1; count99 < 10000000; count99++) {
|
||||
cout << count99 << endl;
|
||||
r99.GetFrame(count99);
|
||||
FFmpegReader sinelReader("/home/jonathan/Videos/sintel_trailer-720p.mp4");
|
||||
sinelReader.Open();
|
||||
|
||||
AudioReaderSource readerSource(&sinelReader, 1, 10000);
|
||||
for (int z = 0; z < 2000; z++) {
|
||||
// Get audio chunks
|
||||
int chunk_size = 750;
|
||||
juce::AudioSampleBuffer *master_buffer = new juce::AudioSampleBuffer(sinelReader.info.channels, chunk_size);
|
||||
master_buffer->clear();
|
||||
const AudioSourceChannelInfo info = {master_buffer, 0, chunk_size};
|
||||
|
||||
// Get next audio block
|
||||
readerSource.getNextAudioBlock(info);
|
||||
|
||||
// Delete buffer
|
||||
master_buffer->clear();
|
||||
delete master_buffer;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user