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// Theora Video RTP Sources
19// Implementation
20
21#include "TheoraVideoRTPSource.hh"
22
23////////// TheoraBufferedPacket and TheoraBufferedPacketFactory //////////
24
25class TheoraBufferedPacket: public BufferedPacket {
26public:
27 TheoraBufferedPacket();
28 virtual ~TheoraBufferedPacket();
29
30private: // redefined virtual functions
31 virtual unsigned nextEnclosedFrameSize(unsigned char*& framePtr,
32 unsigned dataSize);
33};
34
35class TheoraBufferedPacketFactory: public BufferedPacketFactory {
36private: // redefined virtual functions
37 virtual BufferedPacket* createNewPacket(MultiFramedRTPSource* ourSource);
38};
39
40
41///////// TheoraVideoRTPSource implementation ////////
42
43TheoraVideoRTPSource*
44TheoraVideoRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs,
45 unsigned char rtpPayloadFormat) {
46 return new TheoraVideoRTPSource(env, RTPgs, rtpPayloadFormat);
47}
48
49TheoraVideoRTPSource
50::TheoraVideoRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
51 unsigned char rtpPayloadFormat)
52 : MultiFramedRTPSource(env, RTPgs, rtpPayloadFormat, 90000,
53 new TheoraBufferedPacketFactory),
54 fCurPacketIdent(0) {
55}
56
57TheoraVideoRTPSource::~TheoraVideoRTPSource() {
58}
59
60Boolean TheoraVideoRTPSource
61::processSpecialHeader(BufferedPacket* packet,
62 unsigned& resultSpecialHeaderSize) {
63 unsigned char* headerStart = packet->data();
64 unsigned packetSize = packet->dataSize();
65
66 resultSpecialHeaderSize = 4;
67 if (packetSize < resultSpecialHeaderSize) return False; // packet was too small
68
69 // The first 3 bytes of the header are the "Ident" field:
70 fCurPacketIdent = (headerStart[0]<<16) | (headerStart[1]<<8) | headerStart[2];
71
72 // The 4th byte is F|TDT|numPkts.
73 // Reject any packet with TDT == 3:
74 if ((headerStart[3]&0x30) == 0x30) return False;
75
76 u_int8_t F = headerStart[3]>>6;
77 fCurrentPacketBeginsFrame = F <= 1; // "Not Fragmented" or "Start Fragment"
78 fCurrentPacketCompletesFrame = F == 0 || F == 3; // "Not Fragmented" or "End Fragment"
79
80 return True;
81}
82
83char const* TheoraVideoRTPSource::MIMEtype() const {
84 return "video/THEORA";
85}
86
87
88////////// TheoraBufferedPacket and TheoraBufferedPacketFactory implementation //////////
89
90TheoraBufferedPacket::TheoraBufferedPacket() {
91}
92
93TheoraBufferedPacket::~TheoraBufferedPacket() {
94}
95
96unsigned TheoraBufferedPacket
97::nextEnclosedFrameSize(unsigned char*& framePtr, unsigned dataSize) {
98 if (dataSize < 2) {
99 // There's not enough space for a 2-byte header. TARFU! Just return the data that's left:
100 return dataSize;
101 }
102
103 unsigned frameSize = (framePtr[0]<<8) | framePtr[1];
104 framePtr += 2;
105 if (frameSize > dataSize - 2) return dataSize - 2; // inconsistent frame size => just return all the data that's left
106
107 return frameSize;
108}
109
110BufferedPacket* TheoraBufferedPacketFactory
111::createNewPacket(MultiFramedRTPSource* /*ourSource*/) {
112 return new TheoraBufferedPacket();
113}
114