Panda3D
ffmpegVideoCursor.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file ffmpegVideoCursor.h
10  * @author jyelon
11  * @date 2007-08-01
12  */
13 
14 #ifndef FFMPEGVIDEOCURSOR_H
15 #define FFMPEGVIDEOCURSOR_H
16 
17 #include "pandabase.h"
18 #include "movieVideoCursor.h"
19 #include "texture.h"
20 #include "pointerTo.h"
21 #include "ffmpegVirtualFile.h"
22 #include "genericThread.h"
23 #include "threadPriority.h"
24 #include "pmutex.h"
25 #include "reMutex.h"
26 #include "conditionVar.h"
27 #include "pdeque.h"
28 
29 class FfmpegVideo;
30 struct AVFormatContext;
31 struct AVCodecContext;
32 struct AVStream;
33 struct AVPacket;
34 struct AVFrame;
35 struct SwsContext;
36 
37 /**
38  *
39  */
40 class EXPCL_FFMPEG FfmpegVideoCursor : public MovieVideoCursor {
41 private:
43  void init_from(FfmpegVideo *src);
44 
45 PUBLISHED:
47  virtual ~FfmpegVideoCursor();
48 
49  void set_max_readahead_frames(int max_readahead_frames);
50  int get_max_readahead_frames() const;
51 
52  void set_thread_priority(ThreadPriority thread_priority);
53  ThreadPriority get_thread_priority() const;
54 
55  void start_thread();
56  BLOCKING void stop_thread();
57  bool is_thread_started() const;
58 
59 public:
60  virtual bool set_time(double timestamp, int loop_count);
61  virtual PT(Buffer) fetch_buffer();
62 
63 public:
64  // Nested class must be public for PT(FfmpegBuffer) to work correctly.
65  class EXPCL_FFMPEG FfmpegBuffer : public Buffer {
66  public:
67  ALLOC_DELETED_CHAIN(FfmpegBuffer);
68  INLINE FfmpegBuffer(size_t block_size, double video_timebase);
69  virtual int compare_timestamp(const Buffer *other) const;
70  virtual double get_timestamp() const;
71 
72  int _begin_frame;
73  int _end_frame;
74  double _video_timebase;
75 
76  public:
77  static TypeHandle get_class_type() {
78  return _type_handle;
79  }
80  static void init_type() {
81  Buffer::init_type();
82  register_type(_type_handle, "FfmpegVideoCursor::FfmpegBuffer",
83  Buffer::get_class_type());
84  }
85  virtual TypeHandle get_type() const {
86  return get_class_type();
87  }
88  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
89 
90  private:
91  static TypeHandle _type_handle;
92  };
93 
94 protected:
95  virtual PT(Buffer) make_new_buffer();
96 
97 private:
98  bool open_stream();
99  void close_stream();
100  void cleanup();
101 
102  Filename _filename;
103  std::string _sync_name;
104  int _max_readahead_frames;
105  ThreadPriority _thread_priority;
106  PT(GenericThread) _thread;
107 
108  int _pixel_format;
109 
110  // This global Mutex protects calls to avcodec_opencloseetc.
111  static ReMutex _av_lock;
112 
113  // Protects _readahead_frames and all the immediately following members.
114  Mutex _lock;
115 
116  // Condition: the thread has something to do.
117  ConditionVar _action_cvar;
118 
119  typedef pdeque<PT(FfmpegBuffer) > Buffers;
120  Buffers _readahead_frames;
121  enum ThreadStatus {
122  TS_stopped,
123  TS_wait,
124  TS_readahead,
125  TS_seek,
126  TS_seeking,
127  TS_shutdown,
128  };
129  ThreadStatus _thread_status;
130  int _seek_frame;
131 
132  int _current_frame;
133  PT(FfmpegBuffer) _current_frame_buffer;
134 
135 private:
136  // The following functions will be called in the sub-thread.
137  static void st_thread_main(void *self);
138  void thread_main();
139  bool do_poll();
140 
141  PT(FfmpegBuffer) do_alloc_frame();
142  void do_clear_all_frames();
143 
144  bool fetch_packet(int default_frame);
145  bool do_fetch_packet(int default_frame);
146  void fetch_frame(int frame);
147  void decode_frame(int &finished);
148  void do_decode_frame(int &finished);
149  void seek(int frame, bool backward);
150  void do_seek(int frame, bool backward);
151  int binary_seek(int min_frame, int max_frame, int target_frame, int num_iterations);
152  void advance_to_frame(int frame);
153  void reset_stream();
154  void export_frame(FfmpegBuffer *buffer);
155 
156  // The following data members will be accessed by the sub-thread.
157  AVPacket *_packet;
158  int _packet_frame;
159  AVFormatContext *_format_ctx;
160  AVCodecContext *_video_ctx;
161  SwsContext *_convert_ctx;
162 
163  FfmpegVirtualFile _ffvfile;
164  int _video_index;
165  double _video_timebase;
166  AVFrame *_frame;
167  AVFrame *_frame_out;
168  int _initial_dts;
169  double _min_fseek;
170  int _begin_frame;
171  int _end_frame;
172  bool _frame_ready;
173  bool _eof_known;
174  int _eof_frame;
175 
176  // PStat collectors.
177  static PStatCollector _fetch_buffer_pcollector;
178  static PStatCollector _seek_pcollector;
179  static PStatCollector _export_frame_pcollector;
180 
181 public:
182  static void register_with_read_factory();
183  virtual void write_datagram(BamWriter *manager, Datagram &dg);
184 
185  virtual void finalize(BamReader *manager);
186 
187 protected:
188  static TypedWritable *make_from_bam(const FactoryParams &params);
189  void fillin(DatagramIterator &scan, BamReader *manager);
190 
191 public:
192  static TypeHandle get_class_type() {
193  return _type_handle;
194  }
195  static void init_type() {
196  MovieVideoCursor::init_type();
197  register_type(_type_handle, "FfmpegVideoCursor",
198  MovieVideoCursor::get_class_type());
199  FfmpegBuffer::init_type();
200  }
201  virtual TypeHandle get_type() const {
202  return get_class_type();
203  }
204  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
205 
206 private:
207  static TypeHandle _type_handle;
208 
209  friend class FfmpegVideo;
210 };
211 
212 #include "ffmpegVideoCursor.I"
213 
214 #endif // FFMPEGVIDEO_H
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A standard mutex, or mutual exclusion lock.
Definition: pmutex.h:38
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Enables ffmpeg to access panda's VFS.
This is our own Panda specialization on the default STL deque.
Definition: pdeque.h:36
A condition variable, usually used to communicate information about changing state to a thread that i...
Definition: conditionVar.h:41
A lightweight class that represents a single element that may be timed and/or counted via stats.
virtual bool set_time(double timestamp, int loop_count)
Updates the cursor to the indicated time.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
A MovieVideo is actually any source that provides a sequence of video frames.
virtual int compare_timestamp(const Buffer *other) const
Used to sort different buffers to ensure they correspond to the same source frame,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A generic thread type that allows calling a C-style thread function without having to subclass.
Definition: genericThread.h:24
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A class to retrieve the individual data elements previously stored in a Datagram.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
A reentrant mutex.
Definition: reMutex.h:32
virtual double get_timestamp() const
Returns the nearest timestamp value of this particular buffer.