| 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 |