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/base/encoder_zlib.h" | 5 #include "remoting/base/encoder_zlib.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "gfx/rect.h" | 8 #include "gfx/rect.h" |
9 #include "media/base/data_buffer.h" | 9 #include "media/base/data_buffer.h" |
10 #include "remoting/base/capture_data.h" | 10 #include "remoting/base/capture_data.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 callback_.reset(); | 42 callback_.reset(); |
43 } | 43 } |
44 | 44 |
45 void EncoderZlib::EncodeRect(CompressorZlib* compressor, | 45 void EncoderZlib::EncodeRect(CompressorZlib* compressor, |
46 const gfx::Rect& rect, size_t rect_index) { | 46 const gfx::Rect& rect, size_t rect_index) { |
47 CHECK(capture_data_->data_planes().data[0]); | 47 CHECK(capture_data_->data_planes().data[0]); |
48 const int strides = capture_data_->data_planes().strides[0]; | 48 const int strides = capture_data_->data_planes().strides[0]; |
49 const int bytes_per_pixel = GetBytesPerPixel(capture_data_->pixel_format()); | 49 const int bytes_per_pixel = GetBytesPerPixel(capture_data_->pixel_format()); |
50 const int row_size = bytes_per_pixel * rect.width(); | 50 const int row_size = bytes_per_pixel * rect.width(); |
51 | 51 |
52 ChromotingHostMessage* message = PrepareMessage(&rect); | 52 ChromotingHostMessage* message = new ChromotingHostMessage(); |
53 const uint8 * in = capture_data_->data_planes().data[0] + | 53 RectangleUpdatePacket* update = message->mutable_rectangle_update(); |
54 rect.y() * strides + | 54 PrepareUpdateStart(rect, update); |
55 rect.x() * bytes_per_pixel; | 55 const uint8* in = capture_data_->data_planes().data[0] + |
| 56 rect.y() * strides + |
| 57 rect.x() * bytes_per_pixel; |
56 // TODO(hclam): Fill in the sequence number. | 58 // TODO(hclam): Fill in the sequence number. |
57 uint8* out = (uint8*)message->mutable_update_stream_packet()-> | 59 uint8* out = GetOutputBuffer(update, packet_size_); |
58 mutable_rect_data()->mutable_data()->data(); | |
59 int filled = 0; | 60 int filled = 0; |
60 int row_x = 0; | 61 int row_x = 0; |
61 int row_y = 0; | 62 int row_y = 0; |
62 bool compress_again = true; | 63 bool compress_again = true; |
63 while (compress_again) { | 64 while (compress_again) { |
64 // Prepare a message for sending out. | 65 // Prepare a message for sending out. |
65 if (!message) { | 66 if (!message) { |
66 message = PrepareMessage(NULL); | 67 message = new ChromotingHostMessage(); |
67 out = (uint8*)(message->mutable_update_stream_packet()-> | 68 update = message->mutable_rectangle_update(); |
68 mutable_rect_data()->mutable_data()->data()); | 69 out = GetOutputBuffer(update, packet_size_); |
69 filled = 0; | 70 filled = 0; |
70 } | 71 } |
71 | 72 |
72 Compressor::CompressorFlush flush = Compressor::CompressorNoFlush; | 73 Compressor::CompressorFlush flush = Compressor::CompressorNoFlush; |
73 if (row_y == rect.height() - 1) { | 74 if (row_y == rect.height() - 1) { |
74 if (rect_index == capture_data_->dirty_rects().size() - 1) { | 75 if (rect_index == capture_data_->dirty_rects().size() - 1) { |
75 flush = Compressor::CompressorFinish; | 76 flush = Compressor::CompressorFinish; |
76 } else { | 77 } else { |
77 flush = Compressor::CompressorSyncFlush; | 78 flush = Compressor::CompressorSyncFlush; |
78 } | 79 } |
79 } | 80 } |
80 | 81 |
81 int consumed = 0; | 82 int consumed = 0; |
82 int written = 0; | 83 int written = 0; |
83 compress_again = compressor->Process(in + row_x, row_size - row_x, | 84 compress_again = compressor->Process(in + row_x, row_size - row_x, |
84 out + filled, packet_size_ - filled, | 85 out + filled, packet_size_ - filled, |
85 flush, &consumed, &written); | 86 flush, &consumed, &written); |
86 row_x += consumed; | 87 row_x += consumed; |
87 filled += written; | 88 filled += written; |
88 | 89 |
89 // We have reached the end of stream. | 90 // We have reached the end of stream. |
90 if (!compress_again) { | 91 if (!compress_again) { |
91 message->mutable_update_stream_packet()->mutable_end_rect(); | 92 update->set_flags(update->flags() | RectangleUpdatePacket::LAST_PACKET); |
92 } | 93 } |
93 | 94 |
94 // If we have filled the message or we have reached the end of stream. | 95 // If we have filled the message or we have reached the end of stream. |
95 if (filled == packet_size_ || !compress_again) { | 96 if (filled == packet_size_ || !compress_again) { |
96 message->mutable_update_stream_packet()->mutable_rect_data()-> | 97 message->mutable_rectangle_update()->mutable_encoded_rect()-> |
97 mutable_data()->resize(filled); | 98 resize(filled); |
98 SubmitMessage(message, rect_index); | 99 SubmitMessage(message, rect_index); |
99 message = NULL; | 100 message = NULL; |
100 } | 101 } |
101 | 102 |
102 // Reached the end of input row and we're not at the last row. | 103 // Reached the end of input row and we're not at the last row. |
103 if (row_x == row_size && row_y < rect.height() - 1) { | 104 if (row_x == row_size && row_y < rect.height() - 1) { |
104 row_x = 0; | 105 row_x = 0; |
105 in += strides; | 106 in += strides; |
106 ++row_y; | 107 ++row_y; |
107 } | 108 } |
108 } | 109 } |
109 } | 110 } |
110 | 111 |
111 ChromotingHostMessage* EncoderZlib::PrepareMessage(const gfx::Rect* rect) { | 112 void EncoderZlib::PrepareUpdateStart(const gfx::Rect& rect, |
112 ChromotingHostMessage* message = new ChromotingHostMessage(); | 113 RectangleUpdatePacket* update) { |
113 UpdateStreamPacketMessage* packet = message->mutable_update_stream_packet(); | |
114 | 114 |
115 // Prepare the begin rect content. | 115 update->set_flags(update->flags() | RectangleUpdatePacket::FIRST_PACKET); |
116 if (rect != NULL) { | 116 RectangleFormat* format = update->mutable_format(); |
117 packet->mutable_begin_rect()->set_x(rect->x()); | |
118 packet->mutable_begin_rect()->set_y(rect->y()); | |
119 packet->mutable_begin_rect()->set_width(rect->width()); | |
120 packet->mutable_begin_rect()->set_height(rect->height()); | |
121 packet->mutable_begin_rect()->set_encoding(EncodingZlib); | |
122 packet->mutable_begin_rect()->set_pixel_format( | |
123 capture_data_->pixel_format()); | |
124 } | |
125 | 117 |
126 packet->mutable_rect_data()->mutable_data()->resize(packet_size_); | 118 format->set_x(rect.x()); |
127 return message; | 119 format->set_y(rect.y()); |
| 120 format->set_width(rect.width()); |
| 121 format->set_height(rect.height()); |
| 122 format->set_encoding(EncodingZlib); |
| 123 format->set_pixel_format(capture_data_->pixel_format()); |
| 124 } |
| 125 |
| 126 uint8* EncoderZlib::GetOutputBuffer(RectangleUpdatePacket* update, |
| 127 size_t size) { |
| 128 update->mutable_encoded_rect()->resize(size); |
| 129 // TODO(ajwong): Is there a better way to do this at all??? |
| 130 return const_cast<uint8*>(reinterpret_cast<const uint8*>( |
| 131 update->mutable_encoded_rect()->data())); |
128 } | 132 } |
129 | 133 |
130 void EncoderZlib::SubmitMessage(ChromotingHostMessage* message, | 134 void EncoderZlib::SubmitMessage(ChromotingHostMessage* message, |
131 size_t rect_index) { | 135 size_t rect_index) { |
132 EncodingState state = EncodingInProgress; | 136 EncodingState state = EncodingInProgress; |
133 if (rect_index == 0 && message->update_stream_packet().has_begin_rect()) | 137 const RectangleUpdatePacket& update = message->rectangle_update(); |
| 138 if (rect_index == 0 && |
| 139 (update.flags() | RectangleUpdatePacket::FIRST_PACKET)) { |
134 state |= EncodingStarting; | 140 state |= EncodingStarting; |
| 141 } |
135 if (rect_index == capture_data_->dirty_rects().size() - 1 && | 142 if (rect_index == capture_data_->dirty_rects().size() - 1 && |
136 message->update_stream_packet().has_end_rect()) | 143 (update.flags() | RectangleUpdatePacket::LAST_PACKET)) { |
137 state |= EncodingEnded; | 144 state |= EncodingEnded; |
| 145 } |
138 callback_->Run(message, state); | 146 callback_->Run(message, state); |
139 } | 147 } |
140 | 148 |
141 } // namespace remoting | 149 } // namespace remoting |
OLD | NEW |