flv: VP6 video packets have a horizontal and vertical adjustment before the actual video data.

This commit is contained in:
David Wendt 2023-06-25 22:35:24 -04:00 committed by kmeisthax
parent 98ee78be1a
commit ff1ed66729
2 changed files with 58 additions and 1 deletions

View File

@ -359,7 +359,16 @@ impl<'gc> NetStream<'gc> {
let codec = VideoCodec::from_u8(codec_id as u8); let codec = VideoCodec::from_u8(codec_id as u8);
match (video_handle, codec, data) { 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 // NOTE: Currently, no implementation of the decoder backend actually requires
if tag_needs_preloading { if tag_needs_preloading {
let encoded_frame = EncodedFrame { let encoded_frame = EncodedFrame {

View File

@ -78,6 +78,11 @@ impl TryFrom<u8> for CommandFrame {
#[derive(PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
pub enum VideoPacket<'a> { pub enum VideoPacket<'a> {
Data(&'a [u8]), Data(&'a [u8]),
Vp6Data {
hadjust: u8,
vadjust: u8,
data: &'a [u8],
},
AvcSequenceHeader(&'a [u8]), AvcSequenceHeader(&'a [u8]),
AvcNalu { AvcNalu {
composition_time_offset: i32, composition_time_offset: i32,
@ -122,6 +127,11 @@ impl<'a> VideoData<'a> {
(FrameType::CommandFrame, _) => VideoPacket::CommandFrame(CommandFrame::try_from( (FrameType::CommandFrame, _) => VideoPacket::CommandFrame(CommandFrame::try_from(
*data.first().ok_or(Error::ShortVideoBlock)?, *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) => { (_, CodecId::Avc) => {
let bytes = data.get(1..4).ok_or(Error::ShortVideoBlock)?; let bytes = data.get(1..4).ok_or(Error::ShortVideoBlock)?;
let is_negative = bytes[0] & 0x80 != 0; 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] #[test]
fn read_videodata_avcsequence() { fn read_videodata_avcsequence() {
let data = [0x17, 0x00, 0x00, 0x50, 0x00, 0x12, 0x34, 0x56, 0x78]; let data = [0x17, 0x00, 0x00, 0x50, 0x00, 0x12, 0x34, 0x56, 0x78];