OpenShot Library | libopenshot 0.3.3
Loading...
Searching...
No Matches
FrameMapper.h
Go to the documentation of this file.
1
9// Copyright (c) 2008-2019 OpenShot Studios, LLC
10//
11// SPDX-License-Identifier: LGPL-3.0-or-later
12
13#ifndef OPENSHOT_FRAMEMAPPER_H
14#define OPENSHOT_FRAMEMAPPER_H
15
16#include <assert.h>
17#include <iostream>
18#include <vector>
19#include <memory>
20
21#include "AudioResampler.h"
22#include "CacheMemory.h"
23#include "ReaderBase.h"
24#include "Frame.h"
25#include "Fraction.h"
26#include "KeyFrame.h"
27
28
29// Include FFmpeg headers and macros
30#include "FFmpegUtilities.h"
31#include "OpenMPUtilities.h"
32
33
34namespace openshot
35{
48
55 struct Field
56 {
57 int64_t Frame;
58 bool isOdd;
59 };
60
68 {
69 int64_t frame_start;
71
72 int64_t frame_end;
74
76 void Extend(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side) {
77 int remaining_samples = samples;
78 while (remaining_samples > 0) {
79 if (right_side) {
80 // Extend range to the right
81 int samples_per_frame = Frame::GetSamplesPerFrame(frame_end, fps, sample_rate, channels);
82 if (remaining_samples + sample_end < samples_per_frame) {
83 sample_end += remaining_samples;
84 remaining_samples = 0;
85 } else {
86 frame_end++;
87 remaining_samples -= (samples_per_frame - sample_end);
88 sample_end = 0;
89 }
90 } else {
91 // Extend range to the left
92 if (sample_start - remaining_samples >= 0) {
93 sample_start -= remaining_samples;
94 remaining_samples = 0;
95 } else {
97 remaining_samples -= (sample_start + 1);
98 sample_start = Frame::GetSamplesPerFrame(frame_start, fps, sample_rate, channels) - 1;
99 }
100 }
101 }
102
103 // Increase total
104 total += samples;
105 }
106
108 void Shrink(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side) {
109 int remaining_samples = samples;
110 while (remaining_samples > 0) {
111 if (right_side) {
112 // Shrink range on the right
113 if (sample_end - remaining_samples >= 0) {
114 sample_end -= remaining_samples;
115 remaining_samples = 0;
116 } else {
117 frame_end--;
118 int samples_per_frame = Frame::GetSamplesPerFrame(frame_end, fps, sample_rate, channels);
119 remaining_samples -= (sample_end + 1);
120 sample_end = samples_per_frame - 1;
121 }
122 } else {
123 // Shrink range on the left
124 int samples_per_frame = Frame::GetSamplesPerFrame(frame_start, fps, sample_rate, channels);
125 if (sample_start + remaining_samples < samples_per_frame) {
126 sample_start += remaining_samples;
127 remaining_samples = 0;
128 } else {
129 frame_start++;
130 remaining_samples -= (samples_per_frame - sample_start);
131 sample_start = 0;
132 }
133 }
134 }
135
136 // Reduce total
137 total -= samples;
138 }
139
140 void Shift(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side) {
141 // Extend each side of the range (to SHIFT the range) by adding (or subtracting) from both sides
142 // For example: [ range ]
143 // For example: [ range ]
144 if (right_side) {
145 // SHIFT both sides to the right
146 Extend(samples, fps, sample_rate, channels, true);
147 Shrink(samples, fps, sample_rate, channels, false);
148 } else {
149 // SHIFT both sides to the left
150 Extend(samples, fps, sample_rate, channels, false);
151 Shrink(samples, fps, sample_rate, channels, true);
152 }
153 }
154
155 int total;
156 };
157
170
171
193 class FrameMapper : public ReaderBase {
194 private:
195 bool field_toggle; // Internal odd / even toggle (used when building the mapping)
196 Fraction original; // The original frame rate
197 Fraction target; // The target frame rate
198 PulldownType pulldown; // The pull-down technique
199 ReaderBase *reader; // The source video reader
200 CacheMemory final_cache; // Cache of actual Frame objects
201 bool is_dirty; // When this is true, the next call to GetFrame will re-init the mapping
202 float parent_position; // Position of parent clip (which is used to generate the audio mapping)
203 float parent_start; // Start of parent clip (which is used to generate the audio mapping)
204 int64_t previous_frame; // Used during resampling, to determine when a large gap is detected
205 SWRCONTEXT *avr; // Audio resampling context object
206
207 // Audio resampler (if resampling audio)
208 openshot::AudioResampler *resampler;
209
210 // Internal methods used by init
211 void AddField(int64_t frame);
212 void AddField(int64_t frame, bool isOdd);
213 void AddField(Field field);
214
215 // Clear both the fields & frames lists
216 void Clear();
217
218 // Get Frame or Generate Blank Frame
219 std::shared_ptr<Frame> GetOrCreateFrame(int64_t number);
220
222 int64_t AdjustFrameNumber(int64_t clip_frame_number);
223
224 // Use the original and target frame rates and a pull-down technique to create
225 // a mapping between the original fields and frames or a video to a new frame rate.
226 // This might repeat or skip fields and frames of the original video, depending on
227 // whether the frame rate is increasing or decreasing.
228 void Init();
229
230 public:
231 // Init some containers
232 std::vector<Field> fields; // List of all fields
233 std::vector<MappedFrame> frames; // List of all frames
234
236 FrameMapper(ReaderBase *reader, Fraction target_fps, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
237
239 virtual ~FrameMapper();
240
242 void ChangeMapping(Fraction target_fps, PulldownType pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
243
245 void Close() override;
246
248 MappedFrame GetMappedFrame(int64_t TargetFrameNumber);
249
251 CacheMemory* GetCache() override { return &final_cache; };
252
259 std::shared_ptr<Frame> GetFrame(int64_t requested_frame) override;
260
262 bool IsOpen() override;
263
265 std::string Name() override { return "FrameMapper"; };
266
267 // Get and Set JSON methods
268 std::string Json() const override;
269 void SetJson(const std::string value) override;
270 Json::Value JsonValue() const override;
271 void SetJsonValue(const Json::Value root) override;
272
274 void Open() override;
275
277 void PrintMapping(std::ostream* out=&std::cout);
278
281
283 void Reader(ReaderBase *new_reader) { reader = new_reader; }
284
286 void ResampleMappedAudio(std::shared_ptr<Frame> frame, int64_t original_frame_number);
287 };
288}
289
290#endif
Header file for AudioResampler class.
Header file for CacheMemory class.
Header file for FFmpegUtilities.
#define SWRCONTEXT
Header file for Fraction class.
Header file for Frame class.
Header file for the Keyframe class.
Header file for OpenMPUtilities (set some common macros)
Header file for ReaderBase class.
This class is used to resample audio data for many sequential frames.
This class is a memory-based cache manager for Frame objects.
Definition CacheMemory.h:29
This class represents a fraction.
Definition Fraction.h:30
This class creates a mapping between 2 different frame rates, applying a specific pull-down technique...
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,...
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.
void Reader(ReaderBase *new_reader)
Set the current reader.
MappedFrame GetMappedFrame(int64_t TargetFrameNumber)
Get a frame based on the target frame rate and the new frame number of a frame.
std::string Name() override
Return the type name of the class.
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
bool IsOpen() override
Determine if reader is open or closed.
std::vector< Field > fields
ReaderBase * Reader()
Get the current reader.
std::vector< MappedFrame > frames
void ResampleMappedAudio(std::shared_ptr< Frame > frame, int64_t original_frame_number)
Resample audio and map channels (if needed)
void Open() override
Open the internal reader.
CacheMemory * GetCache() override
Get the cache object used by this reader.
void Close() override
Close the openshot::FrameMapper and internal reader.
std::string Json() const override
Generate JSON string of this object.
void PrintMapping(std::ostream *out=&std::cout)
Print all of the original frames and which new frames they map to.
void SetJson(const std::string value) override
Load JSON string into this object.
Json::Value JsonValue() const override
Generate Json::Value for this object.
virtual ~FrameMapper()
Destructor.
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:484
This abstract class is the base class, used by all readers in libopenshot.
Definition ReaderBase.h:76
This namespace is the default namespace for all code in the openshot library.
Definition Compressor.h:29
PulldownType
This enumeration determines how frame rates are increased or decreased.
Definition FrameMapper.h:43
@ PULLDOWN_CLASSIC
Classic 2:3:2:3 pull-down.
Definition FrameMapper.h:44
@ PULLDOWN_ADVANCED
Advanced 2:3:3:2 pull-down (minimal dirty frames)
Definition FrameMapper.h:45
@ PULLDOWN_NONE
Do not apply pull-down techniques, just repeat or skip entire frames.
Definition FrameMapper.h:46
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
This struct holds a single field (half a frame).
Definition FrameMapper.h:56
This struct holds two fields which together make up a complete video frame.
This struct holds a the range of samples needed by this frame.
Definition FrameMapper.h:68
void Shrink(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side)
Shrink SampleRange on either side.
void Extend(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side)
Extend SampleRange on either side.
Definition FrameMapper.h:76
void Shift(int64_t samples, openshot::Fraction fps, int sample_rate, int channels, bool right_side)