rtc_rtp/extension/video_orientation_extension/
mod.rs1#[cfg(test)]
2mod video_orientation_extension_test;
3
4use std::convert::{TryFrom, TryInto};
5
6use bytes::BufMut;
7use serde::{Deserialize, Serialize};
8use shared::{
9 error::{Error, Result},
10 marshal::{Marshal, MarshalSize, Unmarshal},
11};
12
13pub const VIDEO_ORIENTATION_EXTENSION_SIZE: usize = 1;
16
17#[derive(PartialEq, Eq, Debug, Default, Copy, Clone, Serialize, Deserialize)]
41pub struct VideoOrientationExtension {
42 pub direction: CameraDirection,
44 pub flip: bool,
46 pub rotation: VideoRotation,
48}
49
50#[derive(Default, PartialEq, Eq, Debug, Copy, Clone, Serialize, Deserialize)]
51pub enum CameraDirection {
53 #[default]
54 Front = 0,
56 Back = 1,
58}
59
60#[derive(Default, PartialEq, Eq, Debug, Copy, Clone, Serialize, Deserialize)]
61pub enum VideoRotation {
63 #[default]
64 Degree0 = 0,
66 Degree90 = 1,
68 Degree180 = 2,
70 Degree270 = 3,
72}
73
74impl MarshalSize for VideoOrientationExtension {
75 fn marshal_size(&self) -> usize {
76 VIDEO_ORIENTATION_EXTENSION_SIZE
77 }
78}
79
80impl Unmarshal for VideoOrientationExtension {
81 fn unmarshal<B>(buf: &mut B) -> Result<Self>
82 where
83 Self: Sized,
84 B: bytes::Buf,
85 {
86 if buf.remaining() < VIDEO_ORIENTATION_EXTENSION_SIZE {
87 return Err(Error::ErrBufferTooSmall);
88 }
89
90 let b = buf.get_u8();
91
92 let c = (b & 0b1000) >> 3;
93 let f = b & 0b0100;
94 let r = b & 0b0011;
95
96 Ok(VideoOrientationExtension {
97 direction: c.try_into()?,
98 flip: f > 0,
99 rotation: r.try_into()?,
100 })
101 }
102}
103
104impl Marshal for VideoOrientationExtension {
105 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
106 let c = (self.direction as u8) << 3;
107 let f = if self.flip { 0b0100 } else { 0 };
108 let r = self.rotation as u8;
109
110 buf.put_u8(c | f | r);
111
112 Ok(VIDEO_ORIENTATION_EXTENSION_SIZE)
113 }
114}
115
116impl TryFrom<u8> for CameraDirection {
117 type Error = shared::error::Error;
118
119 fn try_from(value: u8) -> Result<Self> {
120 match value {
121 0 => Ok(CameraDirection::Front),
122 1 => Ok(CameraDirection::Back),
123 _ => Err(shared::error::Error::Other(format!(
124 "Unhandled camera direction: {value}"
125 ))),
126 }
127 }
128}
129
130impl TryFrom<u8> for VideoRotation {
131 type Error = shared::error::Error;
132
133 fn try_from(value: u8) -> Result<Self> {
134 match value {
135 0 => Ok(VideoRotation::Degree0),
136 1 => Ok(VideoRotation::Degree90),
137 2 => Ok(VideoRotation::Degree180),
138 3 => Ok(VideoRotation::Degree270),
139 _ => Err(shared::error::Error::Other(format!(
140 "Unhandled video rotation: {value}"
141 ))),
142 }
143 }
144}