OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/rtp_video_writer.h" | 5 #include "remoting/protocol/rtp_video_writer.h" |
6 | 6 |
7 #include "net/base/io_buffer.h" | 7 #include "net/base/io_buffer.h" |
8 #include "remoting/base/compound_buffer.h" | 8 #include "remoting/base/compound_buffer.h" |
9 #include "remoting/proto/video.pb.h" | 9 #include "remoting/proto/video.pb.h" |
10 #include "remoting/protocol/rtp_writer.h" | 10 #include "remoting/protocol/rtp_writer.h" |
11 #include "remoting/protocol/session.h" | 11 #include "remoting/protocol/session.h" |
12 | 12 |
13 namespace remoting { | 13 namespace remoting { |
14 namespace protocol { | 14 namespace protocol { |
15 | 15 |
| 16 namespace { |
| 17 const int kMtu = 1200; |
| 18 } // namespace |
| 19 |
16 RtpVideoWriter::RtpVideoWriter() { } | 20 RtpVideoWriter::RtpVideoWriter() { } |
17 | 21 |
18 RtpVideoWriter::~RtpVideoWriter() { } | 22 RtpVideoWriter::~RtpVideoWriter() { } |
19 | 23 |
20 void RtpVideoWriter::Init(protocol::Session* session) { | 24 void RtpVideoWriter::Init(protocol::Session* session) { |
21 rtp_writer_.Init(session->video_rtp_channel(), session->video_rtcp_channel()); | 25 rtp_writer_.Init(session->video_rtp_channel(), session->video_rtcp_channel()); |
22 } | 26 } |
23 | 27 |
24 void RtpVideoWriter::SendPacket(const VideoPacket& packet) { | 28 void RtpVideoWriter::SendPacket(const VideoPacket& packet) { |
| 29 CHECK(packet.format().encoding() == VideoPacketFormat::ENCODING_VP8) |
| 30 << "Only VP8 is supported in RTP."; |
| 31 |
25 CompoundBuffer payload; | 32 CompoundBuffer payload; |
| 33 // TODO(sergeyu): This copy would not be necessary CompoundBuffer was used |
| 34 // inside of VideoPacket. |
26 payload.AppendCopyOf(packet.data().data(), packet.data().size()); | 35 payload.AppendCopyOf(packet.data().data(), packet.data().size()); |
27 | 36 |
28 rtp_writer_.SendPacket(payload, packet.timestamp()); | 37 Vp8Descriptor vp8_desriptor; |
| 38 // TODO(sergeyu): Add a flag in VideoPacket that indicates whether this is a |
| 39 // key frame or not. |
| 40 vp8_desriptor.non_reference_frame = false; |
| 41 vp8_desriptor.picture_id = kuint32max; |
| 42 |
| 43 int position = 0; |
| 44 while (position < payload.total_bytes()) { |
| 45 int size = std::min(kMtu, payload.total_bytes() - position); |
| 46 |
| 47 // Frame beginning flag is set only for the first packet in the first |
| 48 // partition. |
| 49 vp8_desriptor.frame_beginning = |
| 50 (packet.flags() & VideoPacket::FIRST_PACKET) != 0 && position == 0; |
| 51 |
| 52 // Marker bit is set only for the last packet in the last partition. |
| 53 bool marker = (position + size) == payload.total_bytes() && |
| 54 (packet.flags() & VideoPacket::LAST_PACKET) != 0; |
| 55 |
| 56 // Set fragmentation flag appropriately. |
| 57 if (position == 0) { |
| 58 if (size == payload.total_bytes()) { |
| 59 vp8_desriptor.fragmentation_info = Vp8Descriptor::NOT_FRAGMENTED; |
| 60 } else { |
| 61 vp8_desriptor.fragmentation_info = Vp8Descriptor::FIRST_FRAGMENT; |
| 62 } |
| 63 } else { |
| 64 if (position + size == payload.total_bytes()) { |
| 65 vp8_desriptor.fragmentation_info = Vp8Descriptor::LAST_FRAGMENT; |
| 66 } else { |
| 67 vp8_desriptor.fragmentation_info = Vp8Descriptor::MIDDLE_FRAGMENT; |
| 68 } |
| 69 } |
| 70 |
| 71 // Create CompoundBuffer for the chunk. |
| 72 CompoundBuffer chunk; |
| 73 chunk.CopyFrom(payload, position, position + size); |
| 74 |
| 75 // And send it. |
| 76 rtp_writer_.SendPacket(packet.timestamp(), marker, vp8_desriptor, chunk); |
| 77 |
| 78 position += size; |
| 79 } |
| 80 |
| 81 DCHECK_EQ(position, payload.total_bytes()); |
29 } | 82 } |
30 | 83 |
31 int RtpVideoWriter::GetPendingPackets() { | 84 int RtpVideoWriter::GetPendingPackets() { |
32 return rtp_writer_.GetPendingPackets(); | 85 return rtp_writer_.GetPendingPackets(); |
33 } | 86 } |
34 | 87 |
35 | |
36 void RtpVideoWriter::Close() { | 88 void RtpVideoWriter::Close() { |
37 rtp_writer_.Close(); | 89 rtp_writer_.Close(); |
38 } | 90 } |
39 | 91 |
40 } // namespace protocol | 92 } // namespace protocol |
41 } // namespace remoting | 93 } // namespace remoting |
OLD | NEW |