Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/codec/video_encoder_verbatim.h" | 5 #include "remoting/codec/video_encoder_verbatim.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "media/video/capture/screen/screen_capture_data.h" | 8 #include "base/stl_util.h" |
| 9 #include "remoting/base/util.h" | 9 #include "remoting/base/util.h" |
| 10 #include "remoting/proto/video.pb.h" | 10 #include "remoting/proto/video.pb.h" |
| 11 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | |
| 11 | 12 |
| 12 namespace remoting { | 13 namespace remoting { |
| 13 | 14 |
| 14 static const int kPacketSize = 1024 * 1024; | 15 static const int kPacketSize = 1024 * 1024; |
| 15 | 16 |
| 16 VideoEncoderVerbatim::VideoEncoderVerbatim() | 17 VideoEncoderVerbatim::VideoEncoderVerbatim() |
| 17 : screen_size_(SkISize::Make(0,0)), | 18 : screen_size_(0,0), |
|
Wez
2013/04/26 18:48:14
nit: Doesn't DesktopSize initialize itself to 0x0?
Sergey Ulanov
2013/05/07 22:25:50
Done.
| |
| 18 max_packet_size_(kPacketSize) { | 19 max_packet_size_(kPacketSize) { |
| 19 } | 20 } |
| 20 | 21 |
| 21 void VideoEncoderVerbatim::SetMaxPacketSize(int size) { | 22 void VideoEncoderVerbatim::SetMaxPacketSize(int size) { |
| 22 max_packet_size_ = size; | 23 max_packet_size_ = size; |
| 23 } | 24 } |
| 24 | 25 |
| 25 VideoEncoderVerbatim::~VideoEncoderVerbatim() { | 26 VideoEncoderVerbatim::~VideoEncoderVerbatim() { |
| 26 } | 27 } |
| 27 | 28 |
| 28 void VideoEncoderVerbatim::Encode( | 29 void VideoEncoderVerbatim::Encode( |
| 29 scoped_refptr<media::ScreenCaptureData> capture_data, | 30 webrtc::DesktopFrame* frame, |
| 30 bool key_frame, | |
| 31 const DataAvailableCallback& data_available_callback) { | 31 const DataAvailableCallback& data_available_callback) { |
| 32 capture_data_ = capture_data; | |
| 33 callback_ = data_available_callback; | 32 callback_ = data_available_callback; |
| 34 encode_start_time_ = base::Time::Now(); | 33 encode_start_time_ = base::Time::Now(); |
| 35 | 34 |
| 36 const SkRegion& region = capture_data->dirty_region(); | 35 webrtc::DesktopRegion::Iterator iter(frame->updated_region()); |
| 37 SkRegion::Iterator iter(region); | 36 while (!iter.IsAtEnd()) { |
| 38 while (!iter.done()) { | 37 const webrtc::DesktopRect& rect = iter.rect(); |
| 39 SkIRect rect = iter.rect(); | 38 iter.Advance(); |
| 40 iter.next(); | 39 EncodeRect(frame, rect, iter.IsAtEnd()); |
| 41 EncodeRect(rect, iter.done()); | |
| 42 } | 40 } |
| 43 | 41 |
| 44 capture_data_ = NULL; | |
| 45 callback_.Reset(); | 42 callback_.Reset(); |
| 46 } | 43 } |
| 47 | 44 |
| 48 void VideoEncoderVerbatim::EncodeRect(const SkIRect& rect, bool last) { | 45 void VideoEncoderVerbatim::EncodeRect(webrtc::DesktopFrame* frame, |
| 49 CHECK(capture_data_->data()); | 46 const webrtc::DesktopRect& rect, |
| 50 const int stride = capture_data_->stride(); | 47 bool last) { |
| 48 CHECK(frame->data()); | |
| 49 const int stride = frame->stride(); | |
| 51 const int bytes_per_pixel = 4; | 50 const int bytes_per_pixel = 4; |
| 52 const int row_size = bytes_per_pixel * rect.width(); | 51 const int row_size = bytes_per_pixel * rect.width(); |
| 53 | 52 |
| 54 scoped_ptr<VideoPacket> packet(new VideoPacket()); | 53 scoped_ptr<VideoPacket> packet(new VideoPacket()); |
| 55 PrepareUpdateStart(rect, packet.get()); | 54 PrepareUpdateStart(frame, rect, packet.get()); |
| 56 const uint8* in = capture_data_->data() + | 55 const uint8* in = frame->data() + |
| 57 rect.fTop * stride + rect.fLeft * bytes_per_pixel; | 56 rect.top() * stride + rect.left() * bytes_per_pixel; |
| 58 // TODO(hclam): Fill in the sequence number. | 57 // TODO(hclam): Fill in the sequence number. |
| 59 uint8* out = GetOutputBuffer(packet.get(), max_packet_size_); | 58 uint8* out = GetOutputBuffer(packet.get(), max_packet_size_); |
| 60 int filled = 0; | 59 int filled = 0; |
| 61 int row_pos = 0; // Position in the current row in bytes. | 60 int row_pos = 0; // Position in the current row in bytes. |
| 62 int row_y = 0; // Current row. | 61 int row_y = 0; // Current row. |
| 63 while (row_y < rect.height()) { | 62 while (row_y < rect.height()) { |
| 64 // Prepare a message for sending out. | 63 // Prepare a message for sending out. |
| 65 if (!packet.get()) { | 64 if (!packet.get()) { |
| 66 packet.reset(new VideoPacket()); | 65 packet.reset(new VideoPacket()); |
| 67 out = GetOutputBuffer(packet.get(), max_packet_size_); | 66 out = GetOutputBuffer(packet.get(), max_packet_size_); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 81 in += stride; | 80 in += stride; |
| 82 ++row_y; | 81 ++row_y; |
| 83 } | 82 } |
| 84 } | 83 } |
| 85 | 84 |
| 86 if (row_y == rect.height()) { | 85 if (row_y == rect.height()) { |
| 87 DCHECK_EQ(row_pos, 0); | 86 DCHECK_EQ(row_pos, 0); |
| 88 | 87 |
| 89 packet->mutable_data()->resize(filled); | 88 packet->mutable_data()->resize(filled); |
| 90 packet->set_flags(packet->flags() | VideoPacket::LAST_PACKET); | 89 packet->set_flags(packet->flags() | VideoPacket::LAST_PACKET); |
| 91 packet->set_capture_time_ms(capture_data_->capture_time_ms()); | 90 |
| 91 packet->set_capture_time_ms(frame->capture_time_ms()); | |
| 92 packet->set_encode_time_ms( | 92 packet->set_encode_time_ms( |
| 93 (base::Time::Now() - encode_start_time_).InMillisecondsRoundedUp()); | 93 (base::Time::Now() - encode_start_time_).InMillisecondsRoundedUp()); |
| 94 packet->set_client_sequence_number( | 94 if (!frame->dpi().is_zero()) { |
| 95 capture_data_->client_sequence_number()); | 95 packet->mutable_format()->set_x_dpi(frame->dpi().x()); |
| 96 SkIPoint dpi(capture_data_->dpi()); | 96 packet->mutable_format()->set_y_dpi(frame->dpi().y()); |
| 97 if (dpi.x()) | 97 } |
| 98 packet->mutable_format()->set_x_dpi(dpi.x()); | |
| 99 if (dpi.y()) | |
| 100 packet->mutable_format()->set_y_dpi(dpi.y()); | |
| 101 if (last) | 98 if (last) |
| 102 packet->set_flags(packet->flags() | VideoPacket::LAST_PARTITION); | 99 packet->set_flags(packet->flags() | VideoPacket::LAST_PARTITION); |
| 103 } | 100 } |
| 104 | 101 |
| 105 // If we have filled the current packet, then send it. | 102 // If we have filled the current packet, then send it. |
| 106 if (filled == max_packet_size_ || row_y == rect.height()) { | 103 if (filled == max_packet_size_ || row_y == rect.height()) { |
| 107 packet->mutable_data()->resize(filled); | 104 packet->mutable_data()->resize(filled); |
| 108 callback_.Run(packet.Pass()); | 105 callback_.Run(packet.Pass()); |
| 109 } | 106 } |
| 110 } | 107 } |
| 111 } | 108 } |
| 112 | 109 |
| 113 void VideoEncoderVerbatim::PrepareUpdateStart(const SkIRect& rect, | 110 void VideoEncoderVerbatim::PrepareUpdateStart(webrtc::DesktopFrame* frame, |
| 111 const webrtc::DesktopRect& rect, | |
| 114 VideoPacket* packet) { | 112 VideoPacket* packet) { |
| 115 packet->set_flags(packet->flags() | VideoPacket::FIRST_PACKET); | 113 packet->set_flags(packet->flags() | VideoPacket::FIRST_PACKET); |
| 116 | 114 |
| 117 VideoPacketFormat* format = packet->mutable_format(); | 115 VideoPacketFormat* format = packet->mutable_format(); |
| 118 format->set_x(rect.fLeft); | 116 format->set_x(rect.left()); |
| 119 format->set_y(rect.fTop); | 117 format->set_y(rect.top()); |
| 120 format->set_width(rect.width()); | 118 format->set_width(rect.width()); |
| 121 format->set_height(rect.height()); | 119 format->set_height(rect.height()); |
| 122 format->set_encoding(VideoPacketFormat::ENCODING_VERBATIM); | 120 format->set_encoding(VideoPacketFormat::ENCODING_VERBATIM); |
| 123 if (capture_data_->size() != screen_size_) { | 121 if (frame->size().equals(screen_size_)) { |
| 124 screen_size_ = capture_data_->size(); | 122 screen_size_ = frame->size(); |
| 125 format->set_screen_width(screen_size_.width()); | 123 format->set_screen_width(screen_size_.width()); |
| 126 format->set_screen_height(screen_size_.height()); | 124 format->set_screen_height(screen_size_.height()); |
| 127 } | 125 } |
| 128 } | 126 } |
| 129 | 127 |
| 130 uint8* VideoEncoderVerbatim::GetOutputBuffer(VideoPacket* packet, size_t size) { | 128 uint8* VideoEncoderVerbatim::GetOutputBuffer(VideoPacket* packet, size_t size) { |
| 131 packet->mutable_data()->resize(size); | 129 packet->mutable_data()->resize(size); |
| 132 // TODO(ajwong): Is there a better way to do this at all??? | 130 return reinterpret_cast<uint8*>(string_as_array(packet->mutable_data())); |
| 133 return const_cast<uint8*>(reinterpret_cast<const uint8*>( | |
| 134 packet->mutable_data()->data())); | |
| 135 } | 131 } |
| 136 | 132 |
| 137 } // namespace remoting | 133 } // namespace remoting |
| OLD | NEW |