Rev Author Line No. Line
1 ovan 1 #include "../driver/context.h"
2 #include "video.h"
8 ovan 3  
4 #ifdef video_reader_support
1 ovan 5  
6 #include <theora/TheoraDataSource.h>
7  
8 namespace sleek
9 {
10     namespace video
11     {
12         CVideoMaster::CVideoMaster(driver::context *cx, bool readAudio, u32 workerThreads) noexcept
13             : mTimer(new math::timer), context(cx), mVmgr(0), mAIF(0)
14         {
15             mVmgr = new TheoraVideoManager(std::max(workerThreads, 1u));
9 ovan 16             #ifdef video_reader_audio_support
1 ovan 17             if(readAudio)
18             {
19                 mAIF = new CAudioInterfaceFactoryOpenAL();
20                 mVmgr->setAudioInterfaceFactory(mAIF);
21             }
22             #endif
23         }
24  
25         CVideoMaster::~CVideoMaster() noexcept
26         {
27             removeVideoClipAll();
28             if(mVmgr) delete mVmgr;
9 ovan 29             #ifdef video_reader_audio_support
1 ovan 30             if(mAIF) delete mAIF;
31             #endif
32         }
33  
34         void CVideoMaster::processFrames() noexcept
35         {
36             for(u32 i = 0; i<mClip.size(); ++i)
37             {
38                 TheoraVideoFrame* frame = mClip[i]->pTheoClip->getNextFrame();
39                 if(frame)
40                 {
41                     driver::texture* pTex = mClip[i]->pTex;
42  
43                     void* imgData = pTex->getBuffer();
44                     u8* frameData = frame->getBuffer();
45  
46                     if(imgData && frameData)
47                     {
48                         memcpy(imgData, frameData, pTex->getBufferSize());
49                         pTex->getIdentifier()->update();
50                     }
51  
52                     mClip[i]->pTheoClip->popFrame();
53                 }
54                 #ifdef _DEBUG
55                     std::cout << mClip[i]->pTheoClip->getNumDisplayedFrames()
56                               << "/" << mClip[i]->pTheoClip->getNumFrames()
57                               << std::endl;
58                 #endif
59             }
60         }
61  
62         void CVideoMaster::update() noexcept
63         {
64             mTimer->update();
65  
66             processFrames();
67             mVmgr->update(mTimer->getTimeSec());
68  
69             mTimer->reset();
70         }
71  
72         SVideoClip* CVideoMaster::getClipByName(const std::string &clipname, u32 &out_clipindex) noexcept
73         {
74             for(u32 i = 0; i<mClip.size(); ++i)
75             {
76                 if(mClip[i]->clipName == clipname)
77                 {
78                     out_clipindex = i;
79                     return mClip[i];
80                 }
81             }
82             return nullptr;
83         }
84  
85         SVideoClip* CVideoMaster::getClipByName(const std::string &clipname) noexcept
86         {
87             for(u32 i = 0; i<mClip.size(); ++i)
88                 if(mClip[i]->clipName == clipname)
89                     return mClip[i];
90             return nullptr;
91         }
92  
93         TheoraVideoClip* CVideoMaster::getTheoClipByName(const std::string &clipname) noexcept
94         {
95             for(u32 i = 0; i<mClip.size(); ++i)
96                 if(mClip[i]->clipName == clipname)
97                     return mClip[i]->pTheoClip;
98             return nullptr;
99         }
100  
101         driver::texture* CVideoMaster::getTextureByName(const std::string &clipname) noexcept
102         {
103             for(u32 i = 0; i<mClip.size(); ++i)
104                 if(mClip[i]->clipName == clipname)
105                     return mClip[i]->pTex;
106             return nullptr;
107         }
108  
109         driver::texture* CVideoMaster::addVideoClip(const std::string &filename, const std::string &clipname, bool repeatPlayback, bool startPlayback, bool preloadIntoRAM) noexcept
110         {
111             TheoraVideoClip *pClip = 0;
112  
113             if(filename != "" || clipname != "")
114             {
115                 if(preloadIntoRAM)
116                 {
117                     pClip = mVmgr->createVideoClip(
118                         new TheoraMemoryFileDataSource(filename),
119                         TH_RGB
120                     );
121                 }
122                 else
123                 {
124                     pClip = mVmgr->createVideoClip(
125                         filename,
126                         TH_RGB
127                     );
128                 }
129  
130                 if(pClip)
131                 {
132                     if(startPlayback) pClip->play();
133                     else pClip->stop();
134  
135                     pClip->setAutoRestart(repeatPlayback);
136  
137                     const math::vector2di sizeClip(pClip->getWidth(), pClip->getHeight());
138  
139                     SVideoClip *temp = new SVideoClip();
140  
141                     temp->pTheoClip = pClip;
142                     temp->pTex      = new driver::texture(sizeClip, driver::TXFMT_RGB);
143                     temp->pTex->createIdentifier(context);
144                     temp->clipName  = clipname;
145  
146                     mClip.push_back(temp);
147                     return temp->pTex;
148                 }
149             }
150  
151             if(pClip)
152                 mVmgr->destroyVideoClip(pClip);
153  
154             return nullptr;
155         }
156  
157         bool CVideoMaster::removeVideoClip(const std::string &clipname, bool RemoveTexture) noexcept
158         {
159             u32 clipIndex;
160             SVideoClip* pClip = getClipByName(clipname, clipIndex);
161             if(!pClip) return false;
162  
163             if(pClip->pTheoClip)
164                 mVmgr->destroyVideoClip(pClip->pTheoClip);
165  
166             if(pClip->pTex && RemoveTexture)
167                 delete pClip->pTex;
168  
169             delete pClip;
170             mClip.erase(mClip.begin()+clipIndex);
171             return true;
172         }
173  
174         void CVideoMaster::removeVideoClipAll(bool RemoveTexture) noexcept
175         {
176             while(!mClip.empty())
177             {
178                 SVideoClip* pClip = mClip.back();
179                 if(pClip)
180                 {
181                     if(pClip->pTheoClip)
182                         mVmgr->destroyVideoClip(pClip->pTheoClip);
183                     if(pClip->pTex && RemoveTexture)
184                         delete pClip->pTex;
185                     delete pClip;
186                 }
187                 mClip.erase(mClip.end()-1);
188             }
189         }
190     }
191 }
192 #endif