OLD | NEW |
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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 // TODO(wez): Fix the rest of the decode pipeline not to assume the frame | 135 // 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 | 136 // 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 | 137 // 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 | 138 // 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. | 139 // host size change and resize us if need be. |
140 if (output_size_.width() > static_cast<int>(frame_->width())) | 140 if (output_size_.width() > static_cast<int>(frame_->width())) |
141 output_size_.set(frame_->width(), output_size_.height()); | 141 output_size_.set(frame_->width(), output_size_.height()); |
142 if (output_size_.height() > static_cast<int>(frame_->height())) | 142 if (output_size_.height() > static_cast<int>(frame_->height())) |
143 output_size_.set(output_size_.width(), frame_->height()); | 143 output_size_.set(output_size_.width(), frame_->height()); |
144 | 144 |
145 if (!DoScaling()) { | |
146 ConvertRegion(region, &updated_region_); | |
147 } else { | |
148 ScaleAndConvertRegion(region, &updated_region_); | |
149 } | |
150 } | |
151 | |
152 bool DecoderVp8::DoScaling() const { | |
153 DCHECK(last_image_); | |
154 return !output_size_.equals(last_image_->d_w, last_image_->d_h); | |
155 } | |
156 | |
157 void DecoderVp8::ConvertRegion(const SkRegion& input_region, | |
158 SkRegion* output_region) { | |
159 if (!last_image_) | 145 if (!last_image_) |
160 return; | 146 return; |
161 | 147 |
162 output_region->setEmpty(); | 148 updated_region_.setEmpty(); |
163 | 149 |
164 // Clip based on both the output dimensions and Pepper clip rect. | 150 // Clip based on both the output dimensions and Pepper clip rect. |
165 // ConvertYUVToRGB32WithRect() requires even X and Y coordinates, so we align | 151 // ConvertAndScaleYUVToRGB32Rect() requires even X and Y coordinates, so we |
166 // |clip_rect| to prevent clipping from breaking alignment. We then clamp it | 152 // align |clip_rect| to prevent clipping from breaking alignment. We then |
167 // to the image dimensions, which may lead to odd width & height, which we | 153 // clamp it to the image dimensions, which may lead to odd width & height, |
168 // can cope with. | 154 // which we can cope with. |
169 SkIRect clip_rect = AlignRect(clip_rect_); | 155 SkIRect clip_rect = AlignRect(clip_rect_); |
170 if (!clip_rect.intersect(SkIRect::MakeWH(last_image_->d_w, last_image_->d_h))) | |
171 return; | |
172 | |
173 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane); | |
174 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane); | |
175 | |
176 for (SkRegion::Iterator i(input_region); !i.done(); i.next()) { | |
177 // Align the rectangle so the top-left coordinates are even, for | |
178 // ConvertYUVToRGB32WithRect(). | |
179 SkIRect dest_rect(AlignRect(i.rect())); | |
180 | |
181 // Clip the rectangle, preserving alignment since |clip_rect| is aligned. | |
182 if (!dest_rect.intersect(clip_rect)) | |
183 continue; | |
184 | |
185 ConvertYUVToRGB32WithRect(last_image_->planes[0], | |
186 last_image_->planes[1], | |
187 last_image_->planes[2], | |
188 output_rgb_buf, | |
189 dest_rect, | |
190 last_image_->stride[0], | |
191 last_image_->stride[1], | |
192 output_stride); | |
193 | |
194 output_region->op(dest_rect, SkRegion::kUnion_Op); | |
195 } | |
196 } | |
197 | |
198 void DecoderVp8::ScaleAndConvertRegion(const SkRegion& input_region, | |
199 SkRegion* output_region) { | |
200 if (!last_image_) | |
201 return; | |
202 | |
203 DCHECK(output_size_.width() <= static_cast<int>(frame_->width())); | |
204 DCHECK(output_size_.height() <= static_cast<int>(frame_->height())); | |
205 | |
206 output_region->setEmpty(); | |
207 | |
208 // Clip based on both the output dimensions and Pepper clip rect. | |
209 SkIRect clip_rect = clip_rect_; | |
210 if (!clip_rect.intersect(SkIRect::MakeSize(output_size_))) | 156 if (!clip_rect.intersect(SkIRect::MakeSize(output_size_))) |
211 return; | 157 return; |
212 | 158 |
213 SkISize image_size = SkISize::Make(last_image_->d_w, last_image_->d_h); | 159 SkISize image_size = SkISize::Make(last_image_->d_w, last_image_->d_h); |
214 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane); | 160 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane); |
215 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane); | 161 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane); |
216 | 162 |
217 for (SkRegion::Iterator i(input_region); !i.done(); i.next()) { | 163 for (SkRegion::Iterator i(region); !i.done(); i.next()) { |
218 // Determine the scaled area affected by this rectangle changing. | 164 // Determine the scaled area affected by this rectangle changing. |
219 SkIRect output_rect = ScaleRect(i.rect(), image_size, output_size_); | 165 // Align the rectangle so the top-left coordinates are even, for |
| 166 // ConvertAndScaleYUVToRGB32Rect(). |
| 167 SkIRect output_rect = ScaleRect(AlignRect(i.rect()), |
| 168 image_size, output_size_); |
220 if (!output_rect.intersect(clip_rect)) | 169 if (!output_rect.intersect(clip_rect)) |
221 continue; | 170 continue; |
222 | 171 |
223 // The scaler will not to read outside the input dimensions. | 172 // The scaler will not to read outside the input dimensions. |
224 media::ScaleYUVToRGB32WithRect(last_image_->planes[0], | 173 ConvertAndScaleYUVToRGB32Rect(last_image_->planes[0], |
225 last_image_->planes[1], | 174 last_image_->planes[1], |
226 last_image_->planes[2], | 175 last_image_->planes[2], |
227 output_rgb_buf, | 176 last_image_->stride[0], |
228 image_size.width(), | 177 last_image_->stride[1], |
229 image_size.height(), | 178 image_size, |
230 output_size_.width(), | 179 SkIRect::MakeSize(image_size), |
231 output_size_.height(), | 180 output_rgb_buf, |
232 output_rect.x(), | 181 output_stride, |
233 output_rect.y(), | 182 output_size_, |
234 output_rect.right(), | 183 SkIRect::MakeSize(output_size_), |
235 output_rect.bottom(), | 184 output_rect); |
236 last_image_->stride[0], | |
237 last_image_->stride[1], | |
238 output_stride); | |
239 | 185 |
240 output_region->op(output_rect, SkRegion::kUnion_Op); | 186 updated_region_.op(output_rect, SkRegion::kUnion_Op); |
241 } | 187 } |
242 } | 188 } |
243 | 189 |
244 } // namespace remoting | 190 } // namespace remoting |
OLD | NEW |