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 // MPEG-1 or MPEG-2 Video RTP Sources
19 // Implementation
20 
21 #include "MPEG1or2VideoRTPSource.hh"
22 
23 MPEG1or2VideoRTPSource*
createNew(UsageEnvironment & env,Groupsock * RTPgs,unsigned char rtpPayloadFormat,unsigned rtpTimestampFrequency)24 MPEG1or2VideoRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs,
25 			      unsigned char rtpPayloadFormat,
26 			      unsigned rtpTimestampFrequency) {
27   return new MPEG1or2VideoRTPSource(env, RTPgs, rtpPayloadFormat,
28 				rtpTimestampFrequency);
29 }
30 
MPEG1or2VideoRTPSource(UsageEnvironment & env,Groupsock * RTPgs,unsigned char rtpPayloadFormat,unsigned rtpTimestampFrequency)31 MPEG1or2VideoRTPSource::MPEG1or2VideoRTPSource(UsageEnvironment& env,
32 				       Groupsock* RTPgs,
33 				       unsigned char rtpPayloadFormat,
34 				       unsigned rtpTimestampFrequency)
35   : MultiFramedRTPSource(env, RTPgs,
36 			 rtpPayloadFormat, rtpTimestampFrequency){
37 }
38 
~MPEG1or2VideoRTPSource()39 MPEG1or2VideoRTPSource::~MPEG1or2VideoRTPSource() {
40 }
41 
42 Boolean MPEG1or2VideoRTPSource
processSpecialHeader(BufferedPacket * packet,unsigned & resultSpecialHeaderSize)43 ::processSpecialHeader(BufferedPacket* packet,
44 		       unsigned& resultSpecialHeaderSize) {
45   // There's a 4-byte video-specific header
46   if (packet->dataSize() < 4) return False;
47 
48   u_int32_t header = ntohl(*(u_int32_t*)(packet->data()));
49 
50   u_int32_t sBit = header&0x00002000; // sequence-header-present
51   u_int32_t bBit = header&0x00001000; // beginning-of-slice
52   u_int32_t eBit = header&0x00000800; // end-of-slice
53 
54   fCurrentPacketBeginsFrame = (sBit|bBit) != 0;
55   fCurrentPacketCompletesFrame = ((sBit != 0) && (bBit == 0)) || (eBit != 0);
56 
57   resultSpecialHeaderSize = 4;
58   return True;
59 }
60 
61 Boolean MPEG1or2VideoRTPSource
packetIsUsableInJitterCalculation(unsigned char * packet,unsigned packetSize)62 ::packetIsUsableInJitterCalculation(unsigned char* packet,
63 				    unsigned packetSize) {
64   // There's a 4-byte video-specific header
65   if (packetSize < 4) return False;
66 
67   // Extract the "Picture-Type" field from this, to determine whether
68   // this packet can be used in jitter calculations:
69   unsigned header = ntohl(*(u_int32_t*)packet);
70 
71   unsigned short pictureType = (header>>8)&0x7;
72   if (pictureType == 1) { // an I frame
73     return True;
74   } else { // a P, B, D, or other unknown frame type
75     return False;
76   }
77 }
78 
MIMEtype() const79 char const* MPEG1or2VideoRTPSource::MIMEtype() const {
80   return "video/MPEG";
81 }
82 
83