1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// H.263+ Video RTP Sources
19// Implementation
20
21#include "H263plusVideoRTPSource.hh"
22
23H263plusVideoRTPSource*
24H263plusVideoRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs,
25 unsigned char rtpPayloadFormat,
26 unsigned rtpTimestampFrequency) {
27 return new H263plusVideoRTPSource(env, RTPgs, rtpPayloadFormat,
28 rtpTimestampFrequency);
29}
30
31H263plusVideoRTPSource
32::H263plusVideoRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
33 unsigned char rtpPayloadFormat,
34 unsigned rtpTimestampFrequency)
35 : MultiFramedRTPSource(env, RTPgs,
36 rtpPayloadFormat, rtpTimestampFrequency),
37 fNumSpecialHeaders(0), fSpecialHeaderBytesLength(0) {
38}
39
40H263plusVideoRTPSource::~H263plusVideoRTPSource() {
41}
42
43Boolean H263plusVideoRTPSource
44::processSpecialHeader(BufferedPacket* packet,
45 unsigned& resultSpecialHeaderSize) {
46 unsigned char* headerStart = packet->data();
47 unsigned packetSize = packet->dataSize();
48
49 // The H.263+ payload header is at least 2 bytes in size.
50 // Extract the known fields from the first 2 bytes:
51 unsigned expectedHeaderSize = 2;
52 if (packetSize < expectedHeaderSize) return False;
53
54 //unsigned char RR = headerStart[0]>>3;
55 Boolean P = (headerStart[0]&0x4) != 0;
56 Boolean V = (headerStart[0]&0x2) != 0;
57 unsigned char PLEN = ((headerStart[0]&0x1)<<5)|(headerStart[1]>>3);
58 //unsigned char PEBIT = headerStart[1]&0x7;
59
60 if (V) {
61 // There's an extra VRC byte at the end of the header:
62 ++expectedHeaderSize;
63 if (packetSize < expectedHeaderSize) return False;
64 }
65
66 if (PLEN > 0) {
67 // There's an extra picture header at the end:
68 expectedHeaderSize += PLEN;
69 if (packetSize < expectedHeaderSize) return False;
70 }
71
72 fCurrentPacketBeginsFrame = P;
73 if (fCurrentPacketBeginsFrame) {
74 fNumSpecialHeaders = fSpecialHeaderBytesLength = 0;
75 }
76
77 // Make a copy of the special header bytes, in case a reader
78 // can use them:
79 unsigned bytesAvailable
80 = SPECIAL_HEADER_BUFFER_SIZE - fSpecialHeaderBytesLength - 1;
81 if (expectedHeaderSize <= bytesAvailable) {
82 fSpecialHeaderBytes[fSpecialHeaderBytesLength++] = expectedHeaderSize;
83 for (unsigned i = 0; i < expectedHeaderSize; ++i) {
84 fSpecialHeaderBytes[fSpecialHeaderBytesLength++] = headerStart[i];
85 }
86 fPacketSizes[fNumSpecialHeaders++] = packetSize;
87 }
88
89 if (P) {
90 // Prepend two zero bytes to the start of the payload proper.
91 // Hack: Do this by shrinking this special header by 2 bytes:
92 expectedHeaderSize -= 2;
93 headerStart[expectedHeaderSize] = 0;
94 headerStart[expectedHeaderSize+1] = 0;
95 }
96
97 // The RTP "M" (marker) bit indicates the last fragment of a frame:
98 fCurrentPacketCompletesFrame = packet->rtpMarkerBit();
99
100 resultSpecialHeaderSize = expectedHeaderSize;
101 return True;
102}
103
104char const* H263plusVideoRTPSource::MIMEtype() const {
105 return "video/H263-1998";
106}
107