| 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/decoder_zlib.h" |  | 
| 6 |  | 
| 7 #include "remoting/base/decompressor_zlib.h" |  | 
| 8 #include "remoting/base/protocol_util.h" |  | 
| 9 |  | 
| 10 namespace remoting { |  | 
| 11 |  | 
| 12 DecoderZlib::DecoderZlib() |  | 
| 13     : state_(kWaitingForBeginRect), |  | 
| 14       rect_x_(0), |  | 
| 15       rect_y_(0), |  | 
| 16       rect_width_(0), |  | 
| 17       rect_height_(0), |  | 
| 18       bytes_per_pixel_(0), |  | 
| 19       updated_rects_(NULL), |  | 
| 20       row_pos_(0), |  | 
| 21       row_y_(0), |  | 
| 22       // TODO(hclam): We should use the information from the update stream |  | 
| 23       // to determine whether we should reverse the rows or not. |  | 
| 24       // But for simplicity we set to be always true. |  | 
| 25       reverse_rows_(true) { |  | 
| 26   encoding_ = EncodingZlib; |  | 
| 27 } |  | 
| 28 |  | 
| 29 bool DecoderZlib::BeginDecode(scoped_refptr<media::VideoFrame> frame, |  | 
| 30                               UpdatedRects* updated_rects, |  | 
| 31                               Task* partial_decode_done, |  | 
| 32                               Task* decode_done) { |  | 
| 33   DCHECK(!partial_decode_done_.get()); |  | 
| 34   DCHECK(!decode_done_.get()); |  | 
| 35   DCHECK(!updated_rects_); |  | 
| 36   DCHECK_EQ(kWaitingForBeginRect, state_); |  | 
| 37   DCHECK(!started_); |  | 
| 38 |  | 
| 39   if (static_cast<PixelFormat>(frame->format()) != PixelFormatRgb32) { |  | 
| 40     LOG(INFO) << "DecoderZlib only supports RGB32."; |  | 
| 41     return false; |  | 
| 42   } |  | 
| 43 |  | 
| 44   partial_decode_done_.reset(partial_decode_done); |  | 
| 45   decode_done_.reset(decode_done); |  | 
| 46   updated_rects_ = updated_rects; |  | 
| 47   frame_ = frame; |  | 
| 48 |  | 
| 49   // Create the decompressor. |  | 
| 50   decompressor_.reset(new DecompressorZlib()); |  | 
| 51 |  | 
| 52   started_ = true; |  | 
| 53   return true; |  | 
| 54 } |  | 
| 55 |  | 
| 56 bool DecoderZlib::PartialDecode(ChromotingHostMessage* message) { |  | 
| 57   scoped_ptr<ChromotingHostMessage> msg_deleter(message); |  | 
| 58   DCHECK(message->has_update_stream_packet()); |  | 
| 59   DCHECK(started_); |  | 
| 60 |  | 
| 61   bool ret = true; |  | 
| 62   if (message->update_stream_packet().has_begin_rect()) |  | 
| 63     ret = HandleBeginRect(message); |  | 
| 64   if (ret && message->update_stream_packet().has_rect_data()) |  | 
| 65     ret = HandleRectData(message); |  | 
| 66   if (ret && message->update_stream_packet().has_end_rect()) |  | 
| 67     ret = HandleEndRect(message); |  | 
| 68   return ret; |  | 
| 69 } |  | 
| 70 |  | 
| 71 void DecoderZlib::EndDecode() { |  | 
| 72   DCHECK_EQ(kWaitingForBeginRect, state_); |  | 
| 73   DCHECK(started_); |  | 
| 74 |  | 
| 75   decode_done_->Run(); |  | 
| 76 |  | 
| 77   partial_decode_done_.reset(); |  | 
| 78   decode_done_.reset(); |  | 
| 79   updated_rects_ = NULL; |  | 
| 80   frame_ = NULL; |  | 
| 81   decompressor_.reset(); |  | 
| 82   started_ = false; |  | 
| 83 } |  | 
| 84 |  | 
| 85 bool DecoderZlib::HandleBeginRect(ChromotingHostMessage* message) { |  | 
| 86   DCHECK_EQ(kWaitingForBeginRect, state_); |  | 
| 87   state_ = kWaitingForRectData; |  | 
| 88 |  | 
| 89   rect_width_ = message->update_stream_packet().begin_rect().width(); |  | 
| 90   rect_height_ = message->update_stream_packet().begin_rect().height(); |  | 
| 91   rect_x_ = message->update_stream_packet().begin_rect().x(); |  | 
| 92   rect_y_ = message->update_stream_packet().begin_rect().y(); |  | 
| 93 |  | 
| 94   PixelFormat pixel_format = |  | 
| 95       message->update_stream_packet().begin_rect().pixel_format(); |  | 
| 96 |  | 
| 97   if (static_cast<PixelFormat>(frame_->format()) != pixel_format) { |  | 
| 98     NOTREACHED() << "Pixel format of message doesn't match the video frame. " |  | 
| 99                     "Expected vs received = " |  | 
| 100                  << frame_->format() << " vs " << pixel_format |  | 
| 101                  << " Color space conversion required."; |  | 
| 102     return false; |  | 
| 103   } |  | 
| 104 |  | 
| 105   bytes_per_pixel_ = GetBytesPerPixel(pixel_format); |  | 
| 106   row_pos_ = 0; |  | 
| 107   row_y_ = 0; |  | 
| 108   return true; |  | 
| 109 } |  | 
| 110 |  | 
| 111 bool DecoderZlib::HandleRectData(ChromotingHostMessage* message) { |  | 
| 112   DCHECK_EQ(kWaitingForRectData, state_); |  | 
| 113   DCHECK_EQ(0, |  | 
| 114             message->update_stream_packet().rect_data().sequence_number()); |  | 
| 115 |  | 
| 116   const uint8* in = |  | 
| 117       (const uint8*)message->update_stream_packet().rect_data().data().data(); |  | 
| 118   const int in_size = |  | 
| 119       message->update_stream_packet().rect_data().data().size(); |  | 
| 120   const int row_size = rect_width_ * bytes_per_pixel_; |  | 
| 121   int stride = frame_->stride(media::VideoFrame::kRGBPlane); |  | 
| 122   uint8* rect_begin = frame_->data(media::VideoFrame::kRGBPlane); |  | 
| 123   if (reverse_rows_) { |  | 
| 124     // Advance the pointer to the last row. |  | 
| 125     rect_begin += (frame_->height() - 1) * stride; |  | 
| 126 |  | 
| 127     // And then make the stride negative. |  | 
| 128     stride = -stride; |  | 
| 129   } |  | 
| 130 |  | 
| 131   uint8* out = rect_begin + stride * (rect_y_ + row_y_) + |  | 
| 132       bytes_per_pixel_ * rect_x_; |  | 
| 133 |  | 
| 134   // Consume all the data in the message. |  | 
| 135   bool decompress_again = true; |  | 
| 136   int used = 0; |  | 
| 137   while (decompress_again && used < in_size) { |  | 
| 138     int written = 0; |  | 
| 139     int consumed = 0; |  | 
| 140     decompress_again = decompressor_->Process( |  | 
| 141         in + used, in_size - used, out + row_pos_, row_size - row_pos_, |  | 
| 142         &consumed, &written); |  | 
| 143     used += consumed; |  | 
| 144     row_pos_ += written; |  | 
| 145 |  | 
| 146     // If this row is completely filled then move onto the next row. |  | 
| 147     if (row_pos_ == row_size) { |  | 
| 148       ++row_y_; |  | 
| 149       row_pos_ = 0; |  | 
| 150       out += stride; |  | 
| 151     } |  | 
| 152   } |  | 
| 153   return true; |  | 
| 154 } |  | 
| 155 |  | 
| 156 bool DecoderZlib::HandleEndRect(ChromotingHostMessage* message) { |  | 
| 157   DCHECK_EQ(kWaitingForRectData, state_); |  | 
| 158   state_ = kWaitingForBeginRect; |  | 
| 159 |  | 
| 160   updated_rects_->clear(); |  | 
| 161   updated_rects_->push_back(gfx::Rect(rect_x_, rect_y_, |  | 
| 162                                       rect_width_, rect_height_)); |  | 
| 163   partial_decode_done_->Run(); |  | 
| 164   return true; |  | 
| 165 } |  | 
| 166 |  | 
| 167 }  // namespace remoting |  | 
| OLD | NEW | 
|---|