avm1: Stub impl the `Video` class.

This commit is contained in:
David Wendt 2021-01-04 21:57:06 -05:00 committed by Mike Welsh
parent 828ff39802
commit aa98fad126
3 changed files with 72 additions and 6 deletions

View File

@ -55,6 +55,7 @@ pub(crate) mod system_security;
pub(crate) mod text_field;
mod text_format;
mod transform;
mod video;
mod xml;
pub fn random<'gc>(
@ -506,6 +507,8 @@ pub struct SystemPrototypes<'gc> {
pub date: Object<'gc>,
pub bitmap_data: Object<'gc>,
pub bitmap_data_constructor: Object<'gc>,
pub video: Object<'gc>,
pub video_constructor: Object<'gc>,
}
/// Initialize default global scope and builtins for an AVM1 instance.
@ -582,6 +585,8 @@ pub fn create_globals<'gc>(
);
let date_proto: Object<'gc> = date::create_proto(gc_context, object_proto, function_proto);
let video_proto: Object<'gc> = video::create_proto(gc_context, object_proto, function_proto);
//TODO: These need to be constructors and should also set `.prototype` on each one
let object = object::create_object_object(gc_context, object_proto, function_proto);
@ -697,6 +702,12 @@ pub fn create_globals<'gc>(
Some(function_proto),
transform_proto,
);
let video = FunctionObject::constructor(
gc_context,
Executable::Native(video::constructor),
Some(function_proto),
video_proto,
);
flash.define_value(gc_context, "geom", geom.into(), Attribute::empty());
flash.define_value(gc_context, "filters", filters.into(), Attribute::empty());
@ -1255,6 +1266,8 @@ pub fn create_globals<'gc>(
date: date_proto,
bitmap_data: bitmap_data_proto,
bitmap_data_constructor: bitmap_data,
video: video_proto,
video_constructor: video,
},
globals.into(),
broadcaster_functions,

View File

@ -0,0 +1,30 @@
//! Video class
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::globals::display_object;
use crate::avm1::object::Object;
use crate::avm1::value::Value;
use crate::avm1::ScriptObject;
use gc_arena::MutationContext;
/// Implements `Video`
pub fn constructor<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
_this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
Ok(Value::Undefined)
}
pub fn create_proto<'gc>(
gc_context: MutationContext<'gc, '_>,
proto: Object<'gc>,
fn_proto: Object<'gc>,
) -> Object<'gc> {
let object = ScriptObject::object(gc_context, Some(proto));
display_object::define_display_object_proto(gc_context, object, fn_proto);
object.into()
}

View File

@ -1,6 +1,6 @@
//! Video player display object
use crate::avm1::Object as Avm1Object;
use crate::avm1::{Object as Avm1Object, StageObject as Avm1StageObject};
use crate::backend::render::BitmapHandle;
use crate::backend::video::{EncodedFrame, VideoStreamHandle};
use crate::bounding_box::BoundingBox;
@ -10,7 +10,7 @@ use crate::display_object::{DisplayObjectBase, TDisplayObject};
use crate::prelude::*;
use crate::tag_utils::{SwfMovie, SwfSlice};
use crate::types::{Degrees, Percent};
use crate::vminterface::Instantiator;
use crate::vminterface::{AvmObject, AvmType, Instantiator};
use gc_arena::{Collect, GcCell, MutationContext};
use std::borrow::{Borrow, BorrowMut};
use std::collections::BTreeMap;
@ -40,6 +40,9 @@ pub struct VideoData<'gc> {
/// The last decoded frame in the video stream.
decoded_frame: Option<CollectWrapper<BitmapHandle>>,
/// AVM representation of this video player.
object: Option<AvmObject<'gc>>,
}
#[derive(Clone, Debug, Collect)]
@ -83,6 +86,7 @@ impl<'gc> Video<'gc> {
source,
stream: None,
decoded_frame: None,
object: None,
},
))
}
@ -176,15 +180,17 @@ impl<'gc> TDisplayObject<'gc> for Video<'gc> {
fn post_instantiation(
&self,
context: &mut UpdateContext<'_, 'gc, '_>,
_display_object: DisplayObject<'gc>,
display_object: DisplayObject<'gc>,
_init_object: Option<Avm1Object<'gc>>,
_instantiated_by: Instantiator,
run_frame: bool,
) {
let mut write = self.0.write(context.gc_context);
let stream = match &*write.source.read() {
VideoSource::SWF { streamdef, .. } => {
let (stream, movie) = match &*write.source.read() {
VideoSource::SWF {
streamdef, movie, ..
} => {
let stream = context.video.register_video_stream(
streamdef.num_frames.into(),
(streamdef.width, streamdef.height),
@ -199,11 +205,28 @@ impl<'gc> TDisplayObject<'gc> for Video<'gc> {
return;
}
Some(CollectWrapper(stream.unwrap()))
(Some(CollectWrapper(stream.unwrap())), movie.clone())
}
};
write.stream = stream;
if write.object.is_none() {
let library = context.library.library_for_movie_mut(movie);
let vm_type = library.avm_type();
if vm_type == AvmType::Avm2 {
//TODO: AVM2 me, cap'n.
} else if vm_type == AvmType::Avm1 {
let object: Avm1Object<'_> = Avm1StageObject::for_display_object(
context.gc_context,
display_object,
Some(context.avm1.prototypes().video),
)
.into();
write.object = Some(object.into());
}
}
drop(write);
self.seek(context, 0);