| 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 |