VideoTexture: reactivate VideoTexture for scons/cmake/makefile compilation systems...
[blender.git] / source / gameengine / VideoTexture / VideoFFmpeg.h
1 /* $Id$
2 -----------------------------------------------------------------------------
3 This source file is part of VideoTexture library
4
5 Copyright (c) 2007 The Zdeno Ash Miklas
6
7 This program is free software; you can redistribute it and/or modify it under
8 the terms of the GNU Lesser General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
10 version.
11
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
19 http://www.gnu.org/copyleft/lesser.txt.
20 -----------------------------------------------------------------------------
21 */
22 #if !defined VIDEOFFMPEG_H
23 #define VIDEOFFMPEG_H
24
25 #ifdef WITH_FFMPEG
26 extern "C" {
27 #include <pthread.h>
28 #include <ffmpeg/avformat.h>
29 #include <ffmpeg/avcodec.h>
30 #include <ffmpeg/rational.h>
31 #include <ffmpeg/swscale.h>
32 #include "DNA_listBase.h"
33 #include "BLI_threads.h"
34 #include "BLI_blenlib.h"
35 }
36
37
38 #if LIBAVFORMAT_VERSION_INT < (49 << 16)
39 #define FFMPEG_OLD_FRAME_RATE 1
40 #else
41 #define FFMPEG_CODEC_IS_POINTER 1
42 #endif
43
44 #if LIBAVFORMAT_VERSION_INT >= (52 << 16)
45 #define FFMPEG_PB_IS_POINTER 1
46 #endif
47
48 #ifdef FFMPEG_CODEC_IS_POINTER
49 static inline AVCodecContext* get_codec_from_stream(AVStream* stream)
50 {
51         return stream->codec;
52 }
53 #else
54 static inline AVCodecContext* get_codec_from_stream(AVStream* stream)
55 {
56         return &stream->codec;
57 }
58 #endif
59
60 #include "VideoBase.h"
61
62 #define CACHE_FRAME_SIZE        5
63 #define CACHE_PACKET_SIZE       30
64
65 // type VideoFFmpeg declaration
66 class VideoFFmpeg : public VideoBase
67 {
68 public:
69         /// constructor
70         VideoFFmpeg (HRESULT * hRslt);
71         /// destructor
72         virtual ~VideoFFmpeg ();
73
74         /// set initial parameters
75         void initParams (short width, short height, float rate, bool image=false);
76         /// open video/image file
77         virtual void openFile (char * file);
78         /// open video capture device
79         virtual void openCam (char * driver, short camIdx);
80
81         /// release video source
82         virtual bool release (void);
83
84         /// play video
85         virtual bool play (void);
86         /// stop/pause video
87         virtual bool stop (void);
88
89         /// set play range
90         virtual void setRange (double start, double stop);
91         /// set frame rate
92         virtual void setFrameRate (float rate);
93         // some specific getters and setters
94         int getPreseek(void) { return m_preseek; }
95         void setPreseek(int preseek) { if (preseek >= 0) m_preseek = preseek; }
96         bool getDeinterlace(void) { return m_deinterlace; }
97         void setDeinterlace(bool deinterlace) { m_deinterlace = deinterlace; }
98         char *getImageName(void) { return (m_isImage) ? m_imageName.Ptr() : NULL; }
99
100 protected:
101         // format and codec information
102         AVCodec *m_codec;
103         AVFormatContext *m_formatCtx;
104         AVCodecContext *m_codecCtx;
105         // raw frame extracted from video file
106         AVFrame *m_frame;
107         // deinterlaced frame if codec requires it
108         AVFrame *m_frameDeinterlaced;
109         // decoded RGB24 frame if codec requires it
110         AVFrame *m_frameRGB;
111         // conversion from raw to RGB is done with sws_scale
112         struct SwsContext *m_imgConvertCtx;
113         // should the codec be deinterlaced?
114         bool m_deinterlace;
115         // number of frame of preseek
116         int m_preseek;
117         // order number of stream holding the video in format context
118         int m_videoStream;
119
120         // the actual frame rate
121         double m_baseFrameRate;
122
123         /// last displayed frame
124         long m_lastFrame;
125
126         /// end of file reached
127         bool m_eof;
128
129         /// current file pointer position in file expressed in frame number
130         long m_curPosition;
131
132         /// time of video play start
133         double m_startTime;
134
135         /// width of capture in pixel
136         short m_captWidth;
137         
138         /// height of capture in pixel
139         short m_captHeight;
140
141         /// frame rate of capture in frames per seconds
142         float m_captRate;
143
144         /// is file an image?
145         bool m_isImage;
146
147         /// is image loading done in a separate thread?
148         bool m_isThreaded;
149
150         /// keep last image name
151         STR_String m_imageName;
152
153         /// image calculation
154         virtual void calcImage (unsigned int texId);
155
156         /// load frame from video
157         void loadFrame (void);
158
159         /// set actual position
160         void setPositions (void);
161
162         /// get actual framerate
163         double actFrameRate (void) { return m_frameRate * m_baseFrameRate; }
164
165         /// common function to video file and capture
166         int openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams);
167
168         /// check if a frame is available and load it in pFrame, return true if a frame could be retrieved
169         AVFrame* grabFrame(long frame);
170
171         /// in case of caching, put the frame back in free queue
172         void releaseFrame(AVFrame* frame);
173
174         /// start thread to load the video file/capture/stream 
175         bool startCache();
176         void stopCache();
177
178 private:
179         typedef struct {
180                 Link link;
181                 long framePosition;
182                 AVFrame *frame;
183         } CacheFrame;
184         typedef struct {
185                 Link link;
186                 AVPacket packet;
187         } CachePacket;
188
189         bool m_stopThread;
190         bool m_cacheStarted;
191         ListBase m_thread;
192         ListBase m_frameCacheBase;      // list of frames that are ready
193         ListBase m_frameCacheFree;      // list of frames that are unused
194         ListBase m_packetCacheBase;     // list of packets that are ready for decoding
195         ListBase m_packetCacheFree;     // list of packets that are unused
196         pthread_mutex_t m_cacheMutex;
197
198         AVFrame *allocFrameRGB();
199         static void *cacheThread(void *);
200 };
201
202 inline VideoFFmpeg * getFFmpeg (PyImage * self) 
203 {
204         return static_cast<VideoFFmpeg*>(self->m_image); 
205 }
206
207 #endif  //WITH_FFMPEG
208
209 #endif