OpenShot Library | libopenshot  0.2.7
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 <cmath>
37 #include <vector>
38 #include <memory>
39 #include "CacheMemory.h"
40 #include "ReaderBase.h"
41 #include "Frame.h"
42 #include "Fraction.h"
43 #include "KeyFrame.h"
44 
45 
46 // Include FFmpeg headers and macros
47 #include "FFmpegUtilities.h"
48 #include "OpenMPUtilities.h"
49 
50 
51 namespace openshot
52 {
53  /**
54  * @brief This enumeration determines how frame rates are increased or decreased.
55  *
56  * Pull-down techniques are only needed to remove artificial fields added when converting
57  * between 24 fps (film) and television fps (29.97 fps NTSC or 25 fps PAL).
58  */
60  {
61  PULLDOWN_CLASSIC, ///< Classic 2:3:2:3 pull-down
62  PULLDOWN_ADVANCED, ///< Advanced 2:3:3:2 pull-down (minimal dirty frames)
63  PULLDOWN_NONE, ///< Do not apply pull-down techniques, just repeat or skip entire frames
64  };
65 
66  /**
67  * @brief This struct holds a single field (half a frame).
68  *
69  * A frame of video is made up of 2 fields (half a frame). This struct points to which original
70  * frame, and whether this is the ODD or EVEN lines (i.e. top or bottom).
71  */
72  struct Field
73  {
74  int64_t Frame;
75  bool isOdd;
76 
77  Field() : Frame(0), isOdd(true) { };
78 
79  Field(int64_t frame, bool isodd)
80  {
81  Frame = frame;
82  isOdd = isodd;
83  }
84  };
85 
86  /**
87  * @brief This struct holds a the range of samples needed by this frame
88  *
89  * When frame rate is changed, the audio needs to be redistributed among the remaining
90  * frames. This struct holds the range samples needed by the this frame.
91  */
92  struct SampleRange
93  {
94  int64_t frame_start;
96 
97  int64_t frame_end;
99 
100  int total;
101  };
102 
103  /**
104  * @brief This struct holds two fields which together make up a complete video frame.
105  *
106  * These fields can point at different original frame numbers, for example the odd lines from
107  * frame 3, and the even lines of frame 4, if required by a pull-down technique.
108  */
109  struct MappedFrame
110  {
114  };
115 
116 
117  /**
118  * @brief This class creates a mapping between 2 different frame rates, applying a specific pull-down technique.
119  *
120  * This class creates a mapping between 2 different video files, and supports many pull-down techniques,
121  * such as 2:3:2:3 or 2:3:3:2, and also supports inverse telecine. Pull-down techniques are only needed to remove
122  * artificial fields added when converting between 24 fps (film) and television fps (29.97 fps NTSC or 25 fps PAL).
123  *
124  * The <b>following graphic</b> displays a how frame rates are mapped, and how time remapping affects the order
125  * of frames returned from the FrameMapper.
126  * \image html /doc/images/FrameMapper.png
127  *
128  * Please see the following <b>Example Code</b>:
129  * \code
130  * // Create a frame mapper for a reader, and convert the frame rate (from 24 fps to 29.97 fps)
131  * FrameMapper mapping(reader, Fraction(30000, 1001), PULLDOWN_CLASSIC, 44100, 2, LAYOUT_STEREO);
132  * std::shared_ptr<Frame> frame2 = mapping.GetFrame(2);
133 
134  * // If you need to change the mapping...
135  * mapping.ChangeMapping(Fraction(24, 1), PULLDOWN_CLASSIC, 48000, 2, LAYOUT_MONO)
136  * \endcode
137  */
138  class FrameMapper : public ReaderBase {
139  private:
140  bool field_toggle; // Internal odd / even toggle (used when building the mapping)
141  Fraction original; // The original frame rate
142  Fraction target; // The target frame rate
143  PulldownType pulldown; // The pull-down technique
144  ReaderBase *reader; // The source video reader
145  CacheMemory final_cache; // Cache of actual Frame objects
146  bool is_dirty; // When this is true, the next call to GetFrame will re-init the mapping
147  float parent_position; // Position of parent clip (which is used to generate the audio mapping)
148  float parent_start; // Start of parent clip (which is used to generate the audio 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  /// Adjust frame number for Clip position and start (which can result in a different number)
159  int64_t AdjustFrameNumber(int64_t clip_frame_number);
160 
161  // Use the original and target frame rates and a pull-down technique to create
162  // a mapping between the original fields and frames or a video to a new frame rate.
163  // This might repeat or skip fields and frames of the original video, depending on
164  // whether the frame rate is increasing or decreasing.
165  void Init();
166 
167  public:
168  // Init some containers
169  std::vector<Field> fields; // List of all fields
170  std::vector<MappedFrame> frames; // List of all frames
171 
172  /// Default constructor for openshot::FrameMapper class
173  FrameMapper(ReaderBase *reader, Fraction target_fps, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
174 
175  /// Destructor
176  virtual ~FrameMapper();
177 
178  /// Change frame rate or audio mapping details
179  void ChangeMapping(Fraction target_fps, PulldownType pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
180 
181  /// Close the openshot::FrameMapper and internal reader
182  void Close() override;
183 
184  /// Get a frame based on the target frame rate and the new frame number of a frame
185  MappedFrame GetMappedFrame(int64_t TargetFrameNumber);
186 
187  /// Get the cache object used by this reader
188  CacheMemory* GetCache() override { return &final_cache; };
189 
190  /// @brief This method is required for all derived classes of ReaderBase, and return the
191  /// openshot::Frame object, which contains the image and audio information for that
192  /// frame of video.
193  ///
194  /// @returns The requested frame of video
195  /// @param requested_frame The frame number that is requested.
196  std::shared_ptr<Frame> GetFrame(int64_t requested_frame) override;
197 
198  /// Determine if reader is open or closed
199  bool IsOpen() override;
200 
201  /// Return the type name of the class
202  std::string Name() override { return "FrameMapper"; };
203 
204  // Get and Set JSON methods
205  std::string Json() const override; ///< Generate JSON string of this object
206  void SetJson(const std::string value) override; ///< Load JSON string into this object
207  Json::Value JsonValue() const override; ///< Generate Json::Value for this object
208  void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object
209 
210  /// Open the internal reader
211  void Open() override;
212 
213  /// Print all of the original frames and which new frames they map to
214  void PrintMapping();
215 
216  /// Get the current reader
217  ReaderBase* Reader();
218 
219  /// Set the current reader
220  void Reader(ReaderBase *new_reader) { reader = new_reader; }
221 
222  /// Resample audio and map channels (if needed)
223  void ResampleMappedAudio(std::shared_ptr<Frame> frame, int64_t original_frame_number);
224  };
225 }
226 
227 #endif
Classic 2:3:2:3 pull-down.
Definition: FrameMapper.h:61
Header file for Fraction class.
#define SWRCONTEXT
Header file for ReaderBase class.
Header file for OpenMPUtilities (set some common macros)
std::vector< MappedFrame > frames
Definition: FrameMapper.h:170
std::vector< Field > fields
Definition: FrameMapper.h:169
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:97
Header file for the Keyframe class.
This struct holds a single field (half a frame).
Definition: FrameMapper.h:72
Header file for CacheMemory class.
This struct holds a the range of samples needed by this frame.
Definition: FrameMapper.h:92
Header file for Frame class.
Field(int64_t frame, bool isodd)
Definition: FrameMapper.h:79
This class represents a fraction.
Definition: Fraction.h:48
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround...
void Reader(ReaderBase *new_reader)
Set the current reader.
Definition: FrameMapper.h:220
CacheMemory * GetCache() override
Get the cache object used by this reader.
Definition: FrameMapper.h:188
This struct holds two fields which together make up a complete video frame.
Definition: FrameMapper.h:109
std::string Name() override
Return the type name of the class.
Definition: FrameMapper.h:202
This class creates a mapping between 2 different frame rates, applying a specific pull-down technique...
Definition: FrameMapper.h:138
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:46
Do not apply pull-down techniques, just repeat or skip entire frames.
Definition: FrameMapper.h:63
PulldownType
This enumeration determines how frame rates are increased or decreased.
Definition: FrameMapper.h:59
Header file for FFmpegUtilities.
This class is a memory-based cache manager for Frame objects.
Definition: CacheMemory.h:50
Advanced 2:3:3:2 pull-down (minimal dirty frames)
Definition: FrameMapper.h:62