Index: remoting/codec/video_encoder_verbatim.cc |
diff --git a/remoting/codec/video_encoder_verbatim.cc b/remoting/codec/video_encoder_verbatim.cc |
index 4680362a02d20eb75094e2ab7b91ca90d3f6a2a5..656192c9d1fea0eb93ff64f43a8becb093fd97d0 100644 |
--- a/remoting/codec/video_encoder_verbatim.cc |
+++ b/remoting/codec/video_encoder_verbatim.cc |
@@ -6,6 +6,7 @@ |
#include "base/logging.h" |
#include "base/stl_util.h" |
+#include "base/time/time.h" |
#include "remoting/base/util.h" |
#include "remoting/proto/video.pb.h" |
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
@@ -14,119 +15,73 @@ namespace remoting { |
static const int kPacketSize = 1024 * 1024; |
-VideoEncoderVerbatim::VideoEncoderVerbatim() |
- : max_packet_size_(kPacketSize) { |
-} |
+VideoEncoderVerbatim::VideoEncoderVerbatim() {} |
+VideoEncoderVerbatim::~VideoEncoderVerbatim() {} |
-void VideoEncoderVerbatim::SetMaxPacketSize(int size) { |
- max_packet_size_ = size; |
-} |
+scoped_ptr<VideoPacket> VideoEncoderVerbatim::Encode( |
+ const webrtc::DesktopFrame& frame) { |
+ CHECK(frame.data()); |
-VideoEncoderVerbatim::~VideoEncoderVerbatim() { |
-} |
+ base::Time encode_start_time = base::Time::Now(); |
+ scoped_ptr<VideoPacket> packet(new VideoPacket()); |
-void VideoEncoderVerbatim::Encode( |
- const webrtc::DesktopFrame* frame, |
- const DataAvailableCallback& data_available_callback) { |
- callback_ = data_available_callback; |
- encode_start_time_ = base::Time::Now(); |
+ VideoPacketFormat* format = packet->mutable_format(); |
+ format->set_encoding(VideoPacketFormat::ENCODING_VERBATIM); |
+ if (!frame.size().equals(screen_size_)) { |
+ screen_size_ = frame.size(); |
+ format->set_screen_width(screen_size_.width()); |
+ format->set_screen_height(screen_size_.height()); |
+ } |
- webrtc::DesktopRegion::Iterator iter(frame->updated_region()); |
- while (!iter.IsAtEnd()) { |
+ // Calculate output size. |
+ size_t output_size = 0; |
+ for (webrtc::DesktopRegion::Iterator iter(frame.updated_region()); |
+ !iter.IsAtEnd(); iter.Advance()) { |
const webrtc::DesktopRect& rect = iter.rect(); |
- iter.Advance(); |
- EncodeRect(frame, rect, iter.IsAtEnd()); |
+ output_size += rect.width() * rect.height() * |
+ webrtc::DesktopFrame::kBytesPerPixel; |
} |
- callback_.Reset(); |
-} |
- |
-void VideoEncoderVerbatim::EncodeRect(const webrtc::DesktopFrame* frame, |
- const webrtc::DesktopRect& rect, |
- bool last) { |
- CHECK(frame->data()); |
- const int stride = frame->stride(); |
- const int bytes_per_pixel = 4; |
- const int row_size = bytes_per_pixel * rect.width(); |
+ uint8_t* out = GetOutputBuffer(packet.get(), output_size); |
+ const int stride = frame.stride(); |
Wez
2013/09/12 14:20:15
nit: in_stride?
Sergey Ulanov
2013/09/12 19:18:45
Done.
|
- scoped_ptr<VideoPacket> packet(new VideoPacket()); |
- PrepareUpdateStart(frame, rect, packet.get()); |
- const uint8* in = frame->data() + |
- rect.top() * stride + rect.left() * bytes_per_pixel; |
- // TODO(hclam): Fill in the sequence number. |
- uint8* out = GetOutputBuffer(packet.get(), max_packet_size_); |
- int filled = 0; |
- int row_pos = 0; // Position in the current row in bytes. |
- int row_y = 0; // Current row. |
- while (row_y < rect.height()) { |
- // Prepare a message for sending out. |
- if (!packet.get()) { |
- packet.reset(new VideoPacket()); |
- out = GetOutputBuffer(packet.get(), max_packet_size_); |
- filled = 0; |
- } |
- |
- if (row_y < rect.height()) { |
- int bytes_to_copy = |
- std::min(row_size - row_pos, max_packet_size_ - filled); |
- memcpy(out + filled, in + row_pos, bytes_to_copy); |
- row_pos += bytes_to_copy; |
- filled += bytes_to_copy; |
- |
- // Jump to the next row when we've reached the end of the current row. |
- if (row_pos == row_size) { |
- row_pos = 0; |
- in += stride; |
- ++row_y; |
- } |
- } |
- |
- if (row_y == rect.height()) { |
- DCHECK_EQ(row_pos, 0); |
- |
- packet->mutable_data()->resize(filled); |
- packet->set_flags(packet->flags() | VideoPacket::LAST_PACKET); |
- |
- packet->set_capture_time_ms(frame->capture_time_ms()); |
- packet->set_encode_time_ms( |
- (base::Time::Now() - encode_start_time_).InMillisecondsRoundedUp()); |
- if (!frame->dpi().is_zero()) { |
- packet->mutable_format()->set_x_dpi(frame->dpi().x()); |
- packet->mutable_format()->set_y_dpi(frame->dpi().y()); |
- } |
- if (last) |
- packet->set_flags(packet->flags() | VideoPacket::LAST_PARTITION); |
+ // Store all changed rectangles in the packet. |
+ for (webrtc::DesktopRegion::Iterator iter(frame.updated_region()); |
+ !iter.IsAtEnd(); iter.Advance()) { |
+ const webrtc::DesktopRect& rect = iter.rect(); |
+ const int row_size = webrtc::DesktopFrame::kBytesPerPixel * rect.width(); |
Wez
2013/09/12 14:20:15
nit: row_bytes or out_stride?
Sergey Ulanov
2013/09/12 19:18:45
there is no out_stride, because it's not a single
Wez
2013/09/13 11:12:21
Strictly no, but while processing a given rect |ou
|
+ const uint8_t* in = frame.data() + rect.top() * stride + |
+ rect.left() * webrtc::DesktopFrame::kBytesPerPixel; |
+ for (int y = rect.top(); y < rect.top() + rect.height(); ++y) { |
+ memcpy(out, in, row_size); |
+ out += row_size; |
+ in += stride; |
} |
- // If we have filled the current packet, then send it. |
- if (filled == max_packet_size_ || row_y == rect.height()) { |
- packet->mutable_data()->resize(filled); |
- callback_.Run(packet.Pass()); |
- } |
+ Rect* dirty_rect = packet->add_dirty_rects(); |
+ dirty_rect->set_x(rect.left()); |
+ dirty_rect->set_y(rect.top()); |
+ dirty_rect->set_width(rect.width()); |
+ dirty_rect->set_height(rect.height()); |
} |
-} |
-void VideoEncoderVerbatim::PrepareUpdateStart(const webrtc::DesktopFrame* frame, |
- const webrtc::DesktopRect& rect, |
- VideoPacket* packet) { |
- packet->set_flags(packet->flags() | VideoPacket::FIRST_PACKET); |
- |
- VideoPacketFormat* format = packet->mutable_format(); |
- format->set_x(rect.left()); |
- format->set_y(rect.top()); |
- format->set_width(rect.width()); |
- format->set_height(rect.height()); |
- format->set_encoding(VideoPacketFormat::ENCODING_VERBATIM); |
- if (frame->size().equals(screen_size_)) { |
- screen_size_ = frame->size(); |
- format->set_screen_width(screen_size_.width()); |
- format->set_screen_height(screen_size_.height()); |
+ packet->set_flags(VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET); |
+ packet->set_capture_time_ms(frame.capture_time_ms()); |
+ packet->set_encode_time_ms( |
+ (base::Time::Now() - encode_start_time).InMillisecondsRoundedUp()); |
+ if (!frame.dpi().is_zero()) { |
+ packet->mutable_format()->set_x_dpi(frame.dpi().x()); |
+ packet->mutable_format()->set_y_dpi(frame.dpi().y()); |
} |
+ packet->set_flags(packet->flags() | VideoPacket::LAST_PARTITION); |
Wez
2013/09/12 14:20:15
nit: Merge this into the earlier set_flags() call.
Sergey Ulanov
2013/09/12 19:18:45
Done.
|
+ |
+ return packet.Pass(); |
} |
-uint8* VideoEncoderVerbatim::GetOutputBuffer(VideoPacket* packet, size_t size) { |
+uint8_t* VideoEncoderVerbatim::GetOutputBuffer(VideoPacket* packet, |
+ size_t size) { |
packet->mutable_data()->resize(size); |
- return reinterpret_cast<uint8*>(string_as_array(packet->mutable_data())); |
+ return reinterpret_cast<uint8_t*>(string_as_array(packet->mutable_data())); |
} |
} // namespace remoting |