summaryrefslogtreecommitdiffstats
blob: b88e21712cb3a0f6909d6c50a4c3cfc65ac55455 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
 * Copyright (c) 2012 Yoann Blein
 * Licensed under the simplified BSD license.
 * See Documentation/Licenses/BSD-simplified.txt for more information.
 */

#include <Swiften/ScreenSharing/VP8RTPPacketizer.h>

namespace Swift {

VP8RTPPacketizer::VP8RTPPacketizer()
{
}

void VP8RTPPacketizer::packetizeFrame(const vpx_codec_cx_pkt_t* pkt)
{
	if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
		return;

	// only case there is no partitions is handle (TODO: implement partitions)
	if (pkt->data.frame.partition_id != -1)
		return;

	size_t size = pkt->data.frame.sz;
	uint8_t* buf = static_cast<uint8_t*>(pkt->data.frame.buf);
	size_t sent = 0;
	bool firstPacket = true;

	while (sent < size) {
		payloadBuffer.clear();

		// Payload descriptor
		uint8_t req = 0;
		if (firstPacket)
			req |= SBit;
		payloadBuffer.push_back(req);

		// Payload header
		if (firstPacket) {
			firstPacket = false;

			uint8_t o1 = (size & Size0BitMask) << Size0BitShift; // Size0
			o1 |= HBit; // H (show frame)
			if (!(pkt->data.frame.flags & VPX_FRAME_IS_KEY))
				o1 |= 1; // P (Inverse key frame)
			payloadBuffer.push_back(o1);
			payloadBuffer.push_back(static_cast<uint8_t>(size >> 3)); // Size1
			payloadBuffer.push_back(static_cast<uint8_t>(size >> 11)); // Size2
		}

		// Payload content
		size_t toSend = std::min(size - sent, MaxRTPPayloadSize - payloadBuffer.size());
		payloadBuffer.insert(payloadBuffer.end(), buf, buf + toSend);

		sent += toSend;
		buf += toSend;

		// Mark rtp packet if last of the curr frame
		bool lastPacket = (sent >= size);

		// TODO: send packet
		//parser.newPayloadReceived(&payloadBuffer[0], payloadBuffer.size(), lastPacket);
		onNewPayloadReady(payloadBuffer, lastPacket);
	}
}

}