core: `VideoStream` should not hold the last decoded frame as this data structure is shared across multiple instances of the same character
This commit is contained in:
parent
7eb7f2ee2c
commit
b2544618ab
|
@ -70,6 +70,12 @@ pub struct VideoData<'gc> {
|
||||||
|
|
||||||
/// The self bounds for this movie.
|
/// The self bounds for this movie.
|
||||||
size: (i32, i32),
|
size: (i32, i32),
|
||||||
|
|
||||||
|
/// The last decoded frame in the video stream.
|
||||||
|
///
|
||||||
|
/// NOTE: This is only used for SWF-source video streams.
|
||||||
|
#[collect(require_static)]
|
||||||
|
decoded_frame: Option<(u32, BitmapInfo)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An optionally-instantiated video stream.
|
/// An optionally-instantiated video stream.
|
||||||
|
@ -100,10 +106,6 @@ pub enum VideoSource<'gc> {
|
||||||
/// Each frame consists of a start and end parameter which can be used
|
/// Each frame consists of a start and end parameter which can be used
|
||||||
/// to reconstruct a reference to the embedded bitstream.
|
/// to reconstruct a reference to the embedded bitstream.
|
||||||
frames: BTreeMap<u32, (usize, usize)>,
|
frames: BTreeMap<u32, (usize, usize)>,
|
||||||
|
|
||||||
/// The last decoded frame in the video stream.
|
|
||||||
#[collect(require_static)]
|
|
||||||
decoded_frame: Option<(u32, BitmapInfo)>,
|
|
||||||
},
|
},
|
||||||
/// An attached NetStream.
|
/// An attached NetStream.
|
||||||
NetStream {
|
NetStream {
|
||||||
|
@ -126,7 +128,6 @@ impl<'gc> Video<'gc> {
|
||||||
VideoSource::Swf {
|
VideoSource::Swf {
|
||||||
streamdef,
|
streamdef,
|
||||||
frames: BTreeMap::new(),
|
frames: BTreeMap::new(),
|
||||||
decoded_frame: None,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -140,6 +141,7 @@ impl<'gc> Video<'gc> {
|
||||||
keyframes: BTreeSet::new(),
|
keyframes: BTreeSet::new(),
|
||||||
movie,
|
movie,
|
||||||
size,
|
size,
|
||||||
|
decoded_frame: None,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -163,6 +165,7 @@ impl<'gc> Video<'gc> {
|
||||||
keyframes: BTreeSet::new(),
|
keyframes: BTreeSet::new(),
|
||||||
movie,
|
movie,
|
||||||
size: (width, height),
|
size: (width, height),
|
||||||
|
decoded_frame: None,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -236,12 +239,11 @@ impl<'gc> Video<'gc> {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let (num_frames, decoded_frame) = match &*read.source.read() {
|
let num_frames = match &*read.source.read() {
|
||||||
VideoSource::Swf {
|
VideoSource::Swf {
|
||||||
streamdef,
|
streamdef,
|
||||||
decoded_frame,
|
|
||||||
..
|
..
|
||||||
} => (streamdef.num_frames as usize, decoded_frame.clone()),
|
} => streamdef.num_frames as usize,
|
||||||
VideoSource::NetStream { .. } => return,
|
VideoSource::NetStream { .. } => return,
|
||||||
VideoSource::Unconnected { .. } => return,
|
VideoSource::Unconnected { .. } => return,
|
||||||
};
|
};
|
||||||
|
@ -252,7 +254,7 @@ impl<'gc> Video<'gc> {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
let last_frame = decoded_frame.as_ref().map(|(lf, _)| *lf);
|
let last_frame = read.decoded_frame.as_ref().map(|(lf, _)| *lf);
|
||||||
|
|
||||||
if last_frame == Some(frame_id) {
|
if last_frame == Some(frame_id) {
|
||||||
return; // we are already there, no-op
|
return; // we are already there, no-op
|
||||||
|
@ -314,7 +316,6 @@ impl<'gc> Video<'gc> {
|
||||||
VideoSource::Swf {
|
VideoSource::Swf {
|
||||||
streamdef,
|
streamdef,
|
||||||
frames,
|
frames,
|
||||||
decoded_frame,
|
|
||||||
} => match frames.get(&frame_id) {
|
} => match frames.get(&frame_id) {
|
||||||
Some((slice_start, slice_end)) => {
|
Some((slice_start, slice_end)) => {
|
||||||
let encframe = EncodedFrame {
|
let encframe = EncodedFrame {
|
||||||
|
@ -327,8 +328,8 @@ impl<'gc> Video<'gc> {
|
||||||
.decode_video_stream_frame(*stream, encframe, context.renderer)
|
.decode_video_stream_frame(*stream, encframe, context.renderer)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if let Some((_old_id, old_frame)) = decoded_frame {
|
if let Some((_old_id, old_frame)) = read.decoded_frame.clone() {
|
||||||
Ok(old_frame.clone())
|
Ok(old_frame)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::SeekingBeforeDecoding(frame_id))
|
Err(Error::SeekingBeforeDecoding(frame_id))
|
||||||
}
|
}
|
||||||
|
@ -341,11 +342,7 @@ impl<'gc> Video<'gc> {
|
||||||
drop(read);
|
drop(read);
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(bitmap) => match &mut *source.write(context.gc_context) {
|
Ok(bitmap) => self.0.write(context.gc_context).decoded_frame = Some((frame_id, bitmap)),
|
||||||
VideoSource::Swf { decoded_frame, .. } => *decoded_frame = Some((frame_id, bitmap)),
|
|
||||||
VideoSource::NetStream { .. } => unreachable!(),
|
|
||||||
VideoSource::Unconnected { .. } => unreachable!(),
|
|
||||||
},
|
|
||||||
Err(e) => tracing::error!("Got error when seeking to video frame {}: {}", frame_id, e),
|
Err(e) => tracing::error!("Got error when seeking to video frame {}: {}", frame_id, e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,12 +530,11 @@ impl<'gc> TDisplayObject<'gc> for Video<'gc> {
|
||||||
VideoSource::Swf {
|
VideoSource::Swf {
|
||||||
streamdef,
|
streamdef,
|
||||||
frames,
|
frames,
|
||||||
decoded_frame,
|
|
||||||
} => (
|
} => (
|
||||||
streamdef.is_smoothed,
|
streamdef.is_smoothed,
|
||||||
Some(frames.len()),
|
Some(frames.len()),
|
||||||
read.movie.version(),
|
read.movie.version(),
|
||||||
decoded_frame.clone().map(|df| df.1),
|
read.decoded_frame.clone().map(|df| df.1),
|
||||||
Some(streamdef.codec),
|
Some(streamdef.codec),
|
||||||
),
|
),
|
||||||
VideoSource::NetStream { stream, .. } => (
|
VideoSource::NetStream { stream, .. } => (
|
||||||
|
|
Loading…
Reference in New Issue