You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Laying the ground work for audio mapping (resampling and changing channel layouts) for the openshot::FrameMapper. This is important for use with the Timeline, that all clips have a common frame rate, sample rate, and channel layout.
This commit is contained in:
@@ -30,8 +30,9 @@
|
||||
using namespace std;
|
||||
using namespace openshot;
|
||||
|
||||
FrameMapper::FrameMapper(ReaderBase *reader, Fraction target, PulldownType pulldown) :
|
||||
reader(reader), target(target), pulldown(pulldown), final_cache(820 * 1024)
|
||||
FrameMapper::FrameMapper(ReaderBase *reader, Fraction target, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout) :
|
||||
reader(reader), target(target), pulldown(target_pulldown), sample_rate(target_sample_rate), channels(target_channels), channel_layout(target_channel_layout),
|
||||
final_cache(820 * 1024), is_dirty(true)
|
||||
{
|
||||
// Set the original frame rate from the reader
|
||||
original = Fraction(reader->info.fps.num, reader->info.fps.den);
|
||||
@@ -80,6 +81,12 @@ void FrameMapper::Init()
|
||||
fields.clear();
|
||||
frames.clear();
|
||||
|
||||
// Mark as not dirty
|
||||
is_dirty = false;
|
||||
|
||||
// Clear cache
|
||||
final_cache.Clear();
|
||||
|
||||
// Some framerates are handled special, and some use a generic Keyframe curve to
|
||||
// map the framerates. These are the special framerates:
|
||||
if ((original.ToInt() == 24 || original.ToInt() == 25 || original.ToInt() == 30) &&
|
||||
@@ -290,6 +297,11 @@ MappedFrame FrameMapper::GetMappedFrame(int TargetFrameNumber) throw(OutOfBounds
|
||||
// Get an openshot::Frame object for a specific frame number of this reader.
|
||||
tr1::shared_ptr<Frame> FrameMapper::GetFrame(int requested_frame) throw(ReaderClosed)
|
||||
{
|
||||
// Check if mappings are dirty (and need to be recalculated)
|
||||
if (is_dirty)
|
||||
// Recalculate mappings
|
||||
Init();
|
||||
|
||||
// Check final cache, and just return the frame (if it's available)
|
||||
if (final_cache.Exists(requested_frame))
|
||||
return final_cache.GetFrame(requested_frame);
|
||||
@@ -297,6 +309,14 @@ tr1::shared_ptr<Frame> FrameMapper::GetFrame(int requested_frame) throw(ReaderCl
|
||||
// Get the mapped frame
|
||||
MappedFrame mapped = GetMappedFrame(requested_frame);
|
||||
|
||||
// Return the original frame if no mapping is needed
|
||||
if (reader->info.fps.num == target.num && reader->info.fps.den == target.den &&
|
||||
reader->info.sample_rate == sample_rate && reader->info.channels == channels &&
|
||||
reader->info.channel_layout == channel_layout)
|
||||
// Return original frame (performance optimization)
|
||||
return reader->GetFrame(mapped.Odd.Frame);
|
||||
|
||||
|
||||
// Init some basic properties about this frame
|
||||
int samples_in_frame = Frame::GetSamplesPerFrame(requested_frame, target, info.sample_rate);
|
||||
|
||||
@@ -484,3 +504,18 @@ void FrameMapper::SetJsonValue(Json::Value root) throw(InvalidFile) {
|
||||
Open();
|
||||
}
|
||||
}
|
||||
|
||||
// Change frame rate or audio mapping details
|
||||
void FrameMapper::ChangeMapping(Fraction target_fps, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout)
|
||||
{
|
||||
// Mark as dirty
|
||||
is_dirty = true;
|
||||
|
||||
// Update mapping details
|
||||
target = target_fps;
|
||||
pulldown = target_pulldown;
|
||||
sample_rate = target_sample_rate;
|
||||
channels = target_channels;
|
||||
channel_layout = target_channel_layout;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user