| OLD | NEW | 
| (Empty) |  | 
 |    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 | 
 |    3 // found in the LICENSE file. | 
 |    4  | 
 |    5 #include "remoting/base/encoder_zlib.h" | 
 |    6  | 
 |    7 #include "gfx/rect.h" | 
 |    8 #include "media/base/data_buffer.h" | 
 |    9 #include "remoting/base/capture_data.h" | 
 |   10 #include "remoting/base/compressor_zlib.h" | 
 |   11 #include "remoting/base/protocol_util.h" | 
 |   12 #include "remoting/base/protocol/chromotocol.pb.h" | 
 |   13  | 
 |   14 namespace remoting { | 
 |   15  | 
 |   16 static const int kPacketSize = 1024 * 1024; | 
 |   17  | 
 |   18 EncoderZlib::EncoderZlib() : packet_size_(kPacketSize) { | 
 |   19 } | 
 |   20  | 
 |   21 EncoderZlib::EncoderZlib(int packet_size) : packet_size_(packet_size) { | 
 |   22 } | 
 |   23  | 
 |   24 void EncoderZlib::Encode(scoped_refptr<CaptureData> capture_data, | 
 |   25                          bool key_frame, | 
 |   26                          DataAvailableCallback* data_available_callback) { | 
 |   27   CHECK(capture_data->pixel_format() == PixelFormatRgb32) | 
 |   28       << "Zlib Encoder only works with RGB32"; | 
 |   29   capture_data_ = capture_data; | 
 |   30   callback_.reset(data_available_callback); | 
 |   31  | 
 |   32   CompressorZlib compressor; | 
 |   33   for (current_rect_ = 0; current_rect_ < capture_data->dirty_rects().size(); | 
 |   34        ++current_rect_) { | 
 |   35     EncodeRect(&compressor); | 
 |   36   } | 
 |   37  | 
 |   38   capture_data_ = NULL; | 
 |   39   callback_.reset(); | 
 |   40   current_rect_ = 0; | 
 |   41 } | 
 |   42  | 
 |   43 void EncoderZlib::EncodeRect(CompressorZlib* compressor) { | 
 |   44   CHECK(capture_data_->data_planes().data[0]); | 
 |   45   const gfx::Rect rect = capture_data_->dirty_rects()[current_rect_]; | 
 |   46   const int strides = capture_data_->data_planes().strides[0]; | 
 |   47   const int bytes_per_pixel = GetBytesPerPixel(capture_data_->pixel_format()); | 
 |   48   const int row_size = bytes_per_pixel * rect.width(); | 
 |   49  | 
 |   50   HostMessage* message = PrepareMessage(true); | 
 |   51   const uint8 * in = capture_data_->data_planes().data[0] + | 
 |   52                      rect.y() * strides + | 
 |   53                      rect.x() * bytes_per_pixel; | 
 |   54   // TODO(hclam): Fill in the sequence number. | 
 |   55   uint8* out = (uint8*)message->mutable_update_stream_packet()-> | 
 |   56       mutable_rect_data()->mutable_data()->data(); | 
 |   57   int filled = 0; | 
 |   58   int row_x = 0; | 
 |   59   int row_y = 0; | 
 |   60   bool compress_again = true; | 
 |   61   while (compress_again) { | 
 |   62     // Prepare a message for sending out. | 
 |   63     if (!message) { | 
 |   64       message = PrepareMessage(false); | 
 |   65       out = (uint8*)(message->mutable_update_stream_packet()-> | 
 |   66                      mutable_rect_data()->mutable_data()->data()); | 
 |   67       filled = 0; | 
 |   68     } | 
 |   69  | 
 |   70     Compressor::CompressorFlush flush = Compressor::CompressorNoFlush; | 
 |   71     if (row_y == rect.height() - 1) { | 
 |   72       if (current_rect_ == capture_data_->dirty_rects().size() - 1) | 
 |   73         flush = Compressor::CompressorFinish; | 
 |   74       else | 
 |   75         flush = Compressor::CompressorSyncFlush; | 
 |   76     } | 
 |   77  | 
 |   78     int consumed = 0; | 
 |   79     int written = 0; | 
 |   80     compress_again = compressor->Process(in + row_x, row_size - row_x, | 
 |   81                                          out + filled, packet_size_ - filled, | 
 |   82                                          flush, &consumed, &written); | 
 |   83     row_x += consumed; | 
 |   84     filled += written; | 
 |   85  | 
 |   86     // We have reached the end of stream. | 
 |   87     if (!compress_again) { | 
 |   88       message->mutable_update_stream_packet()->mutable_end_rect(); | 
 |   89     } | 
 |   90  | 
 |   91     // If we have filled the message or we have reached the end of stream. | 
 |   92     if (filled == packet_size_ || !compress_again) { | 
 |   93       message->mutable_update_stream_packet()->mutable_rect_data()-> | 
 |   94           mutable_data()->resize(filled); | 
 |   95       SubmitMessage(message); | 
 |   96       message = NULL; | 
 |   97     } | 
 |   98  | 
 |   99     // Reached the end of input row and we're not at the last row. | 
 |  100     if (row_x == row_size && row_y < rect.height() - 1) { | 
 |  101       row_x = 0; | 
 |  102       in += strides; | 
 |  103       ++row_y; | 
 |  104     } | 
 |  105   } | 
 |  106 } | 
 |  107  | 
 |  108 HostMessage* EncoderZlib::PrepareMessage(bool new_rect) { | 
 |  109   HostMessage* message = new HostMessage(); | 
 |  110   UpdateStreamPacketMessage* packet = message->mutable_update_stream_packet(); | 
 |  111  | 
 |  112   // Prepare the begin rect content. | 
 |  113   if (new_rect) { | 
 |  114     gfx::Rect rect = capture_data_->dirty_rects()[current_rect_]; | 
 |  115     packet->mutable_begin_rect()->set_x(rect.x()); | 
 |  116     packet->mutable_begin_rect()->set_y(rect.y()); | 
 |  117     packet->mutable_begin_rect()->set_width(rect.width()); | 
 |  118     packet->mutable_begin_rect()->set_height(rect.height()); | 
 |  119     packet->mutable_begin_rect()->set_encoding(EncodingZlib); | 
 |  120     packet->mutable_begin_rect()->set_pixel_format( | 
 |  121         capture_data_->pixel_format()); | 
 |  122   } | 
 |  123  | 
 |  124   packet->mutable_rect_data()->mutable_data()->resize(packet_size_); | 
 |  125   return message; | 
 |  126 } | 
 |  127  | 
 |  128 void EncoderZlib::SubmitMessage(HostMessage* message) { | 
 |  129   EncodingState state = EncodingInProgress; | 
 |  130   if (current_rect_ == 0 && message->update_stream_packet().has_begin_rect()) | 
 |  131     state |= EncodingStarting; | 
 |  132   if (current_rect_ == capture_data_->dirty_rects().size() - 1 && | 
 |  133       message->update_stream_packet().has_end_rect()) | 
 |  134     state |= EncodingEnded; | 
 |  135   callback_->Run(message, state); | 
 |  136 } | 
 |  137  | 
 |  138 }  // namespace remoting | 
| OLD | NEW |