23
23
#include "DefineVideoStreamTag.h"
24
24
#include "fn_call.h"
25
25
#include "as_value.h"
26
#include "NetStream_as.h"
26
#include "flash/net/NetStream_as.h"
28
27
#include "Range2d.h"
29
28
#include "builtin_function.h" // for getter/setter properties
29
#include "NativeFunction.h"
30
#include "movie_root.h"
31
32
#include "Object.h"
32
33
#include "MediaHandler.h" // for setting up embedded video decoder
33
34
#include "VideoDecoder.h" // for setting up embedded video decoder
34
35
#include "namedStrings.h"
36
#include "Global_as.h"
36
38
// Define this to get debug logging during embedded video decoding
37
39
//#define DEBUG_EMBEDDED_VIDEO_DECODING
52
54
as_value video_height(const fn_call& fn);
55
Video::Video(SWF::DefineVideoStreamTag* def,
56
character* parent, int id)
57
Video::Video(const SWF::DefineVideoStreamTag* const def,
58
DisplayObject* parent, int id)
58
character(parent, id),
60
DisplayObject(parent, id),
61
63
_embeddedStream(m_def ? true : false),
138
Video::display(Renderer& renderer)
138
140
// if m_def is NULL we've been constructed by 'new Video', in this
139
141
// case I think display() would never be invoked on us...
142
144
SWFMatrix m = getWorldMatrix();
143
const rect& bounds = m_def->get_bound();
145
const rect& bounds = m_def->bounds();
145
147
GnashImage* img = getVideoFrame();
148
gnash::render::drawVideoFrame(img, &m, &bounds, _smoothing);
150
renderer.drawVideoFrame(img, &m, &bounds, _smoothing);
151
153
clear_invalidated();
268
268
// NOTE: only needed for gstreamer:
269
269
if (_ns->newFrameReady()) set_invalidated();
274
Video::add_invalidated_bounds(InvalidatedRanges& ranges,
274
Video::add_invalidated_bounds(InvalidatedRanges& ranges, bool force)
277
276
if (!force && !m_invalidated) return; // no need to redraw
279
278
ranges.add(m_old_invalidated_ranges);
281
// NOTE: do not use m_def->get_bounds()
280
// NOTE: do not use m_def->boundss()
283
282
// if m_def is NULL we've been constructed by 'new Video', in this
284
283
// case I think add_invalidated_bouns would never be invoked on us...
285
284
assert ( m_def );
288
bounds.expand_to_transformed_rect(getWorldMatrix(), m_def->get_bound());
287
bounds.expand_to_transformed_rect(getWorldMatrix(), m_def->bounds());
290
289
ranges.add(bounds.getRange());
294
Video::setStream(boost::intrusive_ptr<NetStream_as> ns)
293
Video::setStream(NetStream_as* ns)
297
296
_ns->setInvalidatedVideo(this);
300
299
// extern (used by Global.cpp)
302
video_class_init(as_object& global)
301
video_class_init(as_object& global, const ObjectURI& uri)
304
303
// This is going to be the global Video "class"/"function"
305
static boost::intrusive_ptr<builtin_function> cl;
309
cl=new builtin_function(&video_ctor, getVideoInterface(global));
310
global.getVM().addStatic(cl.get());
304
Global_as* gl = getGlobal(global);
305
as_object* cl = gl->createClass(&video_ctor, getVideoInterface(global));
313
307
// Register _global.Video
314
global.init_member("Video", cl.get());
308
global.init_member(getName(uri), cl, as_object::DefaultFlags,
313
registerVideoNative(as_object& global)
315
VM& vm = getVM(global);
316
vm.registerNative(video_ctor, 667, 0);
317
vm.registerNative(video_attach, 667, 1);
318
vm.registerNative(video_clear, 667, 2);
318
322
Video::getBounds() const
320
if (_embeddedStream) return m_def->get_bound();
324
if (_embeddedStream) return m_def->bounds();
322
326
// TODO: return the bounds of the dynamically
323
327
// loaded video if not embedded ?
356
359
attachVideoInterface(as_object& o)
358
o.init_member("attachVideo", new builtin_function(video_attach));
359
o.init_member("clear", new builtin_function(video_clear));
362
o.init_member("attachVideo", vm.getNative(667, 1));
363
o.init_member("clear", vm.getNative(667, 2));
363
367
attachPrototypeProperties(as_object& proto)
365
const int protect = as_prop_flags::dontDelete;
369
const int protect = PropFlags::dontDelete;
367
371
proto.init_property("deblocking", &video_deblocking, &video_deblocking,
369
373
proto.init_property("smoothing", &video_smoothing, &video_smoothing,
372
const int flags = as_prop_flags::dontDelete |
373
as_prop_flags::readOnly;
376
const int flags = PropFlags::dontDelete |
375
379
proto.init_property("height", &video_height, &video_height, flags);
376
380
proto.init_property("width", &video_width, &video_width, flags);
383
387
as_c_function_ptr gettersetter;
385
gettersetter = &character::x_getset;
389
gettersetter = &DisplayObject::x_getset;
386
390
o.init_property(NSV::PROP_uX, *gettersetter, *gettersetter);
388
gettersetter = &character::y_getset;
392
gettersetter = &DisplayObject::y_getset;
389
393
o.init_property(NSV::PROP_uY, *gettersetter, *gettersetter);
391
gettersetter = &character::xscale_getset;
395
gettersetter = &DisplayObject::xscale_getset;
392
396
o.init_property(NSV::PROP_uXSCALE, *gettersetter, *gettersetter);
394
gettersetter = &character::yscale_getset;
398
gettersetter = &DisplayObject::yscale_getset;
395
399
o.init_property(NSV::PROP_uYSCALE, *gettersetter, *gettersetter);
397
gettersetter = &character::xmouse_get;
401
gettersetter = &DisplayObject::xmouse_get;
398
402
o.init_readonly_property(NSV::PROP_uXMOUSE, *gettersetter);
400
gettersetter = &character::ymouse_get;
404
gettersetter = &DisplayObject::ymouse_get;
401
405
o.init_readonly_property(NSV::PROP_uYMOUSE, *gettersetter);
403
gettersetter = &character::alpha_getset;
407
gettersetter = &DisplayObject::alpha_getset;
404
408
o.init_property(NSV::PROP_uALPHA, *gettersetter, *gettersetter);
406
gettersetter = &character::visible_getset;
410
gettersetter = &DisplayObject::visible_getset;
407
411
o.init_property(NSV::PROP_uVISIBLE, *gettersetter, *gettersetter);
409
gettersetter = &character::width_getset;
413
gettersetter = &DisplayObject::width_getset;
410
414
o.init_property(NSV::PROP_uWIDTH, *gettersetter, *gettersetter);
412
gettersetter = &character::height_getset;
416
gettersetter = &DisplayObject::height_getset;
413
417
o.init_property(NSV::PROP_uHEIGHT, *gettersetter, *gettersetter);
415
gettersetter = &character::rotation_getset;
419
gettersetter = &DisplayObject::rotation_getset;
416
420
o.init_property(NSV::PROP_uROTATION, *gettersetter, *gettersetter);
418
gettersetter = &character::parent_getset;
422
gettersetter = &DisplayObject::parent_getset;
419
423
o.init_property(NSV::PROP_uPARENT, *gettersetter, *gettersetter);
421
gettersetter = &character::target_getset;
425
gettersetter = &DisplayObject::target_getset;
422
426
o.init_property(NSV::PROP_uTARGET, *gettersetter, *gettersetter);
435
439
return as_value();
438
boost::intrusive_ptr<NetStream_as> ns =
439
boost::dynamic_pointer_cast<NetStream_as>(fn.arg(0).to_object());
442
as_object* obj = fn.arg(0).to_object(*getGlobal(fn)).get();
445
if (isNativeType(obj, ns)) {
442
446
video->setStream(ns);
446
449
IF_VERBOSE_ASCODING_ERRORS(
447
450
log_aserror(_("attachVideo(%s) first arg is not a NetStream instance"),
506
509
// I'm not sure We can rely on the def and parent values being accepted
507
510
// as NULL. Not till we add some testing...
508
boost::intrusive_ptr<character> obj = new Video(NULL, NULL, -1);
511
boost::intrusive_ptr<DisplayObject> obj = new Video(NULL, NULL, -1);
509
512
obj->setDynamic();
510
513
return as_value(obj.get()); // will keep alive