From ff1ed667294455aaae039dc1c9565958ea99110a Mon Sep 17 00:00:00 2001 From: David Wendt Date: Sun, 25 Jun 2023 22:35:24 -0400 Subject: [PATCH] flv: VP6 video packets have a horizontal and vertical adjustment before the actual video data. --- core/src/streams.rs | 11 ++++++++++- flv/src/video.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/core/src/streams.rs b/core/src/streams.rs index 4d74d3bc6..b327322e2 100644 --- a/core/src/streams.rs +++ b/core/src/streams.rs @@ -359,7 +359,16 @@ impl<'gc> NetStream<'gc> { let codec = VideoCodec::from_u8(codec_id as u8); match (video_handle, codec, data) { - (Some(video_handle), Some(codec), FlvVideoPacket::Data(data)) => { + (Some(video_handle), Some(codec), FlvVideoPacket::Data(data)) + | ( + Some(video_handle), + Some(codec), + FlvVideoPacket::Vp6Data { + hadjust: _, + vadjust: _, + data, + }, + ) => { // NOTE: Currently, no implementation of the decoder backend actually requires if tag_needs_preloading { let encoded_frame = EncodedFrame { diff --git a/flv/src/video.rs b/flv/src/video.rs index 216873ade..b3d2490f2 100644 --- a/flv/src/video.rs +++ b/flv/src/video.rs @@ -78,6 +78,11 @@ impl TryFrom for CommandFrame { #[derive(PartialEq, Eq, Debug, Clone)] pub enum VideoPacket<'a> { Data(&'a [u8]), + Vp6Data { + hadjust: u8, + vadjust: u8, + data: &'a [u8], + }, AvcSequenceHeader(&'a [u8]), AvcNalu { composition_time_offset: i32, @@ -122,6 +127,11 @@ impl<'a> VideoData<'a> { (FrameType::CommandFrame, _) => VideoPacket::CommandFrame(CommandFrame::try_from( *data.first().ok_or(Error::ShortVideoBlock)?, )?), + (_, CodecId::On2Vp6) | (_, CodecId::On2Vp6Alpha) => VideoPacket::Vp6Data { + hadjust: data[0] & 0x0F, + vadjust: (data[0] & 0xF0) >> 4, + data: &data[1..], + }, (_, CodecId::Avc) => { let bytes = data.get(1..4).ok_or(Error::ShortVideoBlock)?; let is_negative = bytes[0] & 0x80 != 0; @@ -200,6 +210,44 @@ mod tests { ); } + #[test] + fn read_videodata_vp6() { + let data = [0x14, 0x37, 0x12, 0x34, 0x56, 0x78]; + let mut reader = FlvReader::from_source(&data); + + assert_eq!( + VideoData::parse(&mut reader, data.len() as u32), + Ok(VideoData { + frame_type: FrameType::Keyframe, + codec_id: CodecId::On2Vp6, + data: VideoPacket::Vp6Data { + hadjust: 0x07, + vadjust: 0x03, + data: &[0x12, 0x34, 0x56, 0x78] + } + }) + ); + } + + #[test] + fn read_videodata_vp6alpha() { + let data = [0x15, 0x37, 0x12, 0x34, 0x56, 0x78]; + let mut reader = FlvReader::from_source(&data); + + assert_eq!( + VideoData::parse(&mut reader, data.len() as u32), + Ok(VideoData { + frame_type: FrameType::Keyframe, + codec_id: CodecId::On2Vp6Alpha, + data: VideoPacket::Vp6Data { + hadjust: 0x07, + vadjust: 0x03, + data: &[0x12, 0x34, 0x56, 0x78] + } + }) + ); + } + #[test] fn read_videodata_avcsequence() { let data = [0x17, 0x00, 0x00, 0x50, 0x00, 0x12, 0x34, 0x56, 0x78];