OpenShot Library | libopenshot  0.2.5
FrameMapper.h
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Header file for the FrameMapper class
4  * @author Jonathan Thomas <jonathan@openshot.org>
5  *
6  * @ref License
7  */
8 
9 /* LICENSE
10  *
11  * Copyright (c) 2008-2019 OpenShot Studios, LLC
12  * <http://www.openshotstudios.com/>. This file is part of
13  * OpenShot Library (libopenshot), an open-source project dedicated to
14  * delivering high quality video editing and animation solutions to the
15  * world. For more information visit <http://www.openshot.org/>.
16  *
17  * OpenShot Library (libopenshot) is free software: you can redistribute it
18  * and/or modify it under the terms of the GNU Lesser General Public License
19  * as published by the Free Software Foundation, either version 3 of the
20  * License, or (at your option) any later version.
21  *
22  * OpenShot Library (libopenshot) is distributed in the hope that it will be
23  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU Lesser General Public License for more details.
26  *
27  * You should have received a copy of the GNU Lesser General Public License
28  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #ifndef OPENSHOT_FRAMEMAPPER_H
32 #define OPENSHOT_FRAMEMAPPER_H
33 
34 #include <assert.h>
35 #include <iostream>
36 #include <math.h>
37 #include <vector>
38 #include <memory>
39 #include "CacheMemory.h"
40 #include "ReaderBase.h"
41 #include "Frame.h"
42 #include "Fraction.h"
43 #include "Exceptions.h"
44 #include "KeyFrame.h"
45 
46 
47 // Include FFmpeg headers and macros
48 #include "FFmpegUtilities.h"
49 #include "OpenMPUtilities.h"
50 
51 
52 namespace openshot
53 {
54  /**
55  * @brief This enumeration determines how frame rates are increased or decreased.
56  *
57  * Pull-down techniques are only needed to remove artificial fields added when converting
58  * between 24 fps (film) and television fps (29.97 fps NTSC or 25 fps PAL).
59  */
61  {
62  PULLDOWN_CLASSIC, ///< Classic 2:3:2:3 pull-down
63  PULLDOWN_ADVANCED, ///< Advanced 2:3:3:2 pull-down (minimal dirty frames)
64  PULLDOWN_NONE, ///< Do not apply pull-down techniques, just repeat or skip entire frames
65  };
66 
67  /**
68  * @brief This struct holds a single field (half a frame).
69  *
70  * A frame of video is made up of 2 fields (half a frame). This struct points to which original
71  * frame, and whether this is the ODD or EVEN lines (i.e. top or bottom).
72  */
73  struct Field
74  {
75  int64_t Frame;
76  bool isOdd;
77 
78  Field() : Frame(0), isOdd(true) { };
79 
80  Field(int64_t frame, bool isodd)
81  {
82  Frame = frame;
83  isOdd = isodd;
84  }
85  };
86 
87  /**
88  * @brief This struct holds a the range of samples needed by this frame
89  *
90  * When frame rate is changed, the audio needs to be redistributed among the remaining
91  * frames. This struct holds the range samples needed by the this frame.
92  */
93  struct SampleRange
94  {
95  int64_t frame_start;
97 
98  int64_t frame_end;
100 
101  int total;
102  };
103 
104  /**
105  * @brief This struct holds two fields which together make up a complete video frame.
106  *
107  * These fields can point at different original frame numbers, for example the odd lines from
108  * frame 3, and the even lines of frame 4, if required by a pull-down technique.
109  */
110  struct MappedFrame
111  {
115  };
116 
117 
118  /**
119  * @brief This class creates a mapping between 2 different frame rates, applying a specific pull-down technique.
120  *
121  * This class creates a mapping between 2 different video files, and supports many pull-down techniques,
122  * such as 2:3:2:3 or 2:3:3:2, and also supports inverse telecine. Pull-down techniques are only needed to remove
123  * artificial fields added when converting between 24 fps (film) and television fps (29.97 fps NTSC or 25 fps PAL).
124  *
125  * The <b>following graphic</b> displays a how frame rates are mapped, and how time remapping affects the order
126  * of frames returned from the FrameMapper.
127  * \image html /doc/images/FrameMapper.png
128  *
129  * Please see the following <b>Example Code</b>:
130  * \code
131  * // Create a frame mapper for a reader, and convert the frame rate (from 24 fps to 29.97 fps)
132  * FrameMapper mapping(reader, Fraction(30000, 1001), PULLDOWN_CLASSIC, 44100, 2, LAYOUT_STEREO);
133  * std::shared_ptr<Frame> frame2 = mapping.GetFrame(2);
134 
135  * // If you need to change the mapping...
136  * mapping.ChangeMapping(Fraction(24, 1), PULLDOWN_CLASSIC, 48000, 2, LAYOUT_MONO)
137  * \endcode
138  */
139  class FrameMapper : public ReaderBase {
140  private:
141  bool is_open;
142  bool field_toggle; // Internal odd / even toggle (used when building the mapping)
143  Fraction original; // The original frame rate
144  Fraction target; // The target frame rate
145  PulldownType pulldown; // The pull-down technique
146  ReaderBase *reader; // The source video reader
147  CacheMemory final_cache; // Cache of actual Frame objects
148  bool is_dirty; // When this is true, the next call to GetFrame will re-init the mapping
149  SWRCONTEXT *avr; // Audio resampling context object
150 
151  // Internal methods used by init
152  void AddField(int64_t frame);
153  void AddField(Field field);
154 
155  // Get Frame or Generate Blank Frame
156  std::shared_ptr<Frame> GetOrCreateFrame(int64_t number);
157 
158  // Use the original and target frame rates and a pull-down technique to create
159  // a mapping between the original fields and frames or a video to a new frame rate.
160  // This might repeat or skip fields and frames of the original video, depending on
161  // whether the frame rate is increasing or decreasing.
162  void Init();
163 
164  public:
165  // Init some containers
166  std::vector<Field> fields; // List of all fields
167  std::vector<MappedFrame> frames; // List of all frames
168 
169  /// Default constructor for openshot::FrameMapper class
170  FrameMapper(ReaderBase *reader, Fraction target_fps, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
171 
172  /// Destructor
173  virtual ~FrameMapper();
174 
175  /// Change frame rate or audio mapping details
176  void ChangeMapping(Fraction target_fps, PulldownType pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
177 
178  /// Close the openshot::FrameMapper and internal reader
179  void Close();
180 
181  /// Get a frame based on the target frame rate and the new frame number of a frame
182  MappedFrame GetMappedFrame(int64_t TargetFrameNumber);
183 
184  /// Get the cache object used by this reader
185  CacheMemory* GetCache() { return &final_cache; };
186 
187  /// @brief This method is required for all derived classes of ReaderBase, and return the
188  /// openshot::Frame object, which contains the image and audio information for that
189  /// frame of video.
190  ///
191  /// @returns The requested frame of video
192  /// @param requested_frame The frame number that is requested.
193  std::shared_ptr<Frame> GetFrame(int64_t requested_frame);
194 
195  /// Determine if reader is open or closed
196  bool IsOpen();
197 
198  /// Return the type name of the class
199  std::string Name() { return "FrameMapper"; };
200 
201  /// Get and Set JSON methods
202  std::string Json() const override; ///< Generate JSON string of this object
203  void SetJson(const std::string value); ///< Load JSON string into this object
204  Json::Value JsonValue() const override; ///< Generate Json::Value for this object
205  void SetJsonValue(const Json::Value root); ///< Load Json::Value into this object
206 
207  /// Open the internal reader
208  void Open();
209 
210  /// Print all of the original frames and which new frames they map to
211  void PrintMapping();
212 
213  /// Get the current reader
214  ReaderBase* Reader();
215 
216  /// Set the current reader
217  void Reader(ReaderBase *new_reader) { reader = new_reader; }
218 
219  /// Resample audio and map channels (if needed)
220  void ResampleMappedAudio(std::shared_ptr<Frame> frame, int64_t original_frame_number);
221 
222  };
223 }
224 
225 #endif
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:727
openshot::FrameMapper::fields
std::vector< Field > fields
Definition: FrameMapper.h:166
FFmpegUtilities.h
Header file for FFmpegUtilities.
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:761
openshot::FrameMapper::IsOpen
bool IsOpen()
Determine if reader is open or closed.
Definition: FrameMapper.cpp:624
openshot::FrameMapper::Name
std::string Name()
Return the type name of the class.
Definition: FrameMapper.h:199
Fraction.h
Header file for Fraction class.
openshot::Field::isOdd
bool isOdd
Definition: FrameMapper.h:76
openshot::Field::Field
Field(int64_t frame, bool isodd)
Definition: FrameMapper.h:80
openshot::Field::Field
Field()
Definition: FrameMapper.h:78
openshot::FrameMapper::GetFrame
std::shared_ptr< Frame > GetFrame(int64_t requested_frame)
This method is required for all derived classes of ReaderBase, and return the openshot::Frame object,...
Definition: FrameMapper.cpp:389
openshot::SampleRange::frame_end
int64_t frame_end
Definition: FrameMapper.h:98
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: AudioBufferSource.h:39
openshot::Fraction
This class represents a fraction.
Definition: Fraction.h:45
openshot::FrameMapper::SetJson
void SetJson(const std::string value)
Load JSON string into this object.
Definition: FrameMapper.cpp:696
openshot::FrameMapper::Reader
void Reader(ReaderBase *new_reader)
Set the current reader.
Definition: FrameMapper.h:217
openshot::Field
This struct holds a single field (half a frame).
Definition: FrameMapper.h:74
openshot::FrameMapper::PrintMapping
void PrintMapping()
Print all of the original frames and which new frames they map to.
Definition: FrameMapper.cpp:590
openshot::Frame
This class represents a single frame of video (i.e. image & audio data)
Definition: Frame.h:107
openshot::FrameMapper::Json
std::string Json() const override
Get and Set JSON methods.
Definition: FrameMapper.cpp:678
KeyFrame.h
Header file for the Keyframe class.
openshot::SampleRange::sample_start
int sample_start
Definition: FrameMapper.h:96
openshot::MappedFrame::Even
Field Even
Definition: FrameMapper.h:113
openshot::SampleRange::frame_start
int64_t frame_start
Definition: FrameMapper.h:95
openshot::FrameMapper::~FrameMapper
virtual ~FrameMapper()
Destructor.
Definition: FrameMapper.cpp:63
openshot::FrameMapper::frames
std::vector< MappedFrame > frames
Definition: FrameMapper.h:167
openshot::CacheMemory
This class is a memory-based cache manager for Frame objects.
Definition: CacheMemory.h:51
openshot::MappedFrame::Odd
Field Odd
Definition: FrameMapper.h:112
CacheMemory.h
Header file for CacheMemory class.
openshot::MappedFrame::Samples
SampleRange Samples
Definition: FrameMapper.h:114
openshot::FrameMapper::FrameMapper
FrameMapper(ReaderBase *reader, Fraction target_fps, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout)
Default constructor for openshot::FrameMapper class.
Definition: FrameMapper.cpp:36
openshot::MappedFrame
This struct holds two fields which together make up a complete video frame.
Definition: FrameMapper.h:111
SWRCONTEXT
#define SWRCONTEXT
Definition: FFmpegUtilities.h:148
openshot::SampleRange
This struct holds a the range of samples needed by this frame.
Definition: FrameMapper.h:94
Frame.h
Header file for Frame class.
openshot::SampleRange::total
int total
Definition: FrameMapper.h:101
openshot::FrameMapper
This class creates a mapping between 2 different frame rates, applying a specific pull-down technique...
Definition: FrameMapper.h:139
openshot::FrameMapper::JsonValue
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: FrameMapper.cpp:685
openshot::PULLDOWN_ADVANCED
@ PULLDOWN_ADVANCED
Advanced 2:3:3:2 pull-down (minimal dirty frames)
Definition: FrameMapper.h:63
ReaderBase.h
Header file for ReaderBase class.
openshot::FrameMapper::SetJsonValue
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: FrameMapper.cpp:713
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:314
openshot::SampleRange::sample_end
int sample_end
Definition: FrameMapper.h:99
OpenMPUtilities.h
Header file for OpenMPUtilities (set some common macros)
openshot::ReaderBase
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:98
openshot::PulldownType
PulldownType
This enumeration determines how frame rates are increased or decreased.
Definition: FrameMapper.h:61
openshot::FrameMapper::Open
void Open()
Open the internal reader.
Definition: FrameMapper.cpp:633
openshot::ChannelLayout
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
Definition: ChannelLayouts.h:47
openshot::FrameMapper::GetCache
CacheMemory * GetCache()
Get the cache object used by this reader.
Definition: FrameMapper.h:185
openshot::FrameMapper::Close
void Close()
Close the openshot::FrameMapper and internal reader.
Definition: FrameMapper.cpp:645
openshot::FrameMapper::Reader
ReaderBase * Reader()
Get the current reader.
Definition: FrameMapper.cpp:72
openshot::Field::Frame
int64_t Frame
Definition: FrameMapper.h:75
openshot::PULLDOWN_NONE
@ PULLDOWN_NONE
Do not apply pull-down techniques, just repeat or skip entire frames.
Definition: FrameMapper.h:64
Exceptions.h
Header file for all Exception classes.
openshot::PULLDOWN_CLASSIC
@ PULLDOWN_CLASSIC
Classic 2:3:2:3 pull-down.
Definition: FrameMapper.h:62