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

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: Pick nits. 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
« no previous file with comments | « remoting/base/decoder_vp8.h ('k') | remoting/client/frame_consumer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 SkRegion region;
96 rects.reserve(packet->dirty_rects_size());
97 for (int i = 0; i < packet->dirty_rects_size(); ++i) { 96 for (int i = 0; i < packet->dirty_rects_size(); ++i) {
98 Rect remoting_rect = packet->dirty_rects(i); 97 Rect remoting_rect = packet->dirty_rects(i);
99 rects.push_back(SkIRect::MakeXYWH(remoting_rect.x(), 98 SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(),
100 remoting_rect.y(), 99 remoting_rect.y(),
101 remoting_rect.width(), 100 remoting_rect.width(),
102 remoting_rect.height())); 101 remoting_rect.height());
102 region.op(rect, SkRegion::kUnion_Op);
103 } 103 }
104 104
105 RefreshRects(rects); 105 RefreshRegion(region);
106 return DECODE_DONE; 106 return DECODE_DONE;
107 } 107 }
108 108
109 void DecoderVp8::GetUpdatedRects(RectVector* rects) { 109 void DecoderVp8::GetUpdatedRegion(SkRegion* region) {
110 rects->swap(updated_rects_); 110 region->swap(updated_region_);
111 } 111 }
112 112
113 void DecoderVp8::Reset() { 113 void DecoderVp8::Reset() {
114 frame_ = NULL; 114 frame_ = NULL;
115 state_ = kUninitialized; 115 state_ = kUninitialized;
116 } 116 }
117 117
118 bool DecoderVp8::IsReadyForData() { 118 bool DecoderVp8::IsReadyForData() {
119 return state_ == kReady; 119 return state_ == kReady;
120 } 120 }
121 121
122 VideoPacketFormat::Encoding DecoderVp8::Encoding() { 122 VideoPacketFormat::Encoding DecoderVp8::Encoding() {
123 return VideoPacketFormat::ENCODING_VP8; 123 return VideoPacketFormat::ENCODING_VP8;
124 } 124 }
125 125
126 void DecoderVp8::SetOutputSize(const SkISize& size) { 126 void DecoderVp8::SetOutputSize(const SkISize& size) {
127 output_size_ = size; 127 output_size_ = size;
128 } 128 }
129 129
130 void DecoderVp8::SetClipRect(const SkIRect& clip_rect) { 130 void DecoderVp8::SetClipRect(const SkIRect& clip_rect) {
131 clip_rect_ = clip_rect; 131 clip_rect_ = clip_rect;
132 } 132 }
133 133
134 void DecoderVp8::RefreshRects(const RectVector& rects) { 134 void DecoderVp8::RefreshRegion(const SkRegion& region) {
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()) 145 if (!DoScaling()) {
146 ConvertRects(rects, &updated_rects_); 146 ConvertRegion(region, &updated_region_);
147 else 147 } else {
148 ScaleAndConvertRects(rects, &updated_rects_); 148 ScaleAndConvertRegion(region, &updated_region_);
149 }
149 } 150 }
150 151
151 bool DecoderVp8::DoScaling() const { 152 bool DecoderVp8::DoScaling() const {
152 DCHECK(last_image_); 153 DCHECK(last_image_);
153 return !output_size_.equals(last_image_->d_w, last_image_->d_h); 154 return !output_size_.equals(last_image_->d_w, last_image_->d_h);
154 } 155 }
155 156
156 void DecoderVp8::ConvertRects(const RectVector& input_rects, 157 void DecoderVp8::ConvertRegion(const SkRegion& input_region,
157 RectVector* output_rects) { 158 SkRegion* output_region) {
158 if (!last_image_) 159 if (!last_image_)
159 return; 160 return;
160 161
161 output_rects->clear(); 162 output_region->setEmpty();
162 163
163 // Clip based on both the output dimensions and Pepper clip rect. 164 // Clip based on both the output dimensions and Pepper clip rect.
164 // ConvertYUVToRGB32WithRect() requires even X and Y coordinates, so we align 165 // ConvertYUVToRGB32WithRect() requires even X and Y coordinates, so we align
165 // |clip_rect| to prevent clipping from breaking alignment. We then clamp it 166 // |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 167 // to the image dimensions, which may lead to odd width & height, which we
167 // can cope with. 168 // can cope with.
168 SkIRect clip_rect = AlignRect(clip_rect_); 169 SkIRect clip_rect = AlignRect(clip_rect_);
169 if (!clip_rect.intersect(SkIRect::MakeWH(last_image_->d_w, last_image_->d_h))) 170 if (!clip_rect.intersect(SkIRect::MakeWH(last_image_->d_w, last_image_->d_h)))
170 return; 171 return;
171 172
172 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane); 173 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane);
173 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane); 174 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane);
174 output_rects->reserve(input_rects.size());
175 175
176 for (size_t i = 0; i < input_rects.size(); ++i) { 176 for (SkRegion::Iterator i(input_region); !i.done(); i.next()) {
177 // Align the rectangle so the top-left coordinates are even, for 177 // Align the rectangle so the top-left coordinates are even, for
178 // ConvertYUVToRGB32WithRect(). 178 // ConvertYUVToRGB32WithRect().
179 SkIRect dest_rect(AlignRect(input_rects[i])); 179 SkIRect dest_rect(AlignRect(i.rect()));
180 180
181 // Clip the rectangle, preserving alignment since |clip_rect| is aligned. 181 // Clip the rectangle, preserving alignment since |clip_rect| is aligned.
182 if (!dest_rect.intersect(clip_rect)) 182 if (!dest_rect.intersect(clip_rect))
183 continue; 183 continue;
184 184
185 ConvertYUVToRGB32WithRect(last_image_->planes[0], 185 ConvertYUVToRGB32WithRect(last_image_->planes[0],
186 last_image_->planes[1], 186 last_image_->planes[1],
187 last_image_->planes[2], 187 last_image_->planes[2],
188 output_rgb_buf, 188 output_rgb_buf,
189 dest_rect, 189 dest_rect,
190 last_image_->stride[0], 190 last_image_->stride[0],
191 last_image_->stride[1], 191 last_image_->stride[1],
192 output_stride); 192 output_stride);
193 193
194 output_rects->push_back(dest_rect); 194 output_region->op(dest_rect, SkRegion::kUnion_Op);
195 } 195 }
196 } 196 }
197 197
198 void DecoderVp8::ScaleAndConvertRects(const RectVector& input_rects, 198 void DecoderVp8::ScaleAndConvertRegion(const SkRegion& input_region,
199 RectVector* output_rects) { 199 SkRegion* output_region) {
200 if (!last_image_) 200 if (!last_image_)
201 return; 201 return;
202 202
203 DCHECK(output_size_.width() <= static_cast<int>(frame_->width())); 203 DCHECK(output_size_.width() <= static_cast<int>(frame_->width()));
204 DCHECK(output_size_.height() <= static_cast<int>(frame_->height())); 204 DCHECK(output_size_.height() <= static_cast<int>(frame_->height()));
205 205
206 output_rects->clear(); 206 output_region->setEmpty();
207 207
208 // Clip based on both the output dimensions and Pepper clip rect. 208 // Clip based on both the output dimensions and Pepper clip rect.
209 SkIRect clip_rect = clip_rect_; 209 SkIRect clip_rect = clip_rect_;
210 if (!clip_rect.intersect(SkIRect::MakeSize(output_size_))) 210 if (!clip_rect.intersect(SkIRect::MakeSize(output_size_)))
211 return; 211 return;
212 212
213 SkISize image_size = SkISize::Make(last_image_->d_w, last_image_->d_h); 213 SkISize image_size = SkISize::Make(last_image_->d_w, last_image_->d_h);
214 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane); 214 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane);
215 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane); 215 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane);
216 216
217 output_rects->reserve(input_rects.size()); 217 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. 218 // Determine the scaled area affected by this rectangle changing.
221 SkIRect output_rect = ScaleRect(input_rects[i], image_size, output_size_); 219 SkIRect output_rect = ScaleRect(i.rect(), image_size, output_size_);
222 if (!output_rect.intersect(clip_rect)) 220 if (!output_rect.intersect(clip_rect))
223 continue; 221 continue;
224 222
225 // The scaler will not to read outside the input dimensions. 223 // The scaler will not to read outside the input dimensions.
226 media::ScaleYUVToRGB32WithRect(last_image_->planes[0], 224 media::ScaleYUVToRGB32WithRect(last_image_->planes[0],
227 last_image_->planes[1], 225 last_image_->planes[1],
228 last_image_->planes[2], 226 last_image_->planes[2],
229 output_rgb_buf, 227 output_rgb_buf,
230 image_size.width(), 228 image_size.width(),
231 image_size.height(), 229 image_size.height(),
232 output_size_.width(), 230 output_size_.width(),
233 output_size_.height(), 231 output_size_.height(),
234 output_rect.x(), 232 output_rect.x(),
235 output_rect.y(), 233 output_rect.y(),
236 output_rect.right(), 234 output_rect.right(),
237 output_rect.bottom(), 235 output_rect.bottom(),
238 last_image_->stride[0], 236 last_image_->stride[0],
239 last_image_->stride[1], 237 last_image_->stride[1],
240 output_stride); 238 output_stride);
241 output_rects->push_back(output_rect); 239
240 output_region->op(output_rect, SkRegion::kUnion_Op);
242 } 241 }
243 } 242 }
244 243
245 } // namespace remoting 244 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/base/decoder_vp8.h ('k') | remoting/client/frame_consumer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698