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

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

Issue 10877014: Moved the video encoders/decoders to the codec directory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 8 years, 4 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/base/decoder_vp8_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "remoting/base/decoder_vp8.h"
6
7 #include <math.h>
8
9 #include "base/logging.h"
10 #include "media/base/media.h"
11 #include "media/base/yuv_convert.h"
12 #include "remoting/base/util.h"
13
14 extern "C" {
15 #define VPX_CODEC_DISABLE_COMPAT 1
16 #include "third_party/libvpx/libvpx.h"
17 }
18
19 namespace remoting {
20
21 DecoderVp8::DecoderVp8()
22 : state_(kUninitialized),
23 codec_(NULL),
24 last_image_(NULL),
25 screen_size_(SkISize::Make(0, 0)) {
26 }
27
28 DecoderVp8::~DecoderVp8() {
29 if (codec_) {
30 vpx_codec_err_t ret = vpx_codec_destroy(codec_);
31 CHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec";
32 }
33 delete codec_;
34 }
35
36 void DecoderVp8::Initialize(const SkISize& screen_size) {
37 DCHECK(!screen_size.isEmpty());
38
39 screen_size_ = screen_size;
40 state_ = kReady;
41 }
42
43 Decoder::DecodeResult DecoderVp8::DecodePacket(const VideoPacket* packet) {
44 DCHECK_EQ(kReady, state_);
45
46 // Initialize the codec as needed.
47 if (!codec_) {
48 codec_ = new vpx_codec_ctx_t();
49
50 // TODO(hclam): Scale the number of threads with number of cores of the
51 // machine.
52 vpx_codec_dec_cfg config;
53 config.w = 0;
54 config.h = 0;
55 config.threads = 2;
56 vpx_codec_err_t ret =
57 vpx_codec_dec_init(
58 codec_, vpx_codec_vp8_dx(), &config, 0);
59 if (ret != VPX_CODEC_OK) {
60 LOG(INFO) << "Cannot initialize codec.";
61 delete codec_;
62 codec_ = NULL;
63 state_ = kError;
64 return DECODE_ERROR;
65 }
66 }
67
68 // Do the actual decoding.
69 vpx_codec_err_t ret = vpx_codec_decode(
70 codec_, reinterpret_cast<const uint8*>(packet->data().data()),
71 packet->data().size(), NULL, 0);
72 if (ret != VPX_CODEC_OK) {
73 LOG(INFO) << "Decoding failed:" << vpx_codec_err_to_string(ret) << "\n"
74 << "Details: " << vpx_codec_error(codec_) << "\n"
75 << vpx_codec_error_detail(codec_);
76 return DECODE_ERROR;
77 }
78
79 // Gets the decoded data.
80 vpx_codec_iter_t iter = NULL;
81 vpx_image_t* image = vpx_codec_get_frame(codec_, &iter);
82 if (!image) {
83 LOG(INFO) << "No video frame decoded";
84 return DECODE_ERROR;
85 }
86 last_image_ = image;
87
88 SkRegion region;
89 for (int i = 0; i < packet->dirty_rects_size(); ++i) {
90 Rect remoting_rect = packet->dirty_rects(i);
91 SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(),
92 remoting_rect.y(),
93 remoting_rect.width(),
94 remoting_rect.height());
95 region.op(rect, SkRegion::kUnion_Op);
96 }
97
98 updated_region_.op(region, SkRegion::kUnion_Op);
99 return DECODE_DONE;
100 }
101
102 bool DecoderVp8::IsReadyForData() {
103 return state_ == kReady;
104 }
105
106 VideoPacketFormat::Encoding DecoderVp8::Encoding() {
107 return VideoPacketFormat::ENCODING_VP8;
108 }
109
110 void DecoderVp8::Invalidate(const SkISize& view_size,
111 const SkRegion& region) {
112 DCHECK_EQ(kReady, state_);
113 DCHECK(!view_size.isEmpty());
114
115 for (SkRegion::Iterator i(region); !i.done(); i.next()) {
116 SkIRect rect = i.rect();
117 rect = ScaleRect(rect, view_size, screen_size_);
118 updated_region_.op(rect, SkRegion::kUnion_Op);
119 }
120 }
121
122 void DecoderVp8::RenderFrame(const SkISize& view_size,
123 const SkIRect& clip_area,
124 uint8* image_buffer,
125 int image_stride,
126 SkRegion* output_region) {
127 DCHECK_EQ(kReady, state_);
128 DCHECK(!view_size.isEmpty());
129
130 // Early-return and do nothing if we haven't yet decoded any frames.
131 if (!last_image_)
132 return;
133
134 SkIRect source_clip = SkIRect::MakeWH(last_image_->d_w, last_image_->d_h);
135
136 // ScaleYUVToRGB32WithRect does not currently support up-scaling. We won't
137 // be asked to up-scale except during resizes or if page zoom is >100%, so
138 // we work-around the limitation by using the slower ScaleYUVToRGB32.
139 // TODO(wez): Remove this hack if/when ScaleYUVToRGB32WithRect can up-scale.
140 if (!updated_region_.isEmpty() &&
141 (source_clip.width() < view_size.width() ||
142 source_clip.height() < view_size.height())) {
143 // We're scaling only |clip_area| into the |image_buffer|, so we need to
144 // work out which source rectangle that corresponds to.
145 SkIRect source_rect = ScaleRect(clip_area, view_size, screen_size_);
146 source_rect = SkIRect::MakeLTRB(RoundToTwosMultiple(source_rect.left()),
147 RoundToTwosMultiple(source_rect.top()),
148 source_rect.right(),
149 source_rect.bottom());
150
151 // If there were no changes within the clip source area then don't render.
152 if (!updated_region_.intersects(source_rect))
153 return;
154
155 // Scale & convert the entire clip area.
156 int y_offset = CalculateYOffset(source_rect.x(),
157 source_rect.y(),
158 last_image_->stride[0]);
159 int uv_offset = CalculateUVOffset(source_rect.x(),
160 source_rect.y(),
161 last_image_->stride[1]);
162 ScaleYUVToRGB32(last_image_->planes[0] + y_offset,
163 last_image_->planes[1] + uv_offset,
164 last_image_->planes[2] + uv_offset,
165 image_buffer,
166 source_rect.width(),
167 source_rect.height(),
168 clip_area.width(),
169 clip_area.height(),
170 last_image_->stride[0],
171 last_image_->stride[1],
172 image_stride,
173 media::YV12,
174 media::ROTATE_0,
175 media::FILTER_BILINEAR);
176
177 output_region->op(clip_area, SkRegion::kUnion_Op);
178 updated_region_.op(source_rect, SkRegion::kDifference_Op);
179 return;
180 }
181
182 for (SkRegion::Iterator i(updated_region_); !i.done(); i.next()) {
183 // Determine the scaled area affected by this rectangle changing.
184 SkIRect rect = i.rect();
185 if (!rect.intersect(source_clip))
186 continue;
187 rect = ScaleRect(rect, screen_size_, view_size);
188 if (!rect.intersect(clip_area))
189 continue;
190
191 ConvertAndScaleYUVToRGB32Rect(last_image_->planes[0],
192 last_image_->planes[1],
193 last_image_->planes[2],
194 last_image_->stride[0],
195 last_image_->stride[1],
196 screen_size_,
197 source_clip,
198 image_buffer,
199 image_stride,
200 view_size,
201 clip_area,
202 rect);
203
204 output_region->op(rect, SkRegion::kUnion_Op);
205 }
206
207 updated_region_.op(ScaleRect(clip_area, view_size, screen_size_),
208 SkRegion::kDifference_Op);
209 }
210
211 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/base/decoder_vp8.h ('k') | remoting/base/decoder_vp8_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698