You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Made Keyframe objects thread safe, by generating the values as Points are added, and the Timeline's Open and Close logic was made thread safe, so a reader is not closed while it's still being accessed on another thread. Also removed some unneeded code and comments.
This commit is contained in:
@@ -48,7 +48,6 @@ namespace openshot
|
||||
int channels; ///< The number of audio channels used in the audio stream
|
||||
int audio_stream_index; ///< The index of the audio stream
|
||||
Fraction audio_timebase; ///< The audio timebase determines how long each audio packet should be played
|
||||
bool visualize; ///< Replace the video stream with a waveform visualization of the audio samples
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace openshot {
|
||||
int sample_rate; ///<Sample rate of timeline
|
||||
int channels; ///<Channels in timeline
|
||||
list<Clip*> clips; ///<List of clips on this timeline
|
||||
list<Clip*> closing_clips; ///<List of clips that need to be closed
|
||||
map<Clip*, Clip*> open_clips; ///<List of 'opened' clips on this timeline
|
||||
Cache final_cache; ///<Final cache of timeline frames
|
||||
|
||||
@@ -65,6 +66,9 @@ namespace openshot {
|
||||
/// Update the list of 'opened' clips
|
||||
void update_open_clips(Clip *clip, bool is_open);
|
||||
|
||||
/// Update the list of 'closed' clips
|
||||
void update_closed_clips();
|
||||
|
||||
public:
|
||||
|
||||
/// Default Constructor for the timeline (which sets the canvas width and height and FPS)
|
||||
|
||||
@@ -56,8 +56,6 @@ void Clip::init_settings()
|
||||
// Default pointers
|
||||
file_reader = NULL;
|
||||
resampler = NULL;
|
||||
|
||||
cout << "INIT CLIP SETTINGS!!!!" << endl;
|
||||
}
|
||||
|
||||
// Default Constructor for a clip
|
||||
|
||||
@@ -199,9 +199,6 @@ void FFmpegReader::UpdateAudioInfo()
|
||||
info.audio_timebase.num = aStream->time_base.num;
|
||||
info.audio_timebase.den = aStream->time_base.den;
|
||||
|
||||
cout << "aStream->time_base: " << aStream->time_base.num << "/" << aStream->time_base.den << endl;
|
||||
cout << "aCodecCtx->time_base: " << aCodecCtx->time_base.num << "/" << aCodecCtx->time_base.den << endl;
|
||||
|
||||
// Get timebase of audio stream (if valid)
|
||||
if (aStream->duration > 0.0f)
|
||||
info.duration = aStream->duration * info.audio_timebase.ToDouble();
|
||||
|
||||
@@ -28,7 +28,6 @@ void FileWriterBase::InitFileInfo()
|
||||
info.channels = 0;
|
||||
info.audio_stream_index = -1;
|
||||
info.audio_timebase = Fraction();
|
||||
info.visualize = false;
|
||||
}
|
||||
|
||||
// Display file information
|
||||
@@ -66,7 +65,6 @@ void FileWriterBase::DisplayInfo() {
|
||||
cout << "--> # of Channels: " << info.channels << endl;
|
||||
cout << "--> Audio Stream Index: " << info.audio_stream_index << endl;
|
||||
cout << "--> Audio Timebase: " << info.audio_timebase.ToDouble() << " (" << info.audio_timebase.num << "/" << info.audio_timebase.den << ")" << endl;
|
||||
cout << "--> Visualize Waveform: " << info.visualize << endl;
|
||||
cout << "----------------------------" << endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -302,7 +302,6 @@ float* Frame::GetInterleavedAudioSamples(int new_sample_rate, AudioResampler* re
|
||||
for (int channel = 0; channel < num_of_channels; channel++)
|
||||
{
|
||||
// Add sample to output array
|
||||
//cout << position << ", " << channel << ", " << sample << endl;
|
||||
output[position] = buffer->getSampleData(channel)[sample];
|
||||
|
||||
// increment position
|
||||
@@ -528,11 +527,6 @@ void Frame::AddImage(tr1::shared_ptr<Magick::Image> new_image, float alpha)
|
||||
// Add audio samples to a specific channel
|
||||
void Frame::AddAudio(bool replaceSamples, int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource = 1.0f)
|
||||
{
|
||||
|
||||
// DEBUG CODE (FOR AUDIO ISSUES)
|
||||
//cout << "AddAudio: Frame: " << number << ", replaceSamples: " << replaceSamples << ", destChannel: " << destChannel << ", destStartSample: " << destStartSample << ", numSamples: " << numSamples << ", gain: " << gainToApplyToSource << ", end: " << (destStartSample + numSamples) << endl;
|
||||
//cout << " " << source[0] << "," << source[1] << "," << source[2] << " ... " << "," << source[numSamples-2] << "," << source[numSamples-1] << "," << source[numSamples] << "," << source[numSamples+1] << endl;
|
||||
|
||||
// Extend audio buffer (if needed)
|
||||
if (destStartSample + numSamples > audio->getNumSamples())
|
||||
audio->setSize(audio->getNumChannels(), destStartSample + numSamples, true, true, false);
|
||||
|
||||
@@ -62,6 +62,10 @@ void Keyframe::AddPoint(Point p) {
|
||||
|
||||
// Set Handles (used for smooth curves).
|
||||
SetHandles(p);
|
||||
|
||||
// Check if it needs to be processed
|
||||
if (needs_update)
|
||||
Process();
|
||||
}
|
||||
|
||||
// Add a new point on the key-frame, with some defaults set (BEZIER, AUTO Handles, etc...)
|
||||
|
||||
22
src/Main.cpp
22
src/Main.cpp
@@ -61,10 +61,10 @@ int main()
|
||||
// Add some clips
|
||||
//Clip c1(new FFmpegReader("/home/jonathan/Apps/videcho_site/media/user_files/videos/bd0bf442-3221-11e2-8bf6-001fd00ee3aa.webm"));
|
||||
//Clip c1(new FFmpegReader("/home/jonathan/Videos/Movie Music/02 - Shattered [Turn The Car Around] (Album Version).mp3"));
|
||||
FFmpegReader r1("../../src/examples/piano.wav");
|
||||
Clip c1(new FFmpegReader("/home/jonathan/Videos/sintel_trailer-720p.mp4"));
|
||||
Clip c2(new ImageReader("/home/jonathan/Desktop/logo.png"));
|
||||
Clip c3(new FFmpegReader("/home/jonathan/Videos/sintel_trailer-720p.mp4"));
|
||||
FFmpegReader r1("/home/jonathan/Videos/sintel-1024-stereo.mp4");
|
||||
Clip c1(new FFmpegReader("/home/jonathan/Videos/sintel-1024-stereo.mp4"));
|
||||
Clip c2(new ImageReader("/home/jonathan/Desktop/Logo.png"));
|
||||
Clip c3(new FFmpegReader("/home/jonathan/Videos/sintel-1024-stereo.mp4"));
|
||||
//Clip c3(new FFmpegReader("/home/jonathan/Videos/Movie Music/01 Whip It.mp3"));
|
||||
c1.Position(0.0);
|
||||
c1.gravity = GRAVITY_CENTER;
|
||||
@@ -181,10 +181,10 @@ int main()
|
||||
|
||||
// Add clips
|
||||
t.AddClip(&c1);
|
||||
//t.AddClip(&c2);
|
||||
t.AddClip(&c2);
|
||||
//t.AddClip(&c3);
|
||||
|
||||
r1.Open();
|
||||
//r1.Open();
|
||||
|
||||
// Create a writer
|
||||
FFmpegWriter w("/home/jonathan/output.webm");
|
||||
@@ -192,8 +192,8 @@ int main()
|
||||
|
||||
// Set options
|
||||
//w.SetAudioOptions(true, "libmp3lame", 44100, 2, 128000, false);
|
||||
w.SetAudioOptions(true, "libvorbis", 48000, 2, 128000);
|
||||
w.SetVideoOptions(true, "libvpx", Fraction(24,1), 624, 348, Fraction(1,1), false, false, 2000000);
|
||||
w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000);
|
||||
w.SetVideoOptions(true, "libvpx", Fraction(25,1), 624, 348, Fraction(1,1), false, false, 2000000);
|
||||
|
||||
// Prepare Streams
|
||||
w.PrepareStreams();
|
||||
@@ -204,13 +204,13 @@ int main()
|
||||
// Output stream info
|
||||
w.OutputStreamInfo();
|
||||
|
||||
for (int frame = 1; frame <= 100; frame++)
|
||||
for (int frame = 100; frame <= 200; frame++)
|
||||
{
|
||||
tr1::shared_ptr<Frame> f = r1.GetFrame(frame);
|
||||
tr1::shared_ptr<Frame> f = t.GetFrame(frame);
|
||||
if (f)
|
||||
{
|
||||
//if (frame >= 13)
|
||||
//f->DisplayWaveform();
|
||||
//f->Display();
|
||||
|
||||
// Write frame
|
||||
cout << "queue frame " << frame << " (" << f->number << ", " << f << ")" << endl;
|
||||
|
||||
@@ -231,11 +231,8 @@ void Timeline::update_open_clips(Clip *clip, bool is_open)
|
||||
|
||||
if (clip_found && !is_open)
|
||||
{
|
||||
// Remove clip from 'opened' list, because it's closed now
|
||||
open_clips.erase(clip);
|
||||
|
||||
// Close the clip's reader
|
||||
clip->Close();
|
||||
// Mark clip "to be removed"
|
||||
closing_clips.push_back(clip);
|
||||
}
|
||||
else if (!clip_found && is_open)
|
||||
{
|
||||
@@ -247,6 +244,27 @@ void Timeline::update_open_clips(Clip *clip, bool is_open)
|
||||
}
|
||||
}
|
||||
|
||||
// Update the list of 'closed' clips
|
||||
void Timeline::update_closed_clips()
|
||||
{
|
||||
// Close all "to be closed" clips
|
||||
list<Clip*>::iterator clip_itr;
|
||||
for (clip_itr=closing_clips.begin(); clip_itr != closing_clips.end(); ++clip_itr)
|
||||
{
|
||||
// Get clip object from the iterator
|
||||
Clip *clip = (*clip_itr);
|
||||
|
||||
// Close the clip's reader
|
||||
clip->Close();
|
||||
|
||||
// Remove clip from 'opened' list, because it's closed now
|
||||
open_clips.erase(clip);
|
||||
}
|
||||
|
||||
// Clear list
|
||||
closing_clips.clear();
|
||||
}
|
||||
|
||||
// Sort clips by position on the timeline
|
||||
void Timeline::SortClips()
|
||||
{
|
||||
@@ -267,6 +285,9 @@ void Timeline::Close()
|
||||
// Open or Close this clip, based on if it's intersecting or not
|
||||
update_open_clips(clip, false);
|
||||
}
|
||||
|
||||
// Actually close the clips
|
||||
update_closed_clips();
|
||||
}
|
||||
|
||||
// Open the reader (and start consuming resources)
|
||||
@@ -319,7 +340,7 @@ tr1::shared_ptr<Frame> Timeline::GetFrame(int requested_frame) throw(ReaderClose
|
||||
// Loop through all requested frames
|
||||
for (int frame_number = requested_frame; frame_number < requested_frame + minimum_frames; frame_number++)
|
||||
{
|
||||
#pragma xxx omp task firstprivate(frame_number)
|
||||
#pragma omp task firstprivate(frame_number)
|
||||
{
|
||||
// Create blank frame (which will become the requested frame)
|
||||
tr1::shared_ptr<Frame> new_frame(tr1::shared_ptr<Frame>(new Frame(frame_number, width, height, "#000000", GetSamplesPerFrame(frame_number), channels)));
|
||||
@@ -339,7 +360,7 @@ tr1::shared_ptr<Frame> Timeline::GetFrame(int requested_frame) throw(ReaderClose
|
||||
float clip_duration = clip->End() - clip->Start();
|
||||
bool does_clip_intersect = (clip->Position() <= requested_time && clip->Position() + clip_duration >= requested_time);
|
||||
|
||||
// Open or Close this clip, based on if it's intersecting or not
|
||||
// Open (or schedule for closing) this clip, based on if it's intersecting or not
|
||||
#pragma omp critical (reader_lock)
|
||||
update_open_clips(clip, does_clip_intersect);
|
||||
|
||||
@@ -374,6 +395,10 @@ tr1::shared_ptr<Frame> Timeline::GetFrame(int requested_frame) throw(ReaderClose
|
||||
} // end omp task
|
||||
} // end frame loop
|
||||
|
||||
// Actually close all clips no longer needed
|
||||
#pragma omp critical (reader_lock)
|
||||
update_closed_clips();
|
||||
|
||||
} // end omp single
|
||||
} // end omp parallel
|
||||
|
||||
|
||||
Reference in New Issue
Block a user