OpenShot Library | libopenshot  0.5.0
FFmpegReader.h
Go to the documentation of this file.
1 
12 // Copyright (c) 2008-2019 OpenShot Studios, LLC, Fabrice Bellard
13 //
14 // SPDX-License-Identifier: LGPL-3.0-or-later
15 
16 #ifndef OPENSHOT_FFMPEG_READER_H
17 #define OPENSHOT_FFMPEG_READER_H
18 
19 #include "ReaderBase.h"
20 #include "Enums.h"
21 
22 // Include FFmpeg headers and macros
23 #include "FFmpegUtilities.h"
24 
25 #include <cmath>
26 #include <ctime>
27 #include <iostream>
28 #include <stdio.h>
29 #include <memory>
30 #include "AudioLocation.h"
31 #include "CacheMemory.h"
32 #include "Clip.h"
33 #include "OpenMPUtilities.h"
34 #include "Settings.h"
35 #include <cstdlib>
36 
37 
38 namespace openshot {
47  struct PacketStatus {
48  // Track counts of video and audio packets read & decoded
49  int64_t video_read = 0;
50  int64_t video_decoded = 0;
51  int64_t audio_read = 0;
52  int64_t audio_decoded = 0;
53 
54  // Track end-of-file detection on video/audio and overall
55  bool video_eof = true;
56  bool audio_eof = true;
57  bool packets_eof = true;
58  bool end_of_file = true;
59 
60  int64_t packets_read() {
61  // Return total packets read
62  return video_read + audio_read;
63  }
64 
65  int64_t packets_decoded() {
66  // Return total packets decoded
68  }
69 
70  void reset(bool eof) {
71  // Reset counts and EOF detection for packets
73  video_eof = eof; audio_eof = eof; packets_eof = eof; end_of_file = eof;
74  }
75  };
76 
103  class FFmpegReader : public ReaderBase {
104  private:
105  std::string path;
106 
107  AVFormatContext *pFormatCtx;
108  int videoStream, audioStream;
109  AVCodecContext *pCodecCtx, *aCodecCtx;
110 #if USE_HW_ACCEL
111  AVBufferRef *hw_device_ctx = NULL; //PM
112 #endif
113  AVStream *pStream, *aStream;
114  AVPacket *packet;
115  AVFrame *pFrame;
116  bool is_open;
117  bool is_duration_known;
118  bool check_interlace;
119  bool check_fps;
120  DurationStrategy duration_strategy;
121 
122  CacheMemory working_cache;
123  AudioLocation previous_packet_location;
124 
125  // DEBUG VARIABLES (FOR AUDIO ISSUES)
126  int prev_samples;
127  int64_t prev_pts;
128  int64_t pts_total;
129  int64_t pts_counter;
130  std::shared_ptr<openshot::Frame> last_video_frame;
131  std::shared_ptr<openshot::Frame> last_final_video_frame;
132 
133  bool is_seeking;
134  int64_t seeking_pts;
135  int64_t seeking_frame;
136  bool is_video_seek;
137  int seek_count;
138  int64_t seek_audio_frame_found;
139  int64_t seek_video_frame_found;
140  int64_t last_seek_max_frame;
141  int seek_stagnant_count;
142 
143  int64_t last_frame;
144  int64_t largest_frame_processed;
145  int64_t current_video_frame;
146 
147  int64_t audio_pts;
148  int64_t video_pts;
149  bool hold_packet;
150  double pts_offset_seconds;
151  double audio_pts_seconds;
152  double video_pts_seconds;
153  int64_t NO_PTS_OFFSET;
154  PacketStatus packet_status;
155 
156  // Duration bookkeeping
157  double video_stream_duration_seconds = 0.0;
158  double audio_stream_duration_seconds = 0.0;
159  double format_duration_seconds = 0.0;
160  double inferred_duration_seconds = 0.0;
161 
162  // Cached conversion contexts and frames for performance
163  SwsContext *img_convert_ctx = nullptr;
164  SWRCONTEXT *avr_ctx = nullptr;
165  AVFrame *pFrameRGB_cached = nullptr;
166 
167  int hw_de_supported = 0; // Is set by FFmpegReader
168  bool force_sw_decode = false;
169  bool hw_decode_failed = false;
170  int hw_decode_error_count = 0;
171  bool hw_decode_succeeded = false;
172 #if USE_HW_ACCEL
173  AVPixelFormat hw_de_av_pix_fmt = AV_PIX_FMT_NONE;
174  AVHWDeviceType hw_de_av_device_type = AV_HWDEVICE_TYPE_NONE;
175  int IsHardwareDecodeSupported(int codecid);
176 #endif
177 
179  void CheckFPS();
180 
182  bool CheckSeek();
183 
185  void CheckWorkingFrames(int64_t requested_frame);
186 
188  int64_t ConvertFrameToAudioPTS(int64_t frame_number);
189 
191  int64_t ConvertFrameToVideoPTS(int64_t frame_number);
192 
194  int64_t ConvertVideoPTStoFrame(int64_t pts);
195 
197  std::shared_ptr<openshot::Frame> CreateFrame(int64_t requested_frame);
198 
200  AudioLocation GetAudioPTSLocation(int64_t pts);
201 
203  bool GetAVFrame();
204 
206  bool ReopenWithoutHardwareDecode(int64_t requested_frame);
207 
209  int GetNextPacket();
210 
212  int64_t GetPacketPTS();
213 
215  bool HasAlbumArt();
216 
218  double PickDurationSeconds() const;
219 
221  void ApplyDurationStrategy();
222 
224  bool IsPartialFrame(int64_t requested_frame);
225 
227  void ProcessVideoPacket(int64_t requested_frame);
228 
230  void ProcessAudioPacket(int64_t requested_frame);
231 
233  std::shared_ptr<openshot::Frame> ReadStream(int64_t requested_frame);
234 
236  void RemoveAVFrame(AVFrame *);
237 
239  void RemoveAVPacket(AVPacket *);
240 
242  void Seek(int64_t requested_frame);
243 
247  void UpdatePTSOffset();
248 
250  void UpdateAudioInfo();
251 
253  void UpdateVideoInfo();
254 
255  public:
258 
262 
269  FFmpegReader(const std::string& path, bool inspect_reader=true);
275  FFmpegReader(const std::string& path, DurationStrategy duration_strategy, bool inspect_reader=true);
276 
278  virtual ~FFmpegReader();
279 
281  void Close() override;
282 
284  CacheMemory *GetCache() override { return &final_cache; };
285 
290  std::shared_ptr<openshot::Frame> GetFrame(int64_t requested_frame) override;
291 
293  bool IsOpen() override { return is_open; };
294 
296  bool HardwareDecodeSuccessful() const override;
297 
299  std::string Name() override { return "FFmpegReader"; };
300 
301  // Get and Set JSON methods
302  std::string Json() const override;
303  void SetJson(const std::string value) override;
304  Json::Value JsonValue() const override;
305  void SetJsonValue(const Json::Value root) override;
306 
308  void Open() override;
309 
311  bool GetIsDurationKnown();
312  };
313 
314 }
315 
316 #endif
Settings.h
Header file for global Settings class.
openshot::FFmpegReader::FFmpegReader
FFmpegReader(const std::string &path, bool inspect_reader=true)
Constructor for FFmpegReader.
Definition: FFmpegReader.cpp:102
FFmpegUtilities.h
Header file for FFmpegUtilities.
openshot::PacketStatus::reset
void reset(bool eof)
Definition: FFmpegReader.h:70
Clip.h
Header file for Clip class.
openshot::FFmpegReader::GetFrame
std::shared_ptr< openshot::Frame > GetFrame(int64_t requested_frame) override
Definition: FFmpegReader.cpp:1199
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:28
openshot::AudioLocation
This struct holds the associated video frame and starting sample # for an audio packet.
Definition: AudioLocation.h:25
AudioLocation.h
Header file for AudioLocation class.
openshot::FFmpegReader::~FFmpegReader
virtual ~FFmpegReader()
Destructor.
Definition: FFmpegReader.cpp:138
openshot::FFmpegReader::JsonValue
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: FFmpegReader.cpp:2970
openshot::PacketStatus::audio_read
int64_t audio_read
Definition: FFmpegReader.h:51
openshot::FFmpegReader::SetJson
void SetJson(const std::string value) override
Load JSON string into this object.
Definition: FFmpegReader.cpp:2994
openshot::PacketStatus::packets_eof
bool packets_eof
Definition: FFmpegReader.h:57
openshot::PacketStatus::audio_decoded
int64_t audio_decoded
Definition: FFmpegReader.h:52
openshot::PacketStatus::video_read
int64_t video_read
Definition: FFmpegReader.h:49
openshot::PacketStatus::video_eof
bool video_eof
Definition: FFmpegReader.h:55
openshot::CacheMemory
This class is a memory-based cache manager for Frame objects.
Definition: CacheMemory.h:29
openshot::FFmpegReader::enable_seek
bool enable_seek
Definition: FFmpegReader.h:261
openshot::PacketStatus
This struct holds the packet counts and end-of-file detection for an openshot::FFmpegReader.
Definition: FFmpegReader.h:47
openshot::FFmpegReader::Open
void Open() override
Open File - which is called by the constructor automatically.
Definition: FFmpegReader.cpp:262
CacheMemory.h
Header file for CacheMemory class.
openshot::FFmpegReader::IsOpen
bool IsOpen() override
Determine if reader is open or closed.
Definition: FFmpegReader.h:293
SWRCONTEXT
#define SWRCONTEXT
Definition: FFmpegUtilities.h:155
openshot::PacketStatus::audio_eof
bool audio_eof
Definition: FFmpegReader.h:56
openshot::FFmpegReader::final_cache
CacheMemory final_cache
Final cache object used to hold final frames.
Definition: FFmpegReader.h:257
openshot::FFmpegReader
This class uses the FFmpeg libraries, to open video files and audio files, and return openshot::Frame...
Definition: FFmpegReader.h:103
openshot::FFmpegReader::GetCache
CacheMemory * GetCache() override
Get the cache object used by this reader.
Definition: FFmpegReader.h:284
openshot::DurationStrategy
DurationStrategy
This enumeration determines which duration source to favor.
Definition: Enums.h:60
openshot::FFmpegReader::Close
void Close() override
Close File.
Definition: FFmpegReader.cpp:757
openshot::PacketStatus::packets_read
int64_t packets_read()
Definition: FFmpegReader.h:60
openshot::FFmpegReader::Name
std::string Name() override
Return the type name of the class.
Definition: FFmpegReader.h:299
ReaderBase.h
Header file for ReaderBase class.
openshot::PacketStatus::packets_decoded
int64_t packets_decoded()
Definition: FFmpegReader.h:65
OpenMPUtilities.h
Header file for OpenMPUtilities (set some common macros)
Enums.h
Header file for TextReader class.
openshot::PacketStatus::end_of_file
bool end_of_file
Definition: FFmpegReader.h:58
openshot::ReaderBase
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:75
openshot::FFmpegReader::SetJsonValue
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: FFmpegReader.cpp:3009
openshot::FFmpegReader::Json
std::string Json() const override
Generate JSON string of this object.
Definition: FFmpegReader.cpp:2963
openshot::FFmpegReader::HardwareDecodeSuccessful
bool HardwareDecodeSuccessful() const override
Return true if hardware decode was requested and successfully produced at least one frame.
Definition: FFmpegReader.cpp:1760
openshot::FFmpegReader::GetIsDurationKnown
bool GetIsDurationKnown()
Return true if frame can be read with GetFrame()
Definition: FFmpegReader.cpp:1195
openshot::PacketStatus::video_decoded
int64_t video_decoded
Definition: FFmpegReader.h:50