OpenShot Library | libopenshot  1.0.0
ReaderBase.cpp
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 #include <iostream>
14 #include <iomanip>
15 #include <algorithm>
16 
17 #include "ReaderBase.h"
18 #include "ClipBase.h"
19 #include "Frame.h"
20 
21 #include "Json.h"
22 
23 
24 using namespace openshot;
25 
28 {
29  // Initialize info struct
30  info.has_video = false;
31  info.has_audio = false;
32  info.has_single_image = false;
33  info.duration = 0.0;
34  info.file_size = 0;
35  info.height = 0;
36  info.width = 0;
37  info.pixel_format = -1;
38  info.fps = Fraction();
39  info.video_bit_rate = 0;
42  info.vcodec = "";
43  info.video_length = 0;
46  info.interlaced_frame = false;
47  info.top_field_first = true;
48  info.acodec = "";
49  info.audio_bit_rate = 0;
50  info.sample_rate = 0;
51  info.channels = 0;
55 
56  // Init parent clip
57  clip = NULL;
58  max_decode_width = 0;
61 }
62 
63 // Display file information
64 void ReaderBase::DisplayInfo(std::ostream* out) {
65  *out << std::fixed << std::setprecision(2) << std::boolalpha;
66  *out << "----------------------------" << std::endl;
67  *out << "----- File Information -----" << std::endl;
68  *out << "----------------------------" << std::endl;
69  *out << "--> Has Video: " << info.has_video << std::endl;
70  *out << "--> Has Audio: " << info.has_audio << std::endl;
71  *out << "--> Has Single Image: " << info.has_single_image << std::endl;
72  *out << "--> Duration: " << info.duration << " Seconds" << std::endl;
73  *out << "--> File Size: " << double(info.file_size) / 1024 / 1024 << " MB" << std::endl;
74  *out << "----------------------------" << std::endl;
75  *out << "----- Video Attributes -----" << std::endl;
76  *out << "----------------------------" << std::endl;
77  *out << "--> Width: " << info.width << std::endl;
78  *out << "--> Height: " << info.height << std::endl;
79  *out << "--> Pixel Format: " << info.pixel_format << std::endl;
80  *out << "--> Frames Per Second: " << info.fps.ToDouble() << " (" << info.fps.num << "/" << info.fps.den << ")" << std::endl;
81  *out << "--> Video Bit Rate: " << info.video_bit_rate/1000 << " kb/s" << std::endl;
82  *out << "--> Pixel Ratio: " << info.pixel_ratio.ToDouble() << " (" << info.pixel_ratio.num << "/" << info.pixel_ratio.den << ")" << std::endl;
83  *out << "--> Display Aspect Ratio: " << info.display_ratio.ToDouble() << " (" << info.display_ratio.num << "/" << info.display_ratio.den << ")" << std::endl;
84  *out << "--> Video Codec: " << info.vcodec << std::endl;
85  *out << "--> Video Length: " << info.video_length << " Frames" << std::endl;
86  *out << "--> Video Stream Index: " << info.video_stream_index << std::endl;
87  *out << "--> Video Timebase: " << info.video_timebase.ToDouble() << " (" << info.video_timebase.num << "/" << info.video_timebase.den << ")" << std::endl;
88  *out << "--> Interlaced: " << info.interlaced_frame << std::endl;
89  *out << "--> Interlaced: Top Field First: " << info.top_field_first << std::endl;
90  *out << "----------------------------" << std::endl;
91  *out << "----- Audio Attributes -----" << std::endl;
92  *out << "----------------------------" << std::endl;
93  *out << "--> Audio Codec: " << info.acodec << std::endl;
94  *out << "--> Audio Bit Rate: " << info.audio_bit_rate/1000 << " kb/s" << std::endl;
95  *out << "--> Sample Rate: " << info.sample_rate << " Hz" << std::endl;
96  *out << "--> # of Channels: " << info.channels << std::endl;
97  *out << "--> Channel Layout: " << info.channel_layout << std::endl;
98  *out << "--> Audio Stream Index: " << info.audio_stream_index << std::endl;
99  *out << "--> Audio Timebase: " << info.audio_timebase.ToDouble() << " (" << info.audio_timebase.num << "/" << info.audio_timebase.den << ")" << std::endl;
100  *out << "----------------------------" << std::endl;
101  *out << "--------- Metadata ---------" << std::endl;
102  *out << "----------------------------" << std::endl;
103 
104  // Iterate through metadata
105  for (auto it : info.metadata)
106  *out << "--> " << it.first << ": " << it.second << std::endl;
107 }
108 
109 // Generate Json::Value for this object
110 Json::Value ReaderBase::JsonValue() const {
111 
112  // Create root json object
113  Json::Value root;
114  root["has_video"] = info.has_video;
115  root["has_audio"] = info.has_audio;
116  root["has_single_image"] = info.has_single_image;
117  root["duration"] = info.duration;
118  root["file_size"] = static_cast<Json::Value::Int64>(info.file_size); // direct 64-bit int
119  root["height"] = info.height;
120  root["width"] = info.width;
121  root["pixel_format"] = info.pixel_format;
122  root["fps"] = Json::Value(Json::objectValue);
123  root["fps"]["num"] = info.fps.num;
124  root["fps"]["den"] = info.fps.den;
125  root["video_bit_rate"] = info.video_bit_rate;
126  root["pixel_ratio"] = Json::Value(Json::objectValue);
127  root["pixel_ratio"]["num"] = info.pixel_ratio.num;
128  root["pixel_ratio"]["den"] = info.pixel_ratio.den;
129  root["display_ratio"] = Json::Value(Json::objectValue);
130  root["display_ratio"]["num"] = info.display_ratio.num;
131  root["display_ratio"]["den"] = info.display_ratio.den;
132  root["vcodec"] = info.vcodec;
133  root["video_length"] = static_cast<Json::Value::Int64>(info.video_length);
134  root["video_stream_index"] = info.video_stream_index;
135  root["video_timebase"] = Json::Value(Json::objectValue);
136  root["video_timebase"]["num"] = info.video_timebase.num;
137  root["video_timebase"]["den"] = info.video_timebase.den;
138  root["interlaced_frame"] = info.interlaced_frame;
139  root["top_field_first"] = info.top_field_first;
140  root["acodec"] = info.acodec;
141  root["audio_bit_rate"] = info.audio_bit_rate;
142  root["sample_rate"] = info.sample_rate;
143  root["channels"] = info.channels;
144  root["channel_layout"] = info.channel_layout;
145  root["audio_stream_index"] = info.audio_stream_index;
146  root["audio_timebase"] = Json::Value(Json::objectValue);
147  root["audio_timebase"]["num"] = info.audio_timebase.num;
148  root["audio_timebase"]["den"] = info.audio_timebase.den;
149 
150  // Append metadata map
151  root["metadata"] = Json::Value(Json::objectValue);
152 
153  for (const auto it : info.metadata)
154  root["metadata"][it.first] = it.second;
155 
156  // return JsonValue
157  return root;
158 }
159 
160 // Load Json::Value into this object
161 void ReaderBase::SetJsonValue(const Json::Value root) {
162 
163  // Set data from Json (if key is found)
164  if (!root["has_video"].isNull())
165  info.has_video = root["has_video"].asBool();
166  if (!root["has_audio"].isNull())
167  info.has_audio = root["has_audio"].asBool();
168  if (!root["has_single_image"].isNull())
169  info.has_single_image = root["has_single_image"].asBool();
170  if (!root["duration"].isNull())
171  info.duration = root["duration"].asDouble();
172  if (!root["file_size"].isNull())
173  info.file_size = std::stoll(root["file_size"].asString());
174  if (!root["height"].isNull())
175  info.height = root["height"].asInt();
176  if (!root["width"].isNull())
177  info.width = root["width"].asInt();
178  if (!root["pixel_format"].isNull())
179  info.pixel_format = root["pixel_format"].asInt();
180  if (!root["fps"].isNull() && root["fps"].isObject()) {
181  if (!root["fps"]["num"].isNull())
182  info.fps.num = root["fps"]["num"].asInt();
183  if (!root["fps"]["den"].isNull())
184  info.fps.den = root["fps"]["den"].asInt();
185  }
186  if (!root["video_bit_rate"].isNull())
187  info.video_bit_rate = root["video_bit_rate"].asInt();
188  if (!root["pixel_ratio"].isNull() && root["pixel_ratio"].isObject()) {
189  if (!root["pixel_ratio"]["num"].isNull())
190  info.pixel_ratio.num = root["pixel_ratio"]["num"].asInt();
191  if (!root["pixel_ratio"]["den"].isNull())
192  info.pixel_ratio.den = root["pixel_ratio"]["den"].asInt();
193  }
194  if (!root["display_ratio"].isNull() && root["display_ratio"].isObject()) {
195  if (!root["display_ratio"]["num"].isNull())
196  info.display_ratio.num = root["display_ratio"]["num"].asInt();
197  if (!root["display_ratio"]["den"].isNull())
198  info.display_ratio.den = root["display_ratio"]["den"].asInt();
199  }
200  if (!root["vcodec"].isNull())
201  info.vcodec = root["vcodec"].asString();
202  if (!root["video_length"].isNull())
203  info.video_length = std::stoll(root["video_length"].asString());
204  if (!root["video_stream_index"].isNull())
205  info.video_stream_index = root["video_stream_index"].asInt();
206  if (!root["video_timebase"].isNull() && root["video_timebase"].isObject()) {
207  if (!root["video_timebase"]["num"].isNull())
208  info.video_timebase.num = root["video_timebase"]["num"].asInt();
209  if (!root["video_timebase"]["den"].isNull())
210  info.video_timebase.den = root["video_timebase"]["den"].asInt();
211  }
212  if (!root["interlaced_frame"].isNull())
213  info.interlaced_frame = root["interlaced_frame"].asBool();
214  if (!root["top_field_first"].isNull())
215  info.top_field_first = root["top_field_first"].asBool();
216  if (!root["acodec"].isNull())
217  info.acodec = root["acodec"].asString();
218 
219  if (!root["audio_bit_rate"].isNull())
220  info.audio_bit_rate = root["audio_bit_rate"].asInt();
221  if (!root["sample_rate"].isNull())
222  info.sample_rate = root["sample_rate"].asInt();
223  if (!root["channels"].isNull())
224  info.channels = root["channels"].asInt();
225  if (!root["channel_layout"].isNull())
226  info.channel_layout = (ChannelLayout) root["channel_layout"].asInt();
227  if (!root["audio_stream_index"].isNull())
228  info.audio_stream_index = root["audio_stream_index"].asInt();
229  if (!root["audio_timebase"].isNull() && root["audio_timebase"].isObject()) {
230  if (!root["audio_timebase"]["num"].isNull())
231  info.audio_timebase.num = root["audio_timebase"]["num"].asInt();
232  if (!root["audio_timebase"]["den"].isNull())
233  info.audio_timebase.den = root["audio_timebase"]["den"].asInt();
234  }
235  if (!root["metadata"].isNull() && root["metadata"].isObject()) {
236  for( Json::Value::const_iterator itr = root["metadata"].begin() ; itr != root["metadata"].end() ; itr++ ) {
237  std::string key = itr.key().asString();
238  info.metadata[key] = root["metadata"][key].asString();
239  }
240  }
241 }
242 
245  return clip;
246 }
247 
250  clip = new_clip;
251 }
252 
253 void ReaderBase::SetMaxDecodeSize(int width, int height) {
254  max_decode_width = std::max(0, width);
255  max_decode_height = std::max(0, height);
256 }
257 
259  return max_decode_width;
260 }
261 
263  return max_decode_height;
264 }
265 
267  return max_decode_width > 0 && max_decode_height > 0;
268 }
269 
272 }
273 
276 }
Header file for ClipBase class.
Header file for Frame class.
Header file for JSON class.
Header file for ReaderBase class.
This abstract class is the base class, used by all clips in libopenshot.
Definition: ClipBase.h:32
This class represents a fraction.
Definition: Fraction.h:30
int num
Numerator for the fraction.
Definition: Fraction.h:32
double ToDouble() const
Return this fraction as a double (i.e. 1/2 = 0.5)
Definition: Fraction.cpp:40
int den
Denominator for the fraction.
Definition: Fraction.h:33
int max_decode_height
Optional maximum decoded frame height (0 disables the limit)
Definition: ReaderBase.h:82
bool apply_orientation_metadata
Apply source orientation metadata while reading frames.
Definition: ReaderBase.h:83
openshot::ReaderInfo info
Information about the current media file.
Definition: ReaderBase.h:91
void SetMaxDecodeSize(int width, int height)
Set an optional maximum decoded frame size. Use 0,0 to disable the limit.
Definition: ReaderBase.cpp:253
int max_decode_width
Optional maximum decoded frame width (0 disables the limit)
Definition: ReaderBase.h:81
int MaxDecodeWidth() const
Return the current maximum decoded frame width (0 when unlimited).
Definition: ReaderBase.cpp:258
virtual void SetJsonValue(const Json::Value root)=0
Load Json::Value into this object.
Definition: ReaderBase.cpp:161
virtual Json::Value JsonValue() const =0
Generate Json::Value for this object.
Definition: ReaderBase.cpp:110
int MaxDecodeHeight() const
Return the current maximum decoded frame height (0 when unlimited).
Definition: ReaderBase.cpp:262
bool ApplyOrientationMetadata() const
Return whether readers apply source orientation metadata to returned frames.
Definition: ReaderBase.cpp:274
void DisplayInfo(std::ostream *out=&std::cout)
Display file information in the standard output stream (stdout)
Definition: ReaderBase.cpp:64
bool HasMaxDecodeSize() const
Return true when a maximum decoded frame size is active.
Definition: ReaderBase.cpp:266
openshot::ClipBase * clip
Pointer to the parent clip instance (if any)
Definition: ReaderBase.h:80
openshot::ClipBase * ParentClip()
Parent clip object of this reader (which can be unparented and NULL)
Definition: ReaderBase.cpp:244
ReaderBase()
Constructor for the base reader, where many things are initialized.
Definition: ReaderBase.cpp:27
This namespace is the default namespace for all code in the openshot library.
Definition: AnimatedCurve.h:24
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
int audio_bit_rate
The bit rate of the audio stream (in bytes)
Definition: ReaderBase.h:59
int video_bit_rate
The bit rate of the video stream (in bytes)
Definition: ReaderBase.h:49
bool has_single_image
Determines if this file only contains a single image.
Definition: ReaderBase.h:42
float duration
Length of time (in seconds)
Definition: ReaderBase.h:43
openshot::Fraction audio_timebase
The audio timebase determines how long each audio packet should be played.
Definition: ReaderBase.h:64
int width
The width of the video (in pixesl)
Definition: ReaderBase.h:46
int channels
The number of audio channels used in the audio stream.
Definition: ReaderBase.h:61
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
Definition: ReaderBase.h:48
openshot::Fraction display_ratio
The ratio of width to height of the video stream (i.e. 640x480 has a ratio of 4/3)
Definition: ReaderBase.h:51
int height
The height of the video (in pixels)
Definition: ReaderBase.h:45
int pixel_format
The pixel format (i.e. YUV420P, RGB24, etc...)
Definition: ReaderBase.h:47
int64_t video_length
The number of frames in the video stream.
Definition: ReaderBase.h:53
std::string acodec
The name of the audio codec used to encode / decode the video stream.
Definition: ReaderBase.h:58
std::map< std::string, std::string > metadata
An optional map/dictionary of metadata for this reader.
Definition: ReaderBase.h:65
std::string vcodec
The name of the video codec used to encode / decode the video stream.
Definition: ReaderBase.h:52
openshot::Fraction pixel_ratio
The pixel ratio of the video stream as a fraction (i.e. some pixels are not square)
Definition: ReaderBase.h:50
openshot::ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
Definition: ReaderBase.h:62
bool has_video
Determines if this file has a video stream.
Definition: ReaderBase.h:40
bool has_audio
Determines if this file has an audio stream.
Definition: ReaderBase.h:41
openshot::Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
Definition: ReaderBase.h:55
int video_stream_index
The index of the video stream.
Definition: ReaderBase.h:54
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
Definition: ReaderBase.h:60
int audio_stream_index
The index of the audio stream.
Definition: ReaderBase.h:63
int64_t file_size
Size of file (in bytes)
Definition: ReaderBase.h:44