blob: da16444a7acec26b8435ac016ed975820b01bcfc (
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/protocol/rtp_video_writer.h"
#include "base/task.h"
#include "net/base/io_buffer.h"
#include "remoting/base/compound_buffer.h"
#include "remoting/proto/video.pb.h"
#include "remoting/protocol/rtp_writer.h"
#include "remoting/protocol/session.h"
namespace remoting {
namespace protocol {
namespace {
const int kMtu = 1200;
} // namespace
RtpVideoWriter::RtpVideoWriter() { }
RtpVideoWriter::~RtpVideoWriter() { }
void RtpVideoWriter::Init(protocol::Session* session) {
rtp_writer_.Init(session->video_rtp_channel());
}
void RtpVideoWriter::ProcessVideoPacket(const VideoPacket* packet, Task* done) {
CHECK(packet->format().encoding() == VideoPacketFormat::ENCODING_VP8)
<< "Only VP8 is supported in RTP.";
CompoundBuffer payload;
// TODO(sergeyu): This copy would not be necessary CompoundBuffer was used
// inside of VideoPacket.
payload.AppendCopyOf(packet->data().data(), packet->data().size());
Vp8Descriptor vp8_desriptor;
// TODO(sergeyu): Add a flag in VideoPacket that indicates whether this is a
// key frame or not.
vp8_desriptor.non_reference_frame = false;
vp8_desriptor.picture_id = kuint32max;
int position = 0;
while (position < payload.total_bytes()) {
int size = std::min(kMtu, payload.total_bytes() - position);
// Frame beginning flag is set only for the first packet in the first
// partition.
vp8_desriptor.frame_beginning =
(packet->flags() & VideoPacket::FIRST_PACKET) != 0 && position == 0;
// Marker bit is set only for the last packet in the last partition.
bool marker = (position + size) == payload.total_bytes() &&
(packet->flags() & VideoPacket::LAST_PACKET) != 0;
// Set fragmentation flag appropriately.
if (position == 0) {
if (size == payload.total_bytes()) {
vp8_desriptor.fragmentation_info = Vp8Descriptor::NOT_FRAGMENTED;
} else {
vp8_desriptor.fragmentation_info = Vp8Descriptor::FIRST_FRAGMENT;
}
} else {
if (position + size == payload.total_bytes()) {
vp8_desriptor.fragmentation_info = Vp8Descriptor::LAST_FRAGMENT;
} else {
vp8_desriptor.fragmentation_info = Vp8Descriptor::MIDDLE_FRAGMENT;
}
}
// Create CompoundBuffer for the chunk.
CompoundBuffer chunk;
chunk.CopyFrom(payload, position, position + size);
// And send it.
rtp_writer_.SendPacket(packet->timestamp(), marker, vp8_desriptor, chunk);
position += size;
}
DCHECK_EQ(position, payload.total_bytes());
done->Run();
delete done;
}
int RtpVideoWriter::GetPendingPackets() {
return rtp_writer_.GetPendingPackets();
}
} // namespace protocol
} // namespace remoting
|