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.
5 #include "remoting/base/decoder_zlib.h"
7 #include "remoting/base/decompressor_zlib.h"
8 #include "remoting/base/protocol_util.h"
12 DecoderZlib::DecoderZlib()
13 : state_(kWaitingForBeginRect
),
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.
28 bool DecoderZlib::BeginDecode(scoped_refptr
<media::VideoFrame
> frame
,
29 UpdatedRects
* updated_rects
,
30 Task
* partial_decode_done
,
32 DCHECK(!partial_decode_done_
.get());
33 DCHECK(!decode_done_
.get());
34 DCHECK(!updated_rects_
);
35 DCHECK_EQ(kWaitingForBeginRect
, state_
);
37 if (static_cast<PixelFormat
>(frame
->format()) != PixelFormatRgb32
) {
38 LOG(INFO
) << "DecoderZlib only supports RGB32.";
42 partial_decode_done_
.reset(partial_decode_done
);
43 decode_done_
.reset(decode_done
);
44 updated_rects_
= updated_rects
;
47 // Create the decompressor.
48 decompressor_
.reset(new DecompressorZlib());
52 bool DecoderZlib::PartialDecode(HostMessage
* message
) {
53 scoped_ptr
<HostMessage
> msg_deleter(message
);
54 DCHECK(message
->has_update_stream_packet());
57 if (message
->update_stream_packet().has_begin_rect())
58 ret
= HandleBeginRect(message
);
59 if (ret
&& message
->update_stream_packet().has_rect_data())
60 ret
= HandleRectData(message
);
61 if (ret
&& message
->update_stream_packet().has_end_rect())
62 ret
= HandleEndRect(message
);
66 void DecoderZlib::EndDecode() {
67 DCHECK_EQ(kWaitingForBeginRect
, state_
);
70 partial_decode_done_
.reset();
72 updated_rects_
= NULL
;
74 decompressor_
.reset();
77 bool DecoderZlib::HandleBeginRect(HostMessage
* message
) {
78 DCHECK_EQ(kWaitingForBeginRect
, state_
);
79 state_
= kWaitingForRectData
;
81 rect_width_
= message
->update_stream_packet().begin_rect().width();
82 rect_height_
= message
->update_stream_packet().begin_rect().height();
83 rect_x_
= message
->update_stream_packet().begin_rect().x();
84 rect_y_
= message
->update_stream_packet().begin_rect().y();
86 PixelFormat pixel_format
=
87 message
->update_stream_packet().begin_rect().pixel_format();
89 if (static_cast<PixelFormat
>(frame_
->format()) != pixel_format
) {
90 NOTREACHED() << "Pixel format of message doesn't match the video frame. "
91 "Expected vs received = "
92 << frame_
->format() << " vs " << pixel_format
93 << " Color space conversion required.";
97 bytes_per_pixel_
= GetBytesPerPixel(pixel_format
);
103 bool DecoderZlib::HandleRectData(HostMessage
* message
) {
104 DCHECK_EQ(kWaitingForRectData
, state_
);
106 message
->update_stream_packet().rect_data().sequence_number());
109 (const uint8
*)message
->update_stream_packet().rect_data().data().data();
111 message
->update_stream_packet().rect_data().data().size();
112 const int row_size
= rect_width_
* bytes_per_pixel_
;
113 int stride
= frame_
->stride(media::VideoFrame::kRGBPlane
);
114 uint8
* rect_begin
= frame_
->data(media::VideoFrame::kRGBPlane
);
116 // Advance the pointer to the last row.
117 rect_begin
+= (frame_
->height() - 1) * stride
;
119 // And then make the stride negative.
123 uint8
* out
= rect_begin
+ stride
* (rect_y_
+ row_y_
) +
124 bytes_per_pixel_
* rect_x_
;
126 // Consume all the data in the message.
127 bool decompress_again
= true;
129 while (decompress_again
&& used
< in_size
) {
132 decompress_again
= decompressor_
->Process(
133 in
+ used
, in_size
- used
, out
+ row_pos_
, row_size
- row_pos_
,
134 &consumed
, &written
);
138 // If this row is completely filled then move onto the next row.
139 if (row_pos_
== row_size
) {
148 bool DecoderZlib::HandleEndRect(HostMessage
* message
) {
149 DCHECK_EQ(kWaitingForRectData
, state_
);
150 state_
= kWaitingForBeginRect
;
152 updated_rects_
->clear();
153 updated_rects_
->push_back(gfx::Rect(rect_x_
, rect_y_
,
154 rect_width_
, rect_height_
));
155 partial_decode_done_
->Run();
159 } // namespace remoting