9b09c485329a6b3a80173138304a46ef91630a31
[blender-staging.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
23 /** \file VideoFFmpeg.h
24  *  \ingroup bgevideotex
25  */
26  
27 #if !defined VIDEOFFMPEG_H
28 #define VIDEOFFMPEG_H
29
30 #ifdef WITH_FFMPEG
31 extern "C" {
32 #undef __cplusplus
33 #include <pthread.h>
34 #include <libavformat/avformat.h>
35 #include <libavcodec/avcodec.h>
36 #include <libavutil/rational.h>
37 #include <libswscale/swscale.h>
38 #include "DNA_listBase.h"
39 #include "BLI_threads.h"
40 #include "BLI_blenlib.h"
41 #define __cplusplus
42 }
43
44
45 #if LIBAVFORMAT_VERSION_INT < (49 << 16)
46 #define FFMPEG_OLD_FRAME_RATE 1
47 #else
48 #define FFMPEG_CODEC_IS_POINTER 1
49 #endif
50
51 #if LIBAVFORMAT_VERSION_INT >= (52 << 16)
52 #define FFMPEG_PB_IS_POINTER 1
53 #endif
54
55 #ifdef FFMPEG_CODEC_IS_POINTER
56 static inline AVCodecContext* get_codec_from_stream(AVStream* stream)
57 {
58         return stream->codec;
59 }
60 #else
61 static inline AVCodecContext* get_codec_from_stream(AVStream* stream)
62 {
63         return &stream->codec;
64 }
65 #endif
66
67 #include "VideoBase.h"
68
69 #define CACHE_FRAME_SIZE        10
70 #define CACHE_PACKET_SIZE       30
71
72 // type VideoFFmpeg declaration
73 class VideoFFmpeg : public VideoBase
74 {
75 public:
76         /// constructor
77         VideoFFmpeg (HRESULT * hRslt);
78         /// destructor
79         virtual ~VideoFFmpeg ();
80
81         /// set initial parameters
82         void initParams (short width, short height, float rate, bool image=false);
83         /// open video/image file
84         virtual void openFile (char * file);
85         /// open video capture device
86         virtual void openCam (char * driver, short camIdx);
87
88         /// release video source
89         virtual bool release (void);
90
91         /// play video
92         virtual bool play (void);
93         /// pause video
94         virtual bool pause (void);
95         /// stop video
96         virtual bool stop (void);
97         /// set play range
98         virtual void setRange (double start, double stop);
99         /// set frame rate
100         virtual void setFrameRate (float rate);
101         // some specific getters and setters
102         int getPreseek(void) { return m_preseek; }
103         void setPreseek(int preseek) { if (preseek >= 0) m_preseek = preseek; }
104         bool getDeinterlace(void) { return m_deinterlace; }
105         void setDeinterlace(bool deinterlace) { m_deinterlace = deinterlace; }
106         char *getImageName(void) { return (m_isImage) ? m_imageName.Ptr() : NULL; }
107
108 protected:
109         // format and codec information
110         AVCodec *m_codec;
111         AVFormatContext *m_formatCtx;
112         AVCodecContext *m_codecCtx;
113         // raw frame extracted from video file
114         AVFrame *m_frame;
115         // deinterlaced frame if codec requires it
116         AVFrame *m_frameDeinterlaced;
117         // decoded RGB24 frame if codec requires it
118         AVFrame *m_frameRGB;
119         // conversion from raw to RGB is done with sws_scale
120         struct SwsContext *m_imgConvertCtx;
121         // should the codec be deinterlaced?
122         bool m_deinterlace;
123         // number of frame of preseek
124         int m_preseek;
125         // order number of stream holding the video in format context
126         int m_videoStream;
127
128         // the actual frame rate
129         double m_baseFrameRate;
130
131         /// last displayed frame
132         long m_lastFrame;
133
134         /// end of file reached
135         bool m_eof;
136
137         /// flag to indicate that time is coming from application
138         bool m_externTime;
139
140         /// current file pointer position in file expressed in frame number
141         long m_curPosition;
142
143         /// time of video play start
144         double m_startTime;
145
146         /// width of capture in pixel
147         short m_captWidth;
148         
149         /// height of capture in pixel
150         short m_captHeight;
151
152         /// frame rate of capture in frames per seconds
153         float m_captRate;
154
155         /// is file an image?
156         bool m_isImage;
157
158         /// is image loading done in a separate thread?
159         bool m_isThreaded;
160
161         /// is streaming or camera?
162         bool m_isStreaming;
163
164         /// keep last image name
165         STR_String m_imageName;
166
167         /// image calculation
168         virtual void calcImage (unsigned int texId, double ts);
169
170         /// set actual position
171         void setPositions (void);
172
173         /// get actual framerate
174         double actFrameRate (void) { return m_frameRate * m_baseFrameRate; }
175
176         /// common function to video file and capture
177         int openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams);
178
179         /// check if a frame is available and load it in pFrame, return true if a frame could be retrieved
180         AVFrame* grabFrame(long frame);
181
182         /// in case of caching, put the frame back in free queue
183         void releaseFrame(AVFrame* frame);
184
185         /// start thread to load the video file/capture/stream 
186         bool startCache();
187         void stopCache();
188
189 private:
190         typedef struct {
191                 Link link;
192                 long framePosition;
193                 AVFrame *frame;
194         } CacheFrame;
195         typedef struct {
196                 Link link;
197                 AVPacket packet;
198         } CachePacket;
199
200         bool m_stopThread;
201         bool m_cacheStarted;
202         ListBase m_thread;
203         ListBase m_frameCacheBase;      // list of frames that are ready
204         ListBase m_frameCacheFree;      // list of frames that are unused
205         ListBase m_packetCacheBase;     // list of packets that are ready for decoding
206         ListBase m_packetCacheFree;     // list of packets that are unused
207         pthread_mutex_t m_cacheMutex;
208
209         AVFrame *allocFrameRGB();
210         static void *cacheThread(void *);
211 };
212
213 inline VideoFFmpeg * getFFmpeg (PyImage * self) 
214 {
215         return static_cast<VideoFFmpeg*>(self->m_image); 
216 }
217
218 #endif  //WITH_FFMPEG
219
220 #endif