1 /*
2 * MovieData.cpp
3 * lala
4 *
5 * Created by Stephan Huber on Wed Mar 10 2004.
6 * Copyright (c) 2004 __MyCompanyName__. All rights reserved.
7 *
8 */
9 #include <osg/GL>
10 #include <osg/Endian>
11 #include <osg/Image>
12 #include <osgDB/FileNameUtils>
13
14 #include "MovieData.h"
15 #include "QTUtils.h"
16
17
18
19
MovieData()20 MovieData::MovieData() : _pointer(NULL), _movie(NULL), _gw(NULL), _fError(false), _isLooping(false)
21 {
22
23 }
24
25
~MovieData()26 MovieData::~MovieData()
27 {
28 if (_pointer) free(_pointer);
29 if (_gw) DisposeGWorld(_gw);
30
31 if (_movie) {
32 DisposeMovie(_movie);
33 }
34 }
35
36
37
38
load(osg::Image * image,std::string afilename,double startTime)39 void MovieData::load(osg::Image* image, std::string afilename, double startTime)
40 {
41 bool isUrl( osgDB::containsServerAddress(afilename) );
42
43 std::string filename = afilename;
44 if (!isUrl) {
45 if (!osgDB::isFileNameNativeStyle(filename))
46 filename = osgDB::convertFileNameToNativeStyle(filename);
47 }
48
49 image->setFileName(filename);
50
51
52 QTNewMoviePropertyElement newMovieProperties[2];
53 CFStringRef movieLocation = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8);
54 CFURLRef movieURL(NULL);
55 Boolean trueValue = true;
56
57 newMovieProperties[0].propClass = kQTPropertyClass_DataLocation;
58 if (!isUrl)
59 {
60 #ifdef __APPLE__
61 newMovieProperties[0].propID = kQTDataLocationPropertyID_CFStringPosixPath;
62 #else
63 newMovieProperties[0].propID = kQTDataLocationPropertyID_CFStringWindowsPath;
64 #endif
65
66 newMovieProperties[0].propValueSize = sizeof(CFStringRef);
67 newMovieProperties[0].propValueAddress = &movieLocation;
68 }
69 else
70 {
71 movieURL = CFURLCreateWithString(kCFAllocatorDefault, movieLocation, NULL);
72
73 newMovieProperties[0].propID = kQTDataLocationPropertyID_CFURL;
74 newMovieProperties[0].propValueSize = sizeof(movieURL);
75 newMovieProperties[0].propValueAddress = (void*)&movieURL;
76 }
77
78 // make movie active
79 newMovieProperties[1].propClass = kQTPropertyClass_NewMovieProperty;
80 newMovieProperties[1].propID = kQTNewMoviePropertyID_Active;
81 newMovieProperties[1].propValueSize = sizeof(trueValue);
82 newMovieProperties[1].propValueAddress = &trueValue;
83
84 // Instantiate the Movie
85 OSStatus status = NewMovieFromProperties(2, newMovieProperties, 0, NULL, &_movie);
86 CFRelease(movieLocation);
87 if (movieURL) CFRelease(movieURL);
88
89 if (status !=0) {
90 _fError = true;
91 OSG_FATAL << " MovieData :: NewMovieFromProperties failed with err " << status<< std::endl;
92 return;
93 }
94
95
96 Rect bounds;
97
98 #ifdef __APPLE__
99 GetRegionBounds(GetMovieBoundsRgn(_movie), &bounds);
100 #else
101 bounds = (*GetMovieBoundsRgn(_movie))->rgnBBox;
102 #endif
103
104 _checkMovieError("Can't get movie bounds\n");
105
106 OffsetRect(&bounds, -bounds.left, -bounds.top);
107 SetMovieBox(_movie, &bounds);
108 _checkMovieError("Can't set movie box\n");
109
110 _movieWidth = bounds.right;
111 _movieHeight = bounds.bottom;
112
113 _timescale = GetMovieTimeScale(_movie);
114
115 _initImage(image);
116 if (!_fError) _initGWorldStuff(image);
117
118
119 if (!_fError) {
120
121 if ( startTime == 0.0)
122 GoToBeginningOfMovie(_movie);
123 else {
124 TimeValue t = (TimeValue) (startTime*_timescale);
125 SetMovieTimeValue(_movie,t);
126 }
127
128 UpdateMovie(_movie);
129 SetMovieRate(_movie,0.0);
130 SetMovieActive(_movie, true);
131 UpdateMovie(_movie);
132 MoviesTask(_movie,0);
133 }
134 }
135
136
137 // ---------------------------------------------------------------------------
138 // _intImage
139 // create image for storing
140 // ---------------------------------------------------------------------------
141
_initImage(osg::Image * image)142 void MovieData::_initImage(osg::Image* image)
143 {
144
145 void* buffer;
146
147
148 _textureWidth = ((_movieWidth + 7) >> 3) << 3;
149 _textureHeight = _movieHeight;
150
151 // some magic alignment...
152 _pointer = (char*)malloc(4 * _textureWidth * _textureHeight + 32);
153
154 if (_pointer == NULL) {
155 OSG_FATAL << "MovieData: " << "Can't allocate texture buffer" << std::endl;
156 _fError= true;
157 }
158
159 buffer = (void*)(((unsigned long)(_pointer + 31) >> 5) << 5);
160
161 GLenum internalFormat = (osg::getCpuByteOrder()==osg::BigEndian)?
162 GL_UNSIGNED_INT_8_8_8_8_REV :
163 GL_UNSIGNED_INT_8_8_8_8;
164
165 image->setImage(_textureWidth,_textureHeight,1,
166 (GLint) GL_RGBA8,
167 (GLenum)GL_BGRA,
168 internalFormat,
169 (unsigned char*) buffer,osg::Image::NO_DELETE,4);
170
171 }
172
173 // ---------------------------------------------------------------------------
174 // _initGWorldStuff
175 // init gworld-stuff, so quicktime can play the movie into the gWorld.
176 // ---------------------------------------------------------------------------
177
_initGWorldStuff(osg::Image * image)178 void MovieData::_initGWorldStuff(osg::Image * image) {
179
180 Rect textureBounds;
181 OSStatus err;
182 GDHandle origDevice;
183 CGrafPtr origPort;
184 PixMapHandle pixmap = NULL;
185
186 textureBounds.left = 0;
187 textureBounds.top = 0;
188 textureBounds.right = image->s();
189 textureBounds.bottom = image->t();
190 err = QTNewGWorldFromPtr(&_gw, k32ARGBPixelFormat, &textureBounds, NULL, NULL, 0, image->data(), 4 * image->s());
191
192 if (err !=0 )
193 {
194 OSG_FATAL << "MovieData : Could not create gWorld" << std::endl;
195 }
196
197 GetGWorld (&origPort, &origDevice);
198 SetGWorld(_gw, NULL); // set current graphics port to offscreen
199 SetMovieGWorld(_movie, (CGrafPtr)_gw, NULL);
200
201 _checkMovieError("SetMovieGWorld failed");
202
203 pixmap = GetGWorldPixMap (_gw);
204 if (pixmap)
205 {
206 if (!LockPixels (pixmap)) // lock offscreen pixel map
207 {
208 OSG_FATAL << "Could not lock PixMap" << std::endl;
209 ExitToShell ();
210 }
211 }
212 else
213 {
214 OSG_FATAL << "Could not GetGWorldPixMap" << std::endl;
215 ExitToShell ();
216 }
217
218 SetGWorld(origPort, origDevice);
219
220 }
221
setMovieTime(double atime)222 void MovieData::setMovieTime(double atime) {
223 double time = (atime > getMovieDuration()) ? getMovieDuration() : atime;
224
225 TimeValue t = (TimeValue) (time * _timescale);
226 SetMovieTimeValue(_movie,t);
227 _checkMovieError("setMovieTime failed");
228 UpdateMovie(_movie);
229 MoviesTask(_movie,0);
230
231
232 }
233
setMovieRate(double rate)234 void MovieData::setMovieRate(double rate) {
235 // OSG_ALWAYS << "new movierate: " << rate << " current: " << getMovieRate() << std::endl;
236 _movieRate = rate;
237 if ((rate != 0) && (_preRolled == false)) {
238 PrerollMovie(_movie, GetMovieTime(_movie,NULL), X2Fix(rate));
239 _checkMovieError("PrerollMovie failed");
240 _preRolled = true;
241 }
242
243 SetMovieRate(_movie, X2Fix(rate));
244 _checkMovieError("setMovieRate failed");
245 MoviesTask(_movie, 0);
246 _checkMovieError("MoviesTask failed");
247
248 UpdateMovie(_movie);
249 _checkMovieError("UpdateMovie failed");
250
251 }
252
253
254
255
256