OpenShot Library | libopenshot  0.2.3
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  * @section LICENSE
7  *
8  * Copyright (c) 2008-2014 OpenShot Studios, LLC
9  * <http://www.openshotstudios.com/>. This file is part of
10  * OpenShot Library (libopenshot), an open-source project dedicated to
11  * delivering high quality video editing and animation solutions to the
12  * world. For more information visit <http://www.openshot.org/>.
13  *
14  * OpenShot Library (libopenshot) is free software: you can redistribute it
15  * and/or modify it under the terms of the GNU Lesser General Public License
16  * as published by the Free Software Foundation, either version 3 of the
17  * License, or (at your option) any later version.
18  *
19  * OpenShot Library (libopenshot) is distributed in the hope that it will be
20  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
26  */
27 
28 #ifndef OPENSHOT_FRAMEMAPPER_H
29 #define OPENSHOT_FRAMEMAPPER_H
30 
31 #include <assert.h>
32 #include <iostream>
33 #include <math.h>
34 #include <vector>
35 #include <memory>
36 #include "CacheMemory.h"
37 #include "ReaderBase.h"
38 #include "Frame.h"
39 #include "Fraction.h"
40 #include "Exceptions.h"
41 #include "KeyFrame.h"
42 
43 
44 // Include FFmpeg headers and macros
45 #include "FFmpegUtilities.h"
46 #include "OpenMPUtilities.h"
47 
48 
49 
50 using namespace std;
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  vector<Field> fields; // List of all fields
167  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  ~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  string Name() { return "FrameMapper"; };
200 
201  /// Get and Set JSON methods
202  string Json(); ///< Generate JSON string of this object
203  void SetJson(string value); ///< Load JSON string into this object
204  Json::Value JsonValue(); ///< Generate Json::JsonValue for this object
205  void SetJsonValue(Json::Value root); ///< Load Json::JsonValue 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  /// Resample audio and map channels (if needed)
217  void ResampleMappedAudio(std::shared_ptr<Frame> frame, int64_t original_frame_number);
218 
219  };
220 }
221 
222 #endif
Classic 2:3:2:3 pull-down.
Definition: FrameMapper.h:62
Header file for Fraction class.
#define SWRCONTEXT
vector< MappedFrame > frames
Definition: FrameMapper.h:167
Header file for ReaderBase class.
This class represents a single frame of video (i.e. image & audio data)
Definition: Frame.h:115
Header file for OpenMPUtilities (set some common macros)
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:73
Header file for CacheMemory class.
This struct holds a the range of samples needed by this frame.
Definition: FrameMapper.h:93
Header file for all Exception classes.
Header file for Frame class.
Field(int64_t frame, bool isodd)
Definition: FrameMapper.h:80
This class represents a fraction.
Definition: Fraction.h:42
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround...
This struct holds two fields which together make up a complete video frame.
Definition: FrameMapper.h:110
vector< Field > fields
Definition: FrameMapper.h:166
This class creates a mapping between 2 different frame rates, applying a specific pull-down technique...
Definition: FrameMapper.h:139
CacheMemory * GetCache()
Get the cache object used by this reader.
Definition: FrameMapper.h:185
Do not apply pull-down techniques, just repeat or skip entire frames.
Definition: FrameMapper.h:64
string Name()
Return the type name of the class.
Definition: FrameMapper.h:199
PulldownType
This enumeration determines how frame rates are increased or decreased.
Definition: FrameMapper.h:60
Header file for FFmpegUtilities.
This class is a memory-based cache manager for Frame objects.
Definition: CacheMemory.h:48
Advanced 2:3:3:2 pull-down (minimal dirty frames)
Definition: FrameMapper.h:63