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

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

Issue 9331003: Improving the decoder pipeline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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_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"
11 #include "media/base/yuv_convert.h" 11 #include "media/base/yuv_convert.h"
12 #include "remoting/base/util.h" 12 #include "remoting/base/util.h"
13 13
14 extern "C" { 14 extern "C" {
15 #define VPX_CODEC_DISABLE_COMPAT 1 15 #define VPX_CODEC_DISABLE_COMPAT 1
16 #include "third_party/libvpx/libvpx.h" 16 #include "third_party/libvpx/libvpx.h"
17 } 17 }
18 18
19 namespace remoting { 19 namespace remoting {
20 20
21 DecoderVp8::DecoderVp8() 21 DecoderVp8::DecoderVp8()
22 : state_(kUninitialized), 22 : state_(kUninitialized),
23 codec_(NULL), 23 codec_(NULL),
24 last_image_(NULL), 24 last_image_(NULL),
25 clip_rect_(SkIRect::MakeEmpty()), 25 screen_size_(SkISize::Make(0, 0)) {
26 output_size_(SkISize::Make(0, 0)) {
27 } 26 }
28 27
29 DecoderVp8::~DecoderVp8() { 28 DecoderVp8::~DecoderVp8() {
30 if (codec_) { 29 if (codec_) {
31 vpx_codec_err_t ret = vpx_codec_destroy(codec_); 30 vpx_codec_err_t ret = vpx_codec_destroy(codec_);
32 CHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec"; 31 CHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec";
33 } 32 }
34 delete codec_; 33 delete codec_;
35 } 34 }
36 35
37 void DecoderVp8::Initialize(scoped_refptr<media::VideoFrame> frame) { 36 void DecoderVp8::Initialize(const SkISize& screen_size) {
38 DCHECK_EQ(kUninitialized, state_); 37 DCHECK_EQ(kUninitialized, state_);
39 38
40 if (frame->format() != media::VideoFrame::RGB32) { 39 screen_size_ = screen_size;
41 LOG(INFO) << "DecoderVp8 only supports RGB32 as output";
42 state_ = kError;
43 return;
44 }
45 frame_ = frame;
46
47 state_ = kReady; 40 state_ = kReady;
48 } 41 }
49 42
50 Decoder::DecodeResult DecoderVp8::DecodePacket(const VideoPacket* packet) { 43 Decoder::DecodeResult DecoderVp8::DecodePacket(const VideoPacket* packet) {
51 DCHECK_EQ(kReady, state_); 44 DCHECK_EQ(kReady, state_);
52 45
53 // Initialize the codec as needed. 46 // Initialize the codec as needed.
54 if (!codec_) { 47 if (!codec_) {
55 codec_ = new vpx_codec_ctx_t(); 48 codec_ = new vpx_codec_ctx_t();
56 49
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 SkRegion region; 88 SkRegion region;
96 for (int i = 0; i < packet->dirty_rects_size(); ++i) { 89 for (int i = 0; i < packet->dirty_rects_size(); ++i) {
97 Rect remoting_rect = packet->dirty_rects(i); 90 Rect remoting_rect = packet->dirty_rects(i);
98 SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(), 91 SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(),
99 remoting_rect.y(), 92 remoting_rect.y(),
100 remoting_rect.width(), 93 remoting_rect.width(),
101 remoting_rect.height()); 94 remoting_rect.height());
102 region.op(rect, SkRegion::kUnion_Op); 95 region.op(rect, SkRegion::kUnion_Op);
103 } 96 }
104 97
105 RefreshRegion(region); 98 UpdateRegion(region);
106 return DECODE_DONE; 99 return DECODE_DONE;
107 } 100 }
108 101
109 void DecoderVp8::GetUpdatedRegion(SkRegion* region) {
110 region->swap(updated_region_);
111 }
112
113 void DecoderVp8::Reset() { 102 void DecoderVp8::Reset() {
114 frame_ = NULL;
115 state_ = kUninitialized; 103 state_ = kUninitialized;
Wez 2012/02/07 01:56:31 Do we need this, since when we use it, we immediat
alexeypa (please no reviews) 2012/02/15 23:06:22 Done.
116 } 104 }
117 105
118 bool DecoderVp8::IsReadyForData() { 106 bool DecoderVp8::IsReadyForData() {
119 return state_ == kReady; 107 return state_ == kReady;
120 } 108 }
121 109
122 VideoPacketFormat::Encoding DecoderVp8::Encoding() { 110 VideoPacketFormat::Encoding DecoderVp8::Encoding() {
123 return VideoPacketFormat::ENCODING_VP8; 111 return VideoPacketFormat::ENCODING_VP8;
124 } 112 }
125 113
126 void DecoderVp8::SetOutputSize(const SkISize& size) { 114 void DecoderVp8::UpdateRegion(const SkRegion& region) {
127 output_size_ = size; 115 updated_region_.op(region, SkRegion::kUnion_Op);
128 } 116 }
129 117
130 void DecoderVp8::SetClipRect(const SkIRect& clip_rect) { 118 void DecoderVp8::Draw(const SkISize& view_size,
131 clip_rect_ = clip_rect; 119 const SkIRect& clip_area,
132 } 120 uint8* image_buffer,
121 int image_stride,
122 SkRegion* output_region) {
123 output_region->setEmpty();
133 124
134 void DecoderVp8::RefreshRegion(const SkRegion& region) {
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
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
139 // host size change and resize us if need be.
140 if (output_size_.width() > static_cast<int>(frame_->width()))
141 output_size_.set(frame_->width(), output_size_.height());
142 if (output_size_.height() > static_cast<int>(frame_->height()))
143 output_size_.set(output_size_.width(), frame_->height());
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_) 125 if (!last_image_)
160 return; 126 return;
161 127
162 output_region->setEmpty(); 128 SkIRect source_clip = SkIRect::MakeWH(last_image_->d_w, last_image_->d_h);
163 129
164 // Clip based on both the output dimensions and Pepper clip rect. 130 for (SkRegion::Iterator i(updated_region_); !i.done(); i.next()) {
165 // ConvertYUVToRGB32WithRect() requires even X and Y coordinates, so we align 131 // Determine the scaled area affected by this rectangle changing.
166 // |clip_rect| to prevent clipping from breaking alignment. We then clamp it 132 SkIRect rect = i.rect();
167 // to the image dimensions, which may lead to odd width & height, which we 133 if (!rect.intersect(source_clip))
168 // can cope with. 134 continue;
169 SkIRect clip_rect = AlignRect(clip_rect_); 135 rect = ScaleRect(rect, screen_size_, view_size);
170 if (!clip_rect.intersect(SkIRect::MakeWH(last_image_->d_w, last_image_->d_h))) 136 if (!rect.intersect(clip_area))
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; 137 continue;
184 138
185 ConvertYUVToRGB32WithRect(last_image_->planes[0], 139 ConvertAndScaleYUVToRGB32Rect(last_image_->planes[0],
186 last_image_->planes[1], 140 last_image_->planes[1],
187 last_image_->planes[2], 141 last_image_->planes[2],
188 output_rgb_buf, 142 last_image_->stride[0],
189 dest_rect, 143 last_image_->stride[1],
190 last_image_->stride[0], 144 screen_size_,
191 last_image_->stride[1], 145 source_clip,
192 output_stride); 146 image_buffer,
147 image_stride,
148 view_size,
149 clip_area,
150 rect);
193 151
194 output_region->op(dest_rect, SkRegion::kUnion_Op); 152 output_region->op(rect, SkRegion::kUnion_Op);
195 } 153 }
196 }
197 154
198 void DecoderVp8::ScaleAndConvertRegion(const SkRegion& input_region, 155 updated_region_.setEmpty();
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_)))
211 return;
212
213 SkISize image_size = SkISize::Make(last_image_->d_w, last_image_->d_h);
214 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane);
215 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane);
216
217 for (SkRegion::Iterator i(input_region); !i.done(); i.next()) {
218 // Determine the scaled area affected by this rectangle changing.
219 SkIRect output_rect = ScaleRect(i.rect(), image_size, output_size_);
220 if (!output_rect.intersect(clip_rect))
221 continue;
222
223 // The scaler will not to read outside the input dimensions.
224 media::ScaleYUVToRGB32WithRect(last_image_->planes[0],
225 last_image_->planes[1],
226 last_image_->planes[2],
227 output_rgb_buf,
228 image_size.width(),
229 image_size.height(),
230 output_size_.width(),
231 output_size_.height(),
232 output_rect.x(),
233 output_rect.y(),
234 output_rect.right(),
235 output_rect.bottom(),
236 last_image_->stride[0],
237 last_image_->stride[1],
238 output_stride);
239
240 output_region->op(output_rect, SkRegion::kUnion_Op);
241 }
242 } 156 }
243 157
244 } // namespace remoting 158 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698