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;
15
16#[derive(PartialEq, Eq, Debug, Default, Copy, Clone, Serialize, Deserialize)]
40pub struct VideoOrientationExtension {
41 pub direction: CameraDirection,
42 pub flip: bool,
43 pub rotation: VideoRotation,
44}
45
46#[derive(Default, PartialEq, Eq, Debug, Copy, Clone, Serialize, Deserialize)]
47pub enum CameraDirection {
48 #[default]
49 Front = 0,
50 Back = 1,
51}
52
53#[derive(Default, PartialEq, Eq, Debug, Copy, Clone, Serialize, Deserialize)]
54pub enum VideoRotation {
55 #[default]
56 Degree0 = 0,
57 Degree90 = 1,
58 Degree180 = 2,
59 Degree270 = 3,
60}
61
62impl MarshalSize for VideoOrientationExtension {
63 fn marshal_size(&self) -> usize {
64 VIDEO_ORIENTATION_EXTENSION_SIZE
65 }
66}
67
68impl Unmarshal for VideoOrientationExtension {
69 fn unmarshal<B>(buf: &mut B) -> Result<Self>
70 where
71 Self: Sized,
72 B: bytes::Buf,
73 {
74 if buf.remaining() < VIDEO_ORIENTATION_EXTENSION_SIZE {
75 return Err(Error::ErrBufferTooSmall);
76 }
77
78 let b = buf.get_u8();
79
80 let c = (b & 0b1000) >> 3;
81 let f = b & 0b0100;
82 let r = b & 0b0011;
83
84 Ok(VideoOrientationExtension {
85 direction: c.try_into()?,
86 flip: f > 0,
87 rotation: r.try_into()?,
88 })
89 }
90}
91
92impl Marshal for VideoOrientationExtension {
93 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
94 let c = (self.direction as u8) << 3;
95 let f = if self.flip { 0b0100 } else { 0 };
96 let r = self.rotation as u8;
97
98 buf.put_u8(c | f | r);
99
100 Ok(VIDEO_ORIENTATION_EXTENSION_SIZE)
101 }
102}
103
104impl TryFrom<u8> for CameraDirection {
105 type Error = shared::error::Error;
106
107 fn try_from(value: u8) -> Result<Self> {
108 match value {
109 0 => Ok(CameraDirection::Front),
110 1 => Ok(CameraDirection::Back),
111 _ => Err(shared::error::Error::Other(format!(
112 "Unhandled camera direction: {value}"
113 ))),
114 }
115 }
116}
117
118impl TryFrom<u8> for VideoRotation {
119 type Error = shared::error::Error;
120
121 fn try_from(value: u8) -> Result<Self> {
122 match value {
123 0 => Ok(VideoRotation::Degree0),
124 1 => Ok(VideoRotation::Degree90),
125 2 => Ok(VideoRotation::Degree180),
126 3 => Ok(VideoRotation::Degree270),
127 _ => Err(shared::error::Error::Other(format!(
128 "Unhandled video rotation: {value}"
129 ))),
130 }
131 }
132}