@@ -14,13 +14,6 @@ const EX_HEADER_BIT: u8 = 0b10000000;
1414pub enum FlvVideoData {
1515 Legacy ( VideoTag ) ,
1616 Enhanced ( EnhancedVideoTag ) ,
17- /// Enhanced RTMP command frame (e.g. seek start/end).
18- /// Sent when `VideoFrameType == Command` and packet type is not Metadata.
19- /// Per the spec, the payload is a single UI8 command byte with no video body.
20- EnhancedCommand {
21- command : VideoCommand ,
22- timestamp_nano_offset : Option < u32 > ,
23- } ,
2417}
2518
2619/// Video command signals for Enhanced RTMP.
@@ -50,9 +43,21 @@ impl VideoCommand {
5043#[ derive( Debug , Clone ) ]
5144pub struct EnhancedVideoTag {
5245 pub frame_type : VideoTagFrameType ,
53- pub four_cc : VideoFourCc ,
5446 pub timestamp_nano_offset : Option < u32 > ,
55- pub packet_type : VideoPacketType ,
47+ pub body : EnhancedVideoBody ,
48+ }
49+
50+ /// The body of an Enhanced RTMP video tag.
51+ ///
52+ /// Command frames (gated by `VideoFrameType == Command`) have no FourCC or
53+ /// video body. All other cases carry a FourCC and a `VideoPacketType`.
54+ #[ derive( Debug , Clone ) ]
55+ pub enum EnhancedVideoBody {
56+ Command ( VideoCommand ) ,
57+ Packet {
58+ four_cc : VideoFourCc ,
59+ packet_type : VideoPacketType ,
60+ } ,
5661}
5762
5863/// Semantic video packet type after parsing.
@@ -196,7 +201,7 @@ impl FlvVideoData {
196201 }
197202
198203 if data[ 0 ] & EX_HEADER_BIT != 0 {
199- EnhancedVideoTag :: parse ( data)
204+ EnhancedVideoTag :: parse ( data) . map ( FlvVideoData :: Enhanced )
200205 } else {
201206 VideoTag :: parse ( data) . map ( FlvVideoData :: Legacy )
202207 }
@@ -206,17 +211,14 @@ impl FlvVideoData {
206211 match self {
207212 FlvVideoData :: Legacy ( tag) => tag. serialize ( ) ,
208213 FlvVideoData :: Enhanced ( tag) => tag. serialize ( ) ,
209- FlvVideoData :: EnhancedCommand { .. } => {
210- unimplemented ! ( )
211- }
212214 }
213215 }
214216}
215217
216218impl EnhancedVideoTag {
217219 /// Parses Enhanced RTMP video tag.
218220 /// First byte: `[isExHeader(1) | VideoFrameType(3 bits) | RawVideoPacketType(4 bits)]`
219- fn parse ( data : Bytes ) -> Result < FlvVideoData , FlvVideoTagParseError > {
221+ fn parse ( data : Bytes ) -> Result < Self , FlvVideoTagParseError > {
220222 if data. is_empty ( ) {
221223 return Err ( FlvVideoTagParseError :: TooShort ) ;
222224 }
@@ -233,17 +235,18 @@ impl EnhancedVideoTag {
233235 } ;
234236
235237 // Per spec: if frame_type is Command and packet_type is not Metadata,
236- // the payload is a single UI8 VideoCommand with no video body.
238+ // the payload is a single UI8 VideoCommand with no FourCC or video body.
237239 if frame_type == VideoTagFrameType :: VideoInfoOrCommandFrame
238240 && raw_packet_type != RawVideoPacketType :: Metadata
239241 {
240242 if rest. is_empty ( ) {
241243 return Err ( FlvVideoTagParseError :: TooShort ) ;
242244 }
243245 let command = VideoCommand :: from_raw ( rest[ 0 ] ) ?;
244- return Ok ( FlvVideoData :: EnhancedCommand {
245- command ,
246+ return Ok ( EnhancedVideoTag {
247+ frame_type ,
246248 timestamp_nano_offset,
249+ body : EnhancedVideoBody :: Command ( command) ,
247250 } ) ;
248251 }
249252
@@ -277,12 +280,14 @@ impl EnhancedVideoTag {
277280 }
278281 } ;
279282
280- Ok ( FlvVideoData :: Enhanced ( EnhancedVideoTag {
283+ Ok ( EnhancedVideoTag {
281284 frame_type,
282- four_cc,
283285 timestamp_nano_offset,
284- packet_type,
285- } ) )
286+ body : EnhancedVideoBody :: Packet {
287+ four_cc,
288+ packet_type,
289+ } ,
290+ } )
286291 }
287292
288293 /// Parses CodedFrames body: optional SI24 composition time (3 bytes) + payload.
@@ -330,7 +335,6 @@ impl EnhancedVideoTag {
330335 let mut mod_ex_data_size = data[ offset] as usize + 1 ;
331336 offset += 1 ;
332337
333- // If size == 256, use UI16 + 1 instead
334338 if mod_ex_data_size == 256 {
335339 if data. len ( ) < offset + 2 {
336340 return Err ( FlvVideoTagParseError :: TooShort ) ;
@@ -369,7 +373,6 @@ impl EnhancedVideoTag {
369373 }
370374 }
371375
372- // If another ModEx, continue the loop; otherwise return resolved state.
373376 if next_packet_type != RawVideoPacketType :: ModEx {
374377 return Ok ( (
375378 next_packet_type,
0 commit comments