Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: remoting/base/decoder_row_based.cc

Issue 9331003: Improving the decoder pipeline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/decoder_row_based.h" 5 #include "remoting/base/decoder_row_based.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "remoting/base/decompressor.h" 8 #include "remoting/base/decompressor.h"
9 #include "remoting/base/decompressor_zlib.h" 9 #include "remoting/base/decompressor_zlib.h"
10 #include "remoting/base/decompressor_verbatim.h" 10 #include "remoting/base/decompressor_verbatim.h"
(...skipping 16 matching lines...) Expand all
27 VideoPacketFormat::ENCODING_VERBATIM); 27 VideoPacketFormat::ENCODING_VERBATIM);
28 } 28 }
29 29
30 DecoderRowBased::DecoderRowBased(Decompressor* decompressor, 30 DecoderRowBased::DecoderRowBased(Decompressor* decompressor,
31 VideoPacketFormat::Encoding encoding) 31 VideoPacketFormat::Encoding encoding)
32 : state_(kUninitialized), 32 : state_(kUninitialized),
33 clip_(SkIRect::MakeEmpty()), 33 clip_(SkIRect::MakeEmpty()),
34 decompressor_(decompressor), 34 decompressor_(decompressor),
35 encoding_(encoding), 35 encoding_(encoding),
36 row_pos_(0), 36 row_pos_(0),
37 row_y_(0) { 37 row_y_(0),
38 screen_size_(SkISize::Make(0, 0)) {
38 } 39 }
39 40
40 DecoderRowBased::~DecoderRowBased() { 41 DecoderRowBased::~DecoderRowBased() {
41 } 42 }
42 43
43 void DecoderRowBased::Reset() {
44 frame_ = NULL;
45 decompressor_->Reset();
46 state_ = kUninitialized;
47 updated_region_.setEmpty();
48 }
49
50 bool DecoderRowBased::IsReadyForData() { 44 bool DecoderRowBased::IsReadyForData() {
51 switch (state_) { 45 switch (state_) {
52 case kUninitialized: 46 case kUninitialized:
53 case kError: 47 case kError:
54 return false; 48 return false;
55 case kReady: 49 case kReady:
56 case kProcessing: 50 case kProcessing:
57 case kPartitionDone: 51 case kPartitionDone:
58 case kDone: 52 case kDone:
59 return true; 53 return true;
60 } 54 }
61 NOTREACHED(); 55 NOTREACHED();
62 return false; 56 return false;
63 } 57 }
64 58
65 void DecoderRowBased::Initialize(scoped_refptr<media::VideoFrame> frame) { 59 void DecoderRowBased::Initialize(const SkISize& screen_size) {
66 // Make sure we are not currently initialized. 60 decompressor_->Reset();
67 CHECK_EQ(kUninitialized, state_); 61 updated_region_.setEmpty();
62 screen_buffer_.reset(NULL);
68 63
69 if (frame->format() != media::VideoFrame::RGB32) { 64 screen_size_ = screen_size;
70 LOG(WARNING) << "DecoderRowBased only supports RGB32."; 65 // Allocate the screen buffer, if necessary.
71 state_ = kError; 66 if (!screen_size_.isZero()) {
Wez 2012/02/17 23:42:17 isZero() -> isEmpty()
alexeypa (please no reviews) 2012/02/21 23:00:44 Done.
72 return; 67 screen_buffer_.reset(new uint8[
68 screen_size_.width() * screen_size_.height() * kBytesPerPixel]);
73 } 69 }
74 70
75 frame_ = frame;
76 state_ = kReady; 71 state_ = kReady;
77 } 72 }
78 73
79 Decoder::DecodeResult DecoderRowBased::DecodePacket(const VideoPacket* packet) { 74 Decoder::DecodeResult DecoderRowBased::DecodePacket(const VideoPacket* packet) {
80 UpdateStateForPacket(packet); 75 UpdateStateForPacket(packet);
81 76
82 if (state_ == kError) { 77 if (state_ == kError) {
83 return DECODE_ERROR; 78 return DECODE_ERROR;
84 } 79 }
85 80
81 // The input buffer is a linear vector of pixel data.
Wez 2012/02/17 23:42:17 nit: This comment doesn't really add anything to t
alexeypa (please no reviews) 2012/02/21 23:00:44 Done.
86 const uint8* in = reinterpret_cast<const uint8*>(packet->data().data()); 82 const uint8* in = reinterpret_cast<const uint8*>(packet->data().data());
87 const int in_size = packet->data().size(); 83 const int in_size = packet->data().size();
84 const int row_size = clip_.width() * kBytesPerPixel;
88 85
89 const int row_size = clip_.width() * kBytesPerPixel; 86 // Access the pixel buffer directly.
Wez 2012/02/17 23:42:17 nit: This comment doesn't really add anything
alexeypa (please no reviews) 2012/02/21 23:00:44 Done.
90 int stride = frame_->stride(media::VideoFrame::kRGBPlane); 87 int out_stride = screen_size_.width() * kBytesPerPixel;
91 uint8* rect_begin = frame_->data(media::VideoFrame::kRGBPlane); 88 uint8* out = screen_buffer_.get() + out_stride * (clip_.top() + row_y_) +
92 89 kBytesPerPixel * clip_.left();
93 uint8* out = rect_begin + stride * (clip_.fTop + row_y_) +
94 kBytesPerPixel * clip_.fLeft;
95 90
96 // Consume all the data in the message. 91 // Consume all the data in the message.
97 bool decompress_again = true; 92 bool decompress_again = true;
98 int used = 0; 93 int used = 0;
99 while (decompress_again && used < in_size) { 94 while (decompress_again && used < in_size) {
100 if (row_y_ >= clip_.height()) { 95 if (row_y_ >= clip_.height()) {
101 state_ = kError; 96 state_ = kError;
102 LOG(WARNING) << "Too much data is received for the given rectangle."; 97 LOG(WARNING) << "Too much data is received for the given rectangle.";
103 return DECODE_ERROR; 98 return DECODE_ERROR;
104 } 99 }
105 100
106 int written = 0; 101 int written = 0;
107 int consumed = 0; 102 int consumed = 0;
108 // TODO(ajwong): This assume source and dest stride are the same, which is
109 // incorrect.
110 decompress_again = decompressor_->Process( 103 decompress_again = decompressor_->Process(
111 in + used, in_size - used, out + row_pos_, row_size - row_pos_, 104 in + used, in_size - used, out + row_pos_, row_size - row_pos_,
112 &consumed, &written); 105 &consumed, &written);
113 used += consumed; 106 used += consumed;
114 row_pos_ += written; 107 row_pos_ += written;
115 108
116 // If this row is completely filled then move onto the next row. 109 // If this row is completely filled then move onto the next row.
117 if (row_pos_ == row_size) { 110 if (row_pos_ == row_size) {
118 ++row_y_; 111 ++row_y_;
119 row_pos_ = 0; 112 row_pos_ = 0;
120 out += stride; 113 out += out_stride;
121 } 114 }
122 } 115 }
123 116
124 if (state_ == kPartitionDone || state_ == kDone) { 117 if (state_ == kPartitionDone || state_ == kDone) {
125 if (row_y_ < clip_.height()) { 118 if (row_y_ < clip_.height()) {
126 state_ = kError; 119 state_ = kError;
127 LOG(WARNING) << "Received LAST_PACKET, but didn't get enough data."; 120 LOG(WARNING) << "Received LAST_PACKET, but didn't get enough data.";
128 return DECODE_ERROR; 121 return DECODE_ERROR;
129 } 122 }
130 123
(...skipping 12 matching lines...) Expand all
143 if (state_ == kError) { 136 if (state_ == kError) {
144 return; 137 return;
145 } 138 }
146 139
147 if (packet->flags() & VideoPacket::FIRST_PACKET) { 140 if (packet->flags() & VideoPacket::FIRST_PACKET) {
148 if (state_ != kReady && state_ != kDone && state_ != kPartitionDone) { 141 if (state_ != kReady && state_ != kDone && state_ != kPartitionDone) {
149 state_ = kError; 142 state_ = kError;
150 LOG(WARNING) << "Received unexpected FIRST_PACKET."; 143 LOG(WARNING) << "Received unexpected FIRST_PACKET.";
151 return; 144 return;
152 } 145 }
153 state_ = kProcessing;
154 146
155 // Reset the buffer location status variables on the first packet. 147 // Reset the buffer location status variables on the first packet.
156 clip_.setXYWH(packet->format().x(), packet->format().y(), 148 clip_.setXYWH(packet->format().x(), packet->format().y(),
157 packet->format().width(), packet->format().height()); 149 packet->format().width(), packet->format().height());
150 if (!SkIRect::MakeSize(screen_size_).contains(clip_)) {
151 state_ = kError;
152 LOG(WARNING) << "Invalid clipping area received.";
Wez 2012/02/17 23:42:17 If this is never valid then consider a DCHECK, or
alexeypa (please no reviews) 2012/02/21 23:00:44 This should never happen but this data arrives fro
153 return;
154 }
155
156 state_ = kProcessing;
158 row_pos_ = 0; 157 row_pos_ = 0;
159 row_y_ = 0; 158 row_y_ = 0;
160 } 159 }
161 160
162 if (state_ != kProcessing) { 161 if (state_ != kProcessing) {
163 state_ = kError; 162 state_ = kError;
164 LOG(WARNING) << "Received unexpected packet."; 163 LOG(WARNING) << "Received unexpected packet.";
165 return; 164 return;
166 } 165 }
167 166
(...skipping 11 matching lines...) Expand all
179 state_ = kError; 178 state_ = kError;
180 LOG(WARNING) << "Received unexpected LAST_PARTITION."; 179 LOG(WARNING) << "Received unexpected LAST_PARTITION.";
181 return; 180 return;
182 } 181 }
183 state_ = kDone; 182 state_ = kDone;
184 } 183 }
185 184
186 return; 185 return;
187 } 186 }
188 187
189 void DecoderRowBased::GetUpdatedRegion(SkRegion* region) {
190 region->swap(updated_region_);
191 updated_region_.setEmpty();
192 }
193
194 VideoPacketFormat::Encoding DecoderRowBased::Encoding() { 188 VideoPacketFormat::Encoding DecoderRowBased::Encoding() {
195 return encoding_; 189 return encoding_;
196 } 190 }
197 191
192 void DecoderRowBased::Invalidate(const SkISize& view_size,
193 const SkRegion& region) {
194 updated_region_.op(region, SkRegion::kUnion_Op);
195 }
196
197 void DecoderRowBased::RenderFrame(const SkISize& view_size,
198 const SkIRect& clip_area,
199 uint8* image_buffer,
200 int image_stride,
201 SkRegion* output_region) {
202 output_region->setEmpty();
203
204 // TODO(alexeypa): implement scaling in the case when |view_size| does
205 // not match |screen_size_|.
Wez 2012/02/17 23:42:17 nit: Consider changing this to a comment bemoaning
alexeypa (please no reviews) 2012/02/21 23:00:44 Done.
206 SkIRect clip_rect = SkIRect::MakeSize(screen_size_);
207 if (!clip_rect.intersect(clip_area))
208 return;
209
210 int screen_stride = screen_size_.width() * kBytesPerPixel;
211
212 for (SkRegion::Iterator i(updated_region_); !i.done(); i.next()) {
213 SkIRect rect(i.rect());
214 if (!rect.intersect(clip_rect))
215 continue;
216
217 CopyRGB32Rect(screen_buffer_.get(), screen_stride,
218 clip_rect,
219 image_buffer, image_stride,
220 clip_area,
221 rect);
222 output_region->op(rect, SkRegion::kUnion_Op);
223 }
224
225 updated_region_.setEmpty();
226 }
227
198 } // namespace remoting 228 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698