1 /**********
2 This library is free software; you can redistribute it and/or modify it under
3 the terms of the GNU Lesser General Public License as published by the
4 Free Software Foundation; either version 3 of the License, or (at your
5 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6 
7 This library is distributed in the hope that it will be useful, but WITHOUT
8 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
10 more details.
11 
12 You should have received a copy of the GNU Lesser General Public License
13 along with this library; if not, write to the Free Software Foundation, Inc.,
14 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
15 **********/
16 // "liveMedia"
17 // Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
18 // VP9 Video RTP Sources
19 // Implementation
20 
21 #include "VP9VideoRTPSource.hh"
22 
23 VP9VideoRTPSource*
createNew(UsageEnvironment & env,Groupsock * RTPgs,unsigned char rtpPayloadFormat,unsigned rtpTimestampFrequency)24 VP9VideoRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs,
25 			      unsigned char rtpPayloadFormat,
26 			      unsigned rtpTimestampFrequency) {
27   return new VP9VideoRTPSource(env, RTPgs, rtpPayloadFormat,
28 			       rtpTimestampFrequency);
29 }
30 
31 VP9VideoRTPSource
VP9VideoRTPSource(UsageEnvironment & env,Groupsock * RTPgs,unsigned char rtpPayloadFormat,unsigned rtpTimestampFrequency)32 ::VP9VideoRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
33 		     unsigned char rtpPayloadFormat,
34 		     unsigned rtpTimestampFrequency)
35   : MultiFramedRTPSource(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency) {
36 }
37 
~VP9VideoRTPSource()38 VP9VideoRTPSource::~VP9VideoRTPSource() {
39 }
40 
41 #define incrHeader do { ++resultSpecialHeaderSize; ++headerStart; if (--packetSize == 0) return False; } while (0)
42 
43 Boolean VP9VideoRTPSource
processSpecialHeader(BufferedPacket * packet,unsigned & resultSpecialHeaderSize)44 ::processSpecialHeader(BufferedPacket* packet,
45                        unsigned& resultSpecialHeaderSize) {
46   unsigned char* headerStart = packet->data();
47   unsigned packetSize = packet->dataSize();
48 
49   // Figure out the size of the special header.
50   if (packetSize == 0) return False; // error
51   resultSpecialHeaderSize = 1; // unless we learn otherwise
52 
53   u_int8_t const byte1 = *headerStart;
54   Boolean const I = (byte1&0x80) != 0;
55   Boolean const L = (byte1&0x40) != 0;
56   Boolean const F = (byte1&0x20) != 0;
57   Boolean const B = (byte1&0x10) != 0;
58   Boolean const E = (byte1&0x08) != 0;
59   Boolean const V = (byte1&0x04) != 0;
60   Boolean const U = (byte1&0x02) != 0;
61 
62   fCurrentPacketBeginsFrame = B;
63   fCurrentPacketCompletesFrame = E;
64       // use this instead of the RTP header's 'M' bit (which might not be accurate)
65 
66   if (I) { // PictureID present
67     incrHeader;
68     Boolean const M = ((*headerStart)&0x80) != 0;
69     if (M) incrHeader;
70   }
71 
72   if (L) { // Layer indices present
73     incrHeader;
74     if (F) { // Reference indices present
75       incrHeader;
76       unsigned R = (*headerStart)&0x03;
77       while (R-- > 0) {
78 	incrHeader;
79 	Boolean const X = ((*headerStart)&0x10) != 0;
80 	if (X) incrHeader;
81       }
82     }
83   }
84 
85   if (V) { // Scalability Structure (SS) present
86     incrHeader;
87     unsigned patternLength = *headerStart;
88     while (patternLength-- > 0) {
89       incrHeader;
90       unsigned R = (*headerStart)&0x03;
91       while (R-- > 0) {
92 	incrHeader;
93 	Boolean const X = ((*headerStart)&0x10) != 0;
94 	if (X) incrHeader;
95       }
96     }
97   }
98 
99   if (U) { // Scalability Structure Update (SU) present
100     return False; // This structure isn't yet defined in the VP9 payload format I-D
101   }
102 
103   return True;
104 }
105 
MIMEtype() const106 char const* VP9VideoRTPSource::MIMEtype() const {
107   return "video/VP9";
108 }
109