~ubuntu-branches/ubuntu/karmic/gnash/karmic

« back to all changes in this revision

Viewing changes to libcore/Video.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sindhudweep Narayan Sarkar
  • Date: 2009-10-07 00:06:10 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20091007000610-mj9rwqe774gizn1j
Tags: 0.8.6-0ubuntu1
new upstream release 0.8.6 (LP: #435897)

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include "DefineVideoStreamTag.h"
24
24
#include "fn_call.h"
25
25
#include "as_value.h"
26
 
#include "NetStream_as.h"
27
 
#include "render.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"
30
31
#include "VM.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"
35
37
 
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);
53
55
}
54
56
 
55
 
Video::Video(SWF::DefineVideoStreamTag* def,
56
 
                character* parent, int id)
 
57
Video::Video(const SWF::DefineVideoStreamTag* const def,
 
58
                DisplayObject* parent, int id)
57
59
        :
58
 
        character(parent, id),
 
60
        DisplayObject(parent, id),
59
61
        m_def(def),
60
62
        _ns(0),
61
63
        _embeddedStream(m_def ? true : false),
133
135
}
134
136
 
135
137
void
136
 
Video::display()
 
138
Video::display(Renderer& renderer)
137
139
{
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...
140
142
        assert(m_def);
141
143
 
142
144
        SWFMatrix m = getWorldMatrix();
143
 
        const rect& bounds = m_def->get_bound();
 
145
        const rect& bounds = m_def->bounds();
144
146
 
145
147
        GnashImage* img = getVideoFrame();
146
148
        if (img)
147
149
        {
148
 
                gnash::render::drawVideoFrame(img, &m, &bounds, _smoothing);
 
150
                renderer.drawVideoFrame(img, &m, &bounds, _smoothing);
149
151
        }
150
152
 
151
153
        clear_invalidated();
254
256
 
255
257
    saveOriginalTarget(); // for softref
256
258
 
257
 
    // Register this video instance as a live character
258
 
    _vm.getRoot().addLiveChar(this);
 
259
    // Register this video instance as a live DisplayObject
 
260
    getRoot(*this).addLiveChar(this);
259
261
}
260
262
 
261
263
 
263
265
Video::advance()
264
266
{
265
267
        if (_ns) {
266
 
                //_ns->advance();
267
 
        
268
268
        // NOTE: only needed for gstreamer:
269
269
                if (_ns->newFrameReady()) set_invalidated();
270
270
        }
271
271
}
272
272
 
273
273
void
274
 
Video::add_invalidated_bounds(InvalidatedRanges& ranges, 
275
 
        bool force)
 
274
Video::add_invalidated_bounds(InvalidatedRanges& ranges, bool force)
276
275
{       
277
276
        if (!force && !m_invalidated) return; // no need to redraw
278
277
    
279
278
        ranges.add(m_old_invalidated_ranges);
280
279
        
281
 
        // NOTE: do not use m_def->get_bounds()
 
280
        // NOTE: do not use m_def->boundss()
282
281
 
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 );
286
285
 
287
286
        rect bounds;    
288
 
        bounds.expand_to_transformed_rect(getWorldMatrix(), m_def->get_bound());
 
287
        bounds.expand_to_transformed_rect(getWorldMatrix(), m_def->bounds());
289
288
        
290
289
        ranges.add(bounds.getRange());            
291
290
}
292
291
 
293
292
void
294
 
Video::setStream(boost::intrusive_ptr<NetStream_as> ns)
 
293
Video::setStream(NetStream_as* ns)
295
294
{
296
295
        _ns = ns;
297
296
        _ns->setInvalidatedVideo(this);
299
298
 
300
299
// extern (used by Global.cpp)
301
300
void
302
 
video_class_init(as_object& global)
 
301
video_class_init(as_object& global, const ObjectURI& uri)
303
302
{
304
303
        // This is going to be the global Video "class"/"function"
305
 
        static boost::intrusive_ptr<builtin_function> cl;
306
 
 
307
 
        if ( cl == NULL )
308
 
        {
309
 
                cl=new builtin_function(&video_ctor, getVideoInterface(global));
310
 
                global.getVM().addStatic(cl.get());
311
 
        }
 
304
    Global_as* gl = getGlobal(global);
 
305
    as_object* cl = gl->createClass(&video_ctor, getVideoInterface(global));
312
306
 
313
307
        // Register _global.Video
314
 
        global.init_member("Video", cl.get());
 
308
        global.init_member(getName(uri), cl, as_object::DefaultFlags,
 
309
            getNamespace(uri));
 
310
}
 
311
 
 
312
void
 
313
registerVideoNative(as_object& global)
 
314
{
 
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);
315
319
}
316
320
 
317
321
rect
318
322
Video::getBounds() const
319
323
{
320
 
        if (_embeddedStream) return m_def->get_bound();
 
324
        if (_embeddedStream) return m_def->bounds();
321
325
 
322
326
        // TODO: return the bounds of the dynamically
323
327
        //       loaded video if not embedded ?
328
332
void
329
333
Video::markReachableResources() const
330
334
{
331
 
        if ( _ns ) _ns->setReachable();
 
335
        if (_ns) _ns->setReachable();
332
336
 
333
 
        // Invoke character's version of reachability mark
334
 
        markCharacterReachable();
 
337
        // Invoke DisplayObject's version of reachability mark
 
338
        markDisplayObjectReachable();
335
339
}
336
340
#endif // GNASH_USE_GC
337
341
 
344
348
        if ( proto == NULL )
345
349
        {
346
350
                proto = new as_object(getObjectInterface());
347
 
                where.getVM().addStatic(proto.get());
 
351
                getVM(where).addStatic(proto.get());
348
352
 
349
353
                attachVideoInterface(*proto);
350
 
                //proto->init_member("constructor", new builtin_function(video_ctor));
351
354
        }
352
355
        return proto.get();
353
356
}
355
358
void
356
359
attachVideoInterface(as_object& o)
357
360
{
358
 
        o.init_member("attachVideo", new builtin_function(video_attach));
359
 
        o.init_member("clear", new builtin_function(video_clear));
 
361
    VM& vm = getVM(o);
 
362
        o.init_member("attachVideo", vm.getNative(667, 1));
 
363
        o.init_member("clear", vm.getNative(667, 2));
360
364
}
361
365
 
362
366
void
363
367
attachPrototypeProperties(as_object& proto)
364
368
{
365
 
    const int protect = as_prop_flags::dontDelete;
 
369
    const int protect = PropFlags::dontDelete;
366
370
    
367
371
    proto.init_property("deblocking", &video_deblocking, &video_deblocking,
368
372
            protect);
369
373
    proto.init_property("smoothing", &video_smoothing, &video_smoothing,
370
374
            protect);
371
375
    
372
 
    const int flags = as_prop_flags::dontDelete |
373
 
        as_prop_flags::readOnly;
 
376
    const int flags = PropFlags::dontDelete |
 
377
        PropFlags::readOnly;
374
378
 
375
379
    proto.init_property("height", &video_height, &video_height, flags);
376
380
    proto.init_property("width", &video_width, &video_width, flags);
382
386
 
383
387
        as_c_function_ptr gettersetter;
384
388
 
385
 
        gettersetter = &character::x_getset;
 
389
        gettersetter = &DisplayObject::x_getset;
386
390
        o.init_property(NSV::PROP_uX, *gettersetter, *gettersetter);
387
391
 
388
 
        gettersetter = &character::y_getset;
 
392
        gettersetter = &DisplayObject::y_getset;
389
393
        o.init_property(NSV::PROP_uY, *gettersetter, *gettersetter);
390
394
 
391
 
        gettersetter = &character::xscale_getset;
 
395
        gettersetter = &DisplayObject::xscale_getset;
392
396
        o.init_property(NSV::PROP_uXSCALE, *gettersetter, *gettersetter);
393
397
 
394
 
        gettersetter = &character::yscale_getset;
 
398
        gettersetter = &DisplayObject::yscale_getset;
395
399
        o.init_property(NSV::PROP_uYSCALE, *gettersetter, *gettersetter);
396
400
 
397
 
        gettersetter = &character::xmouse_get;
 
401
        gettersetter = &DisplayObject::xmouse_get;
398
402
        o.init_readonly_property(NSV::PROP_uXMOUSE, *gettersetter);
399
403
 
400
 
        gettersetter = &character::ymouse_get;
 
404
        gettersetter = &DisplayObject::ymouse_get;
401
405
        o.init_readonly_property(NSV::PROP_uYMOUSE, *gettersetter);
402
406
 
403
 
        gettersetter = &character::alpha_getset;
 
407
        gettersetter = &DisplayObject::alpha_getset;
404
408
        o.init_property(NSV::PROP_uALPHA, *gettersetter, *gettersetter);
405
409
 
406
 
        gettersetter = &character::visible_getset;
 
410
        gettersetter = &DisplayObject::visible_getset;
407
411
        o.init_property(NSV::PROP_uVISIBLE, *gettersetter, *gettersetter);
408
412
 
409
 
        gettersetter = &character::width_getset;
 
413
        gettersetter = &DisplayObject::width_getset;
410
414
        o.init_property(NSV::PROP_uWIDTH, *gettersetter, *gettersetter);
411
415
 
412
 
        gettersetter = &character::height_getset;
 
416
        gettersetter = &DisplayObject::height_getset;
413
417
        o.init_property(NSV::PROP_uHEIGHT, *gettersetter, *gettersetter);
414
418
 
415
 
        gettersetter = &character::rotation_getset;
 
419
        gettersetter = &DisplayObject::rotation_getset;
416
420
        o.init_property(NSV::PROP_uROTATION, *gettersetter, *gettersetter);
417
421
 
418
 
        gettersetter = &character::parent_getset;
 
422
        gettersetter = &DisplayObject::parent_getset;
419
423
        o.init_property(NSV::PROP_uPARENT, *gettersetter, *gettersetter);
420
424
 
421
 
        gettersetter = &character::target_getset;
 
425
        gettersetter = &DisplayObject::target_getset;
422
426
        o.init_property(NSV::PROP_uTARGET, *gettersetter, *gettersetter);
423
427
}
424
428
 
435
439
                return as_value();
436
440
        }
437
441
 
438
 
        boost::intrusive_ptr<NetStream_as> ns = 
439
 
        boost::dynamic_pointer_cast<NetStream_as>(fn.arg(0).to_object());
440
 
        if (ns)
441
 
        {
 
442
    as_object* obj = fn.arg(0).to_object(*getGlobal(fn)).get();
 
443
        NetStream_as* ns;
 
444
 
 
445
    if (isNativeType(obj, ns)) {
442
446
                video->setStream(ns);
443
447
        }
444
 
        else
445
 
        {
 
448
        else {
446
449
                IF_VERBOSE_ASCODING_ERRORS(
447
450
                log_aserror(_("attachVideo(%s) first arg is not a NetStream instance"),
448
451
                        fn.arg(0));
505
508
 
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
511
514
}