1
+ #ifndef RTC_VP8_NAL_UNIT_H
2
+ #define RTC_VP8_NAL_UNIT_H
3
+
4
+ #if RTC_ENABLE_MEDIA
5
+
6
+ #include " common.hpp"
7
+ #include " nalunit.hpp"
8
+ #include < cassert>
9
+ #include < cstdint>
10
+ #include < vector>
11
+
12
+ /*
13
+ * Example “VP8NalUnit” derived from your base NalUnit class, mirroring
14
+ * how "H265NalUnit" is done. In VP8, there is no true NAL unit concept,
15
+ * but we can still parse the "VP8 payload descriptor" (RFC 7741 sec. 4.2)
16
+ * from the front of the data, and store or retrieve key bits.
17
+ *
18
+ * IMPORTANT: We avoid calling NalUnit(std::move(data), Type) since
19
+ * NalUnit has no such two-argument constructor. Instead, we do
20
+ * NalUnit(std::move(data)) just like your H265 code.
21
+ */
22
+
23
+ namespace rtc {
24
+
25
+ #pragma pack(push, 1)
26
+
27
+ // The mandatory first byte of the VP8 payload descriptor.
28
+ // (RFC 7741, Section 4.2)
29
+ struct VP8PayloadDescriptorFirstByte {
30
+ uint8_t raw = 0 ;
31
+
32
+ bool hasExtension () const { return (raw & 0x80 ) != 0 ; } // X
33
+ bool isNonReference () const { return (raw & 0x20 ) != 0 ; } // N
34
+ bool isStartOfPartition () const { return (raw & 0x10 ) != 0 ; } // S
35
+ uint8_t partitionIndex () const { return (raw & 0x07 ); } // PID
36
+
37
+ void setHasExtension (bool val) {
38
+ if (val) raw |= (1 << 7 );
39
+ else raw &= ~(1 << 7 );
40
+ }
41
+ void setNonReference (bool val) {
42
+ if (val) raw |= (1 << 5 );
43
+ else raw &= ~(1 << 5 );
44
+ }
45
+ void setStartOfPartition (bool val) {
46
+ if (val) raw |= (1 << 4 );
47
+ else raw &= ~(1 << 4 );
48
+ }
49
+ void setPartitionIndex (uint8_t pid) {
50
+ raw = (raw & 0xF8 ) | (pid & 0x07 );
51
+ }
52
+ };
53
+
54
+ // Optional extension byte if the X bit = 1.
55
+ struct VP8PayloadDescriptorExtensionByte {
56
+ uint8_t raw = 0 ;
57
+
58
+ bool hasPictureID () const { return (raw & 0x80 ) != 0 ; } // I
59
+ bool hasTL0PICIDX () const { return (raw & 0x40 ) != 0 ; } // L
60
+ bool hasTID () const { return (raw & 0x20 ) != 0 ; } // T
61
+ bool hasKEYIDX () const { return (raw & 0x10 ) != 0 ; } // K
62
+ };
63
+
64
+ #pragma pack(pop)
65
+
66
+ // “VP8NalUnit” extends NalUnit but is really a container for one VP8 frame
67
+ // (or partial frame) plus its RTP "payload descriptor" bits.
68
+ struct VP8NalUnit : public NalUnit {
69
+ public:
70
+ // Match your H265NalUnit style:
71
+ VP8NalUnit () : NalUnit(NalUnit::Type::VP8) {}
72
+ VP8NalUnit (size_t size, bool includingHeader = true )
73
+ : NalUnit(size, includingHeader, NalUnit::Type::VP8) {}
74
+ VP8NalUnit (binary &&data)
75
+ : NalUnit(std::move(data)) {} // call NalUnit(binary && data)
76
+ VP8NalUnit (const VP8NalUnit&) = default ;
77
+
78
+ // Parse the VP8 payload descriptor from the beginning of data().
79
+ // Returns how many bytes of descriptor were consumed.
80
+ size_t parseDescriptor ();
81
+
82
+ // The actual VP8 bitstream data after the descriptor.
83
+ binary payload () const ;
84
+
85
+ // If this frame is a keyframe or not (based on the "P" bit in the
86
+ // first 3 bytes of the actual VP8 payload when partitionIndex=0).
87
+ bool isKeyFrame () const { return mIsKeyFrame ; }
88
+
89
+ // The “S bit” in the first descriptor byte.
90
+ bool isStartOfPartition () const { return mFirstByte .isStartOfPartition (); }
91
+
92
+ VP8PayloadDescriptorFirstByte mFirstByte {0 };
93
+
94
+ // PictureID if present in the extension. (RFC 7741 Section 4.2)
95
+ uint16_t pictureID () const { return mPictureID ; }
96
+
97
+ // For demonstration, generating multiple “fragments” from a large frame
98
+ // simulating the style of H.265 FU logic, though not standardized for VP8:
99
+ static std::vector<binary> GenerateFragments (const std::vector<VP8NalUnit> &units,
100
+ size_t maxFragmentSize);
101
+ std::vector<VP8NalUnit> generateFragments (size_t maxFragmentSize) const ;
102
+
103
+ private:
104
+ bool mHasExtension = false ;
105
+ VP8PayloadDescriptorExtensionByte mExtByte {0 };
106
+
107
+ bool mHasPictureID = false ;
108
+ uint16_t mPictureID = 0 ;
109
+ bool mIsKeyFrame = false ; // if “P=0” in the first-byte of actual VP8 data
110
+
111
+ // Implementation detail: parse out extension fields if X=1, etc.
112
+ };
113
+
114
+ } // namespace rtc
115
+
116
+ #endif /* RTC_ENABLE_MEDIA */
117
+
118
+ #endif /* RTC_VP8_NAL_UNIT_H */
0 commit comments