OpenShot Library | libopenshot  0.1.9
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 "../include/ReaderBase.h"
38 #include "../include/Frame.h"
39 #include "../include/Fraction.h"
40 #include "../include/Exceptions.h"
41 #include "../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  AVAudioResampleContext *avr; // Audio resampling context object
150  int64_t timeline_frame_offset; // Timeline frame offset
151 
152  // Internal methods used by init
153  void AddField(int64_t frame);
154  void AddField(Field field);
155 
156  // Get Frame or Generate Blank Frame
157  std::shared_ptr<Frame> GetOrCreateFrame(int64_t number);
158 
159  // Use the original and target frame rates and a pull-down technique to create
160  // a mapping between the original fields and frames or a video to a new frame rate.
161  // This might repeat or skip fields and frames of the original video, depending on
162  // whether the frame rate is increasing or decreasing.
163  void Init();
164 
165  public:
166  // Init some containers
167  vector<Field> fields; // List of all fields
168  vector<MappedFrame> frames; // List of all frames
169 
170  /// Default constructor for openshot::FrameMapper class
171  FrameMapper(ReaderBase *reader, Fraction target_fps, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
172 
173  /// Destructor
174  ~FrameMapper();
175 
176  /// Change frame rate or audio mapping details
177  void ChangeMapping(Fraction target_fps, PulldownType pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
178 
179  // Set offset relative to parent timeline
180  void SetTimelineFrameOffset(int64_t offset);
181 
182  /// Close the openshot::FrameMapper and internal reader
183  void Close();
184 
185  /// Get a frame based on the target frame rate and the new frame number of a frame
186  MappedFrame GetMappedFrame(int64_t TargetFrameNumber);
187 
188  /// Get the cache object used by this reader
189  CacheMemory* GetCache() { return &final_cache; };
190 
191  /// @brief This method is required for all derived classes of ReaderBase, and return the
192  /// openshot::Frame object, which contains the image and audio information for that
193  /// frame of video.
194  ///
195  /// @returns The requested frame of video
196  /// @param requested_frame The frame number that is requested.
197  std::shared_ptr<Frame> GetFrame(int64_t requested_frame);
198 
199  /// Determine if reader is open or closed
200  bool IsOpen();
201 
202  /// Return the type name of the class
203  string Name() { return "FrameMapper"; };
204 
205  /// Get and Set JSON methods
206  string Json(); ///< Generate JSON string of this object
207  void SetJson(string value); ///< Load JSON string into this object
208  Json::Value JsonValue(); ///< Generate Json::JsonValue for this object
209  void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object
210 
211  /// Open the internal reader
212  void Open();
213 
214  /// Print all of the original frames and which new frames they map to
215  void PrintMapping();
216 
217  /// Get the current reader
218  ReaderBase* Reader();
219 
220  /// Resample audio and map channels (if needed)
221  void ResampleMappedAudio(std::shared_ptr<Frame> frame, int64_t original_frame_number);
222 
223  };
224 }
225 
226 #endif
Classic 2:3:2:3 pull-down.
Definition: FrameMapper.h:62
vector< MappedFrame > frames
Definition: FrameMapper.h:168
Header file for OpenMPUtilities (set some common macros)
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:95
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
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:167
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:189
This namespace is the default namespace for all code in the openshot library.
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:203
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