Loading...
Searching...
No Matches
FrameMapper.h
Go to the documentation of this file.
// Copyright (c) 2008-2019 OpenShot Studios, LLC
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#ifndef OPENSHOT_FRAMEMAPPER_H
#define OPENSHOT_FRAMEMAPPER_H
#include <assert.h>
#include <iostream>
#include <vector>
#include <memory>
#include "AudioResampler.h"
#include "CacheMemory.h"
#include "ReaderBase.h"
#include "Frame.h"
#include "Fraction.h"
#include "KeyFrame.h"
// Include FFmpeg headers and macros
#include "FFmpegUtilities.h"
#include "OpenMPUtilities.h"
namespace openshot
{
enum PulldownType
{
PULLDOWN_CLASSIC,
PULLDOWN_ADVANCED,
PULLDOWN_NONE,
};
struct Field
{
int64_t Frame;
bool isOdd;
Field() : Frame(0), isOdd(true) { };
Field(int64_t frame, bool isodd)
{
Frame = frame;
isOdd = isodd;
}
};
struct SampleRange
{
int64_t frame_start;
int sample_start;
int64_t frame_end;
int sample_end;
void Extend(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side) {
int remaining_samples = samples;
while (remaining_samples > 0) {
if (right_side) {
// Extend range to the right
int samples_per_frame = Frame::GetSamplesPerFrame(frame_end, fps, sample_rate, channels);
if (remaining_samples + sample_end < samples_per_frame) {
sample_end += remaining_samples;
remaining_samples = 0;
} else {
frame_end++;
remaining_samples -= (samples_per_frame - sample_end);
sample_end = 0;
}
} else {
// Extend range to the left
if (sample_start - remaining_samples >= 0) {
sample_start -= remaining_samples;
remaining_samples = 0;
} else {
frame_start--;
remaining_samples -= (sample_start + 1);
sample_start = Frame::GetSamplesPerFrame(frame_start, fps, sample_rate, channels) - 1;
}
}
}
// Increase total
total += samples;
}
void Shrink(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side) {
int remaining_samples = samples;
while (remaining_samples > 0) {
if (right_side) {
// Shrink range on the right
if (sample_end - remaining_samples >= 0) {
sample_end -= remaining_samples;
remaining_samples = 0;
} else {
frame_end--;
int samples_per_frame = Frame::GetSamplesPerFrame(frame_end, fps, sample_rate, channels);
remaining_samples -= (sample_end + 1);
sample_end = samples_per_frame - 1;
}
} else {
// Shrink range on the left
int samples_per_frame = Frame::GetSamplesPerFrame(frame_start, fps, sample_rate, channels);
if (sample_start + remaining_samples < samples_per_frame) {
sample_start += remaining_samples;
remaining_samples = 0;
} else {
frame_start++;
remaining_samples -= (samples_per_frame - sample_start);
sample_start = 0;
}
}
}
// Reduce total
total -= samples;
}
void Shift(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side) {
// Extend each side of the range (to SHIFT the range) by adding (or subtracting) from both sides
// For example: [ range ]
// For example: [ range ]
if (right_side) {
// SHIFT both sides to the right
Extend(samples, fps, sample_rate, channels, true);
Shrink(samples, fps, sample_rate, channels, false);
} else {
// SHIFT both sides to the left
Extend(samples, fps, sample_rate, channels, false);
Shrink(samples, fps, sample_rate, channels, true);
}
}
int total;
};
struct MappedFrame
{
Field Odd;
Field Even;
SampleRange Samples;
};
class FrameMapper : public ReaderBase {
private:
bool field_toggle; // Internal odd / even toggle (used when building the mapping)
Fraction original; // The original frame rate
Fraction target; // The target frame rate
PulldownType pulldown; // The pull-down technique
ReaderBase *reader; // The source video reader
CacheMemory final_cache; // Cache of actual Frame objects
bool is_dirty; // When this is true, the next call to GetFrame will re-init the mapping
float parent_position; // Position of parent clip (which is used to generate the audio mapping)
float parent_start; // Start of parent clip (which is used to generate the audio mapping)
int64_t previous_frame; // Used during resampling, to determine when a large gap is detected
SWRCONTEXT *avr; // Audio resampling context object
// Audio resampler (if resampling audio)
openshot::AudioResampler *resampler;
// Internal methods used by init
void AddField(int64_t frame);
void AddField(Field field);
// Clear both the fields & frames lists
void Clear();
// Get Frame or Generate Blank Frame
std::shared_ptr<Frame> GetOrCreateFrame(int64_t number);
int64_t AdjustFrameNumber(int64_t clip_frame_number);
// Use the original and target frame rates and a pull-down technique to create
// a mapping between the original fields and frames or a video to a new frame rate.
// This might repeat or skip fields and frames of the original video, depending on
// whether the frame rate is increasing or decreasing.
void Init();
public:
// Init some containers
std::vector<Field> fields; // List of all fields
std::vector<MappedFrame> frames; // List of all frames
FrameMapper(ReaderBase *reader, Fraction target_fps, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
virtual ~FrameMapper();
void ChangeMapping(Fraction target_fps, PulldownType pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
void Close() override;
MappedFrame GetMappedFrame(int64_t TargetFrameNumber);
CacheMemory* GetCache() override { return &final_cache; };
std::shared_ptr<Frame> GetFrame(int64_t requested_frame) override;
bool IsOpen() override;
std::string Name() override { return "FrameMapper"; };
// Get and Set JSON methods
std::string Json() const override;
void SetJson(const std::string value) override;
Json::Value JsonValue() const override;
void SetJsonValue(const Json::Value root) override;
void Open() override;
void PrintMapping(std::ostream* out=&std::cout);
ReaderBase* Reader();
void Reader(ReaderBase *new_reader) { reader = new_reader; }
void ResampleMappedAudio(std::shared_ptr<Frame> frame, int64_t original_frame_number);
};
}
#endif
AudioResampler.h
Header file for AudioResampler class.
CacheMemory.h
Header file for CacheMemory class.
FFmpegUtilities.h
Header file for FFmpegUtilities.
SWRCONTEXT
#define SWRCONTEXT
Definition FFmpegUtilities.h:148
Fraction.h
Header file for Fraction class.
Frame.h
Header file for Frame class.
KeyFrame.h
Header file for the Keyframe class.
OpenMPUtilities.h
Header file for OpenMPUtilities (set some common macros)
ReaderBase.h
Header file for ReaderBase class.
openshot::AudioResampler
This class is used to resample audio data for many sequential frames.
Definition AudioResampler.h:30
openshot::CacheMemory
This class is a memory-based cache manager for Frame objects.
Definition CacheMemory.h:29
openshot::Fraction
This class represents a fraction.
Definition Fraction.h:30
openshot::FrameMapper
This class creates a mapping between 2 different frame rates, applying a specific pull-down technique...
Definition FrameMapper.h:201
openshot::FrameMapper::GetFrame
std::shared_ptr< Frame > GetFrame(int64_t requested_frame) override
This method is required for all derived classes of ReaderBase, and return the openshot::Frame object,...
Definition FrameMapper.cpp:423
openshot::FrameMapper::ChangeMapping
void ChangeMapping(Fraction target_fps, PulldownType pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout)
Change frame rate or audio mapping details.
Definition FrameMapper.cpp:779
openshot::FrameMapper::Reader
void Reader(ReaderBase *new_reader)
Set the current reader.
Definition FrameMapper.h:290
openshot::FrameMapper::GetMappedFrame
MappedFrame GetMappedFrame(int64_t TargetFrameNumber)
Get a frame based on the target frame rate and the new frame number of a frame.
Definition FrameMapper.cpp:339
openshot::FrameMapper::Name
std::string Name() override
Return the type name of the class.
Definition FrameMapper.h:272
openshot::FrameMapper::SetJsonValue
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition FrameMapper.cpp:765
openshot::FrameMapper::IsOpen
bool IsOpen() override
Determine if reader is open or closed.
Definition FrameMapper.cpp:669
openshot::FrameMapper::fields
std::vector< Field > fields
Definition FrameMapper.h:239
openshot::FrameMapper::Reader
ReaderBase * Reader()
Get the current reader.
Definition FrameMapper.cpp:64
openshot::FrameMapper::frames
std::vector< MappedFrame > frames
Definition FrameMapper.h:240
openshot::FrameMapper::ResampleMappedAudio
void ResampleMappedAudio(std::shared_ptr< Frame > frame, int64_t original_frame_number)
Resample audio and map channels (if needed)
Definition FrameMapper.cpp:824
openshot::FrameMapper::Open
void Open() override
Open the internal reader.
Definition FrameMapper.cpp:677
openshot::FrameMapper::GetCache
CacheMemory * GetCache() override
Get the cache object used by this reader.
Definition FrameMapper.h:258
openshot::FrameMapper::Close
void Close() override
Close the openshot::FrameMapper and internal reader.
Definition FrameMapper.cpp:689
openshot::FrameMapper::Json
std::string Json() const override
Generate JSON string of this object.
Definition FrameMapper.cpp:721
openshot::FrameMapper::PrintMapping
void PrintMapping(std::ostream *out=&std::cout)
Print all of the original frames and which new frames they map to.
Definition FrameMapper.cpp:643
openshot::FrameMapper::SetJson
void SetJson(const std::string value) override
Load JSON string into this object.
Definition FrameMapper.cpp:742
openshot::FrameMapper::JsonValue
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition FrameMapper.cpp:728
openshot::FrameMapper::~FrameMapper
virtual ~FrameMapper()
Destructor.
Definition FrameMapper.cpp:55
openshot::Frame
This class represents a single frame of video (i.e. image & audio data)
Definition Frame.h:91
openshot::Frame::GetSamplesPerFrame
int GetSamplesPerFrame(openshot::Fraction fps, int sample_rate, int channels)
Calculate the # of samples per video frame (for the current frame number)
Definition Frame.cpp:480
openshot::ReaderBase
This abstract class is the base class, used by all readers in libopenshot.
Definition ReaderBase.h:76
openshot
This namespace is the default namespace for all code in the openshot library.
Definition Compressor.h:29
openshot::PulldownType
PulldownType
This enumeration determines how frame rates are increased or decreased.
Definition FrameMapper.h:43
openshot::PULLDOWN_CLASSIC
@ PULLDOWN_CLASSIC
Classic 2:3:2:3 pull-down.
Definition FrameMapper.h:44
openshot::PULLDOWN_ADVANCED
@ PULLDOWN_ADVANCED
Advanced 2:3:3:2 pull-down (minimal dirty frames)
Definition FrameMapper.h:45
openshot::PULLDOWN_NONE
@ PULLDOWN_NONE
Do not apply pull-down techniques, just repeat or skip entire frames.
Definition FrameMapper.h:46
openshot::ChannelLayout
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
Definition ChannelLayouts.h:29
openshot::Field
This struct holds a single field (half a frame).
Definition FrameMapper.h:56
openshot::Field::isOdd
bool isOdd
Definition FrameMapper.h:58
openshot::Field::Field
Field()
Definition FrameMapper.h:60
openshot::Field::Frame
int64_t Frame
Definition FrameMapper.h:57
openshot::Field::Field
Field(int64_t frame, bool isodd)
Definition FrameMapper.h:62
openshot::MappedFrame
This struct holds two fields which together make up a complete video frame.
Definition FrameMapper.h:173
openshot::MappedFrame::Odd
Field Odd
Definition FrameMapper.h:174
openshot::MappedFrame::Even
Field Even
Definition FrameMapper.h:175
openshot::MappedFrame::Samples
SampleRange Samples
Definition FrameMapper.h:176
openshot::SampleRange
This struct holds a the range of samples needed by this frame.
Definition FrameMapper.h:76
openshot::SampleRange::sample_end
int sample_end
Definition FrameMapper.h:81
openshot::SampleRange::frame_end
int64_t frame_end
Definition FrameMapper.h:80
openshot::SampleRange::total
int total
Definition FrameMapper.h:163
openshot::SampleRange::Shrink
void Shrink(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side)
Shrink SampleRange on either side.
Definition FrameMapper.h:116
openshot::SampleRange::frame_start
int64_t frame_start
Definition FrameMapper.h:77
openshot::SampleRange::Extend
void Extend(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side)
Extend SampleRange on either side.
Definition FrameMapper.h:84
openshot::SampleRange::sample_start
int sample_start
Definition FrameMapper.h:78
openshot::SampleRange::Shift
void Shift(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side)
Definition FrameMapper.h:148