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