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

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

Issue 9277001: Replace RectVectors with SkRegions in Decoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 11 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_vp8.h" 5 #include "remoting/base/decoder_vp8.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "media/base/media.h" 10 #include "media/base/media.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 85
86 // Gets the decoded data. 86 // Gets the decoded data.
87 vpx_codec_iter_t iter = NULL; 87 vpx_codec_iter_t iter = NULL;
88 vpx_image_t* image = vpx_codec_get_frame(codec_, &iter); 88 vpx_image_t* image = vpx_codec_get_frame(codec_, &iter);
89 if (!image) { 89 if (!image) {
90 LOG(INFO) << "No video frame decoded"; 90 LOG(INFO) << "No video frame decoded";
91 return DECODE_ERROR; 91 return DECODE_ERROR;
92 } 92 }
93 last_image_ = image; 93 last_image_ = image;
94 94
95 RectVector rects; 95 std::vector<SkIRect> rects;
96 rects.reserve(packet->dirty_rects_size()); 96 rects.reserve(packet->dirty_rects_size());
97 for (int i = 0; i < packet->dirty_rects_size(); ++i) { 97 for (int i = 0; i < packet->dirty_rects_size(); ++i) {
98 Rect remoting_rect = packet->dirty_rects(i); 98 Rect remoting_rect = packet->dirty_rects(i);
99 rects.push_back(SkIRect::MakeXYWH(remoting_rect.x(), 99 rects.push_back(SkIRect::MakeXYWH(remoting_rect.x(),
100 remoting_rect.y(), 100 remoting_rect.y(),
101 remoting_rect.width(), 101 remoting_rect.width(),
102 remoting_rect.height())); 102 remoting_rect.height()));
103 } 103 }
104 104
105 RefreshRects(rects); 105 SkRegion region;
106 region.setRects(&rects[0], rects.size());
107
108 RefreshRegion(region);
106 return DECODE_DONE; 109 return DECODE_DONE;
107 } 110 }
108 111
109 void DecoderVp8::GetUpdatedRects(RectVector* rects) { 112 void DecoderVp8::GetUpdatedRegion(SkRegion* region) {
110 rects->swap(updated_rects_); 113 region->swap(updated_region_);
111 } 114 }
112 115
113 void DecoderVp8::Reset() { 116 void DecoderVp8::Reset() {
114 frame_ = NULL; 117 frame_ = NULL;
115 state_ = kUninitialized; 118 state_ = kUninitialized;
116 } 119 }
117 120
118 bool DecoderVp8::IsReadyForData() { 121 bool DecoderVp8::IsReadyForData() {
119 return state_ == kReady; 122 return state_ == kReady;
120 } 123 }
121 124
122 VideoPacketFormat::Encoding DecoderVp8::Encoding() { 125 VideoPacketFormat::Encoding DecoderVp8::Encoding() {
123 return VideoPacketFormat::ENCODING_VP8; 126 return VideoPacketFormat::ENCODING_VP8;
124 } 127 }
125 128
126 void DecoderVp8::SetOutputSize(const SkISize& size) { 129 void DecoderVp8::SetOutputSize(const SkISize& size) {
127 output_size_ = size; 130 output_size_ = size;
128 } 131 }
129 132
130 void DecoderVp8::SetClipRect(const SkIRect& clip_rect) { 133 void DecoderVp8::SetClipRect(const SkIRect& clip_rect) {
131 clip_rect_ = clip_rect; 134 clip_rect_ = clip_rect;
132 } 135 }
133 136
134 void DecoderVp8::RefreshRects(const RectVector& rects) { 137 void DecoderVp8::RefreshRegion(const SkRegion& region) {
135 // TODO(wez): Fix the rest of the decode pipeline not to assume the frame 138 // TODO(wez): Fix the rest of the decode pipeline not to assume the frame
136 // size is the host dimensions, since it's not when scaling. If the host 139 // size is the host dimensions, since it's not when scaling. If the host
137 // gets smaller, then the output size will be too big and we'll overrun the 140 // gets smaller, then the output size will be too big and we'll overrun the
138 // frame, so currently we render 1:1 in that case; the app will see the 141 // frame, so currently we render 1:1 in that case; the app will see the
139 // host size change and resize us if need be. 142 // host size change and resize us if need be.
140 if (output_size_.width() > static_cast<int>(frame_->width())) 143 if (output_size_.width() > static_cast<int>(frame_->width()))
141 output_size_.set(frame_->width(), output_size_.height()); 144 output_size_.set(frame_->width(), output_size_.height());
142 if (output_size_.height() > static_cast<int>(frame_->height())) 145 if (output_size_.height() > static_cast<int>(frame_->height()))
143 output_size_.set(output_size_.width(), frame_->height()); 146 output_size_.set(output_size_.width(), frame_->height());
144 147
145 if (!DoScaling()) 148 if (!DoScaling())
146 ConvertRects(rects, &updated_rects_); 149 ConvertRegion(region, &updated_region_);
Sergey Ulanov 2012/01/23 19:59:54 nit: add { }
Wez 2012/01/23 21:37:23 Done.
147 else 150 else
148 ScaleAndConvertRects(rects, &updated_rects_); 151 ScaleAndConvertRegion(region, &updated_region_);
149 } 152 }
150 153
151 bool DecoderVp8::DoScaling() const { 154 bool DecoderVp8::DoScaling() const {
152 DCHECK(last_image_); 155 DCHECK(last_image_);
153 return !output_size_.equals(last_image_->d_w, last_image_->d_h); 156 return !output_size_.equals(last_image_->d_w, last_image_->d_h);
154 } 157 }
155 158
156 void DecoderVp8::ConvertRects(const RectVector& input_rects, 159 void DecoderVp8::ConvertRegion(const SkRegion& input_region,
157 RectVector* output_rects) { 160 SkRegion* output_region) {
158 if (!last_image_) 161 if (!last_image_)
159 return; 162 return;
160 163
161 output_rects->clear(); 164 output_region->setEmpty();
162 165
163 // Clip based on both the output dimensions and Pepper clip rect. 166 // Clip based on both the output dimensions and Pepper clip rect.
164 // ConvertYUVToRGB32WithRect() requires even X and Y coordinates, so we align 167 // ConvertYUVToRGB32WithRect() requires even X and Y coordinates, so we align
165 // |clip_rect| to prevent clipping from breaking alignment. We then clamp it 168 // |clip_rect| to prevent clipping from breaking alignment. We then clamp it
166 // to the image dimensions, which may lead to odd width & height, which we 169 // to the image dimensions, which may lead to odd width & height, which we
167 // can cope with. 170 // can cope with.
168 SkIRect clip_rect = AlignRect(clip_rect_); 171 SkIRect clip_rect = AlignRect(clip_rect_);
169 if (!clip_rect.intersect(SkIRect::MakeWH(last_image_->d_w, last_image_->d_h))) 172 if (!clip_rect.intersect(SkIRect::MakeWH(last_image_->d_w, last_image_->d_h)))
170 return; 173 return;
171 174
172 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane); 175 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane);
173 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane); 176 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane);
174 output_rects->reserve(input_rects.size());
175 177
176 for (size_t i = 0; i < input_rects.size(); ++i) { 178 for (SkRegion::Iterator i(input_region); !i.done(); i.next()) {
177 // Align the rectangle so the top-left coordinates are even, for 179 // Align the rectangle so the top-left coordinates are even, for
178 // ConvertYUVToRGB32WithRect(). 180 // ConvertYUVToRGB32WithRect().
179 SkIRect dest_rect(AlignRect(input_rects[i])); 181 SkIRect dest_rect(AlignRect(i.rect()));
180 182
181 // Clip the rectangle, preserving alignment since |clip_rect| is aligned. 183 // Clip the rectangle, preserving alignment since |clip_rect| is aligned.
182 if (!dest_rect.intersect(clip_rect)) 184 if (!dest_rect.intersect(clip_rect))
183 continue; 185 continue;
184 186
185 ConvertYUVToRGB32WithRect(last_image_->planes[0], 187 ConvertYUVToRGB32WithRect(last_image_->planes[0],
186 last_image_->planes[1], 188 last_image_->planes[1],
187 last_image_->planes[2], 189 last_image_->planes[2],
188 output_rgb_buf, 190 output_rgb_buf,
189 dest_rect, 191 dest_rect,
190 last_image_->stride[0], 192 last_image_->stride[0],
191 last_image_->stride[1], 193 last_image_->stride[1],
192 output_stride); 194 output_stride);
193 195
194 output_rects->push_back(dest_rect); 196 output_region->op(dest_rect, SkRegion::kUnion_Op);
Sergey Ulanov 2012/01/23 19:59:54 Comments about SkRegion::setRects() say that it ma
Wez 2012/01/23 21:37:23 To use setRects() here, we'd need to create a vect
195 } 197 }
196 } 198 }
197 199
198 void DecoderVp8::ScaleAndConvertRects(const RectVector& input_rects, 200 void DecoderVp8::ScaleAndConvertRegion(const SkRegion& input_region,
199 RectVector* output_rects) { 201 SkRegion* output_region) {
200 if (!last_image_) 202 if (!last_image_)
201 return; 203 return;
202 204
203 DCHECK(output_size_.width() <= static_cast<int>(frame_->width())); 205 DCHECK(output_size_.width() <= static_cast<int>(frame_->width()));
204 DCHECK(output_size_.height() <= static_cast<int>(frame_->height())); 206 DCHECK(output_size_.height() <= static_cast<int>(frame_->height()));
205 207
206 output_rects->clear(); 208 output_region->setEmpty();
207 209
208 // Clip based on both the output dimensions and Pepper clip rect. 210 // Clip based on both the output dimensions and Pepper clip rect.
209 SkIRect clip_rect = clip_rect_; 211 SkIRect clip_rect = clip_rect_;
210 if (!clip_rect.intersect(SkIRect::MakeSize(output_size_))) 212 if (!clip_rect.intersect(SkIRect::MakeSize(output_size_)))
211 return; 213 return;
212 214
213 SkISize image_size = SkISize::Make(last_image_->d_w, last_image_->d_h); 215 SkISize image_size = SkISize::Make(last_image_->d_w, last_image_->d_h);
214 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane); 216 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane);
215 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane); 217 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane);
216 218
217 output_rects->reserve(input_rects.size()); 219 for (SkRegion::Iterator i(input_region); !i.done(); i.next()) {
218
219 for (size_t i = 0; i < input_rects.size(); ++i) {
220 // Determine the scaled area affected by this rectangle changing. 220 // Determine the scaled area affected by this rectangle changing.
221 SkIRect output_rect = ScaleRect(input_rects[i], image_size, output_size_); 221 SkIRect output_rect = ScaleRect(i.rect(), image_size, output_size_);
222 if (!output_rect.intersect(clip_rect)) 222 if (!output_rect.intersect(clip_rect))
223 continue; 223 continue;
224 224
225 // The scaler will not to read outside the input dimensions. 225 // The scaler will not to read outside the input dimensions.
226 media::ScaleYUVToRGB32WithRect(last_image_->planes[0], 226 media::ScaleYUVToRGB32WithRect(last_image_->planes[0],
227 last_image_->planes[1], 227 last_image_->planes[1],
228 last_image_->planes[2], 228 last_image_->planes[2],
229 output_rgb_buf, 229 output_rgb_buf,
230 image_size.width(), 230 image_size.width(),
231 image_size.height(), 231 image_size.height(),
232 output_size_.width(), 232 output_size_.width(),
233 output_size_.height(), 233 output_size_.height(),
234 output_rect.x(), 234 output_rect.x(),
235 output_rect.y(), 235 output_rect.y(),
236 output_rect.right(), 236 output_rect.right(),
237 output_rect.bottom(), 237 output_rect.bottom(),
238 last_image_->stride[0], 238 last_image_->stride[0],
239 last_image_->stride[1], 239 last_image_->stride[1],
240 output_stride); 240 output_stride);
241 output_rects->push_back(output_rect); 241 output_region->op(output_rect, SkRegion::kUnion_Op);
Sergey Ulanov 2012/01/23 19:59:54 same here
242 } 242 }
243 } 243 }
244 244
245 } // namespace remoting 245 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698