root/OpenSceneGraph/trunk/src/osgPlugins/quicktime/QuicktimeImageStream.cpp @ 3318

Revision 3318, 6.0 kB (checked in by robert, 10 years ago)

Added support for looping mode

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// -*-c++-*-
2
3/*
4 * Copyright (C) 2004 Stephan Huber http://digitalmind.de
5 *
6 *
7 * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
8 * real-time rendering of large 3D photo-realistic models.
9 * The OSG homepage is http://www.openscenegraph.org/
10 *
11 * This software is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 */
25
26#include "QuicktimeImageStream.h"
27#include <osg/Notify>
28#include <osg/Timer>
29
30#include <OpenThreads/ScopedLock>
31
32#include "QTUtils.h"
33#include "MovieData.h"
34
35
36using namespace osg;
37
38#define IDLE_TIMEOUT 150000L
39#define ERR_MSG(no,msg) osg::notify(osg::WARN) << "QT-ImageStream: " << msg << " failed with error " << no << std::endl;
40
41static OpenThreads::Mutex* s_qtMutex = new OpenThreads::Mutex;
42
43
44// Constructor: setup and start thread
45QuicktimeImageStream::QuicktimeImageStream(std::string fileName) : ImageStream()
46{
47
48    {   
49        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
50        osgQuicktime::initQuicktime();
51    }
52       
53    _len = 0;
54   
55    _data = new MovieData();
56
57    for (int i = 0; i < NUM_CMD_INDEX; i++)
58        _cmd[i] = THREAD_IDLE;
59    _wrIndex = _rdIndex = 0;
60
61    load(fileName);
62
63    if (!fileName.empty())
64        setFileName(fileName);
65}
66
67
68// Deconstructor: stop and terminate thread
69QuicktimeImageStream::~QuicktimeImageStream()
70{
71
72    if( isRunning() )
73    {
74        quit(true);
75    }
76
77    // clean up quicktime movies.
78    {   
79        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
80        delete _data;
81    }
82}
83
84
85// Set command
86void QuicktimeImageStream::setCmd(ThreadCommand cmd)
87{
88    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
89
90    _cmd[_wrIndex] = cmd;
91    _wrIndex = (_wrIndex + 1) % NUM_CMD_INDEX;
92}
93
94
95// Get command
96QuicktimeImageStream::ThreadCommand QuicktimeImageStream::getCmd()
97{
98    ThreadCommand cmd = THREAD_IDLE;
99
100    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
101
102    if (_rdIndex != _wrIndex) {
103        cmd = _cmd[_rdIndex];
104        _rdIndex = (_rdIndex + 1) % NUM_CMD_INDEX;
105    }
106
107    return cmd;
108}
109
110
111void QuicktimeImageStream::load(std::string fileName)
112{
113    osg::notify(osg::DEBUG_INFO) << "QT-ImageStream: loading quicktime movie from " << fileName << std::endl;
114   
115    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
116
117    _data->load(this, fileName);
118   
119    _len = _data->getMovieDuration();
120   
121   
122}
123
124void QuicktimeImageStream::quit(bool wiatForThreadToExit)
125{
126    osg::notify(osg::DEBUG_INFO)<<"Sending quit"<<this<<std::endl;
127    setCmd(THREAD_QUIT);
128
129    if (wiatForThreadToExit)
130    {
131        while(isRunning())
132        {
133            osg::notify(osg::DEBUG_INFO)<<"Waiting for QuicktimeImageStream to quit"<<this<<std::endl;
134            OpenThreads::Thread::YieldCurrentThread();
135        }
136        osg::notify(osg::DEBUG_INFO)<<"QuicktimeImageStream has quit"<<this<<std::endl;
137    }
138}
139
140
141void QuicktimeImageStream::run()
142{
143
144    bool playing = false;
145    bool done = false;
146    //OSErr err;
147   
148    // err = EnterMoviesOnThread(0);
149    // ERR_MSG(err,"EnterMoviesOnThread");
150           
151    while (!done) {
152        // osg::notify(osg::ALWAYS) << "movietime: " << _data->getMovieTime() << " state " << getCmd() << std::endl;
153        // Handle commands
154        ThreadCommand cmd = getCmd();
155
156        float currentTime=0.0f;
157   
158        {
159            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
160
161            if (cmd != THREAD_IDLE) {
162                switch (cmd) {
163                    case THREAD_START: // Start or continue stream
164                        StartMovie(_data->getMovie());
165                        playing = true;
166                        break;
167
168                    case THREAD_STOP:
169                        SetMovieRate(_data->getMovie(),0);
170                        osg::notify(INFO) << "QT-ImageStream: stop at "<< std::endl;
171                        playing = false;
172                        break;
173
174                    case THREAD_REWIND:
175                        SetMovieRate(_data->getMovie(),0);
176                        GoToBeginningOfMovie(_data->getMovie());
177                        break;
178
179                    case THREAD_CLOSE:
180                        SetMovieRate(_data->getMovie(),0);
181                        break;
182
183                    case THREAD_QUIT: // TODO
184                        SetMovieRate(_data->getMovie(),0);
185                        osg::notify(INFO) << "QT-ImageStream: quit" << std::endl;
186                        //playing = false;
187                        done = true;
188                        break;
189                    default:
190                        osg::notify(osg::WARN) << "QT-ImageStream: Unknown command " << cmd << std::endl;
191                        break;
192                }
193            }
194
195            MoviesTask(_data->getMovie(),0);
196
197            currentTime = _data->getMovieTime();
198        }
199       
200
201        if (_lastUpdate!= currentTime)
202        {
203
204            dirty();
205            _lastUpdate = currentTime;
206
207            if (currentTime>=_data->getMovieDuration())
208            {
209                if (getLoopingMode()==LOOPING)
210                {
211                    rewind();
212                    play();
213                }
214                else
215                {
216                    pause();
217                }
218            }
219
220        }
221       
222        if (playing)
223        {
224            // TODO
225        }
226        else if (!done)
227        {
228            ::usleep(IDLE_TIMEOUT);
229        }
230    }
231    // err = ExitMoviesOnThread();
232    //ERR_MSG(err,"ExitMoviesOnThread");
233}
Note: See TracBrowser for help on using the browser.