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

Side by Side Diff: remoting/codec/video_encoder_vpx.cc

Issue 1864213002: Convert //remoting to use std::unique_ptr (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Mac IWYU Created 4 years, 8 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
« no previous file with comments | « remoting/codec/video_encoder_vpx.h ('k') | remoting/codec/video_encoder_vpx_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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/codec/video_encoder_vpx.h" 5 #include "remoting/codec/video_encoder_vpx.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
11 #include "base/sys_info.h" 12 #include "base/sys_info.h"
12 #include "remoting/base/util.h" 13 #include "remoting/base/util.h"
13 #include "remoting/proto/video.pb.h" 14 #include "remoting/proto/video.pb.h"
14 #include "third_party/libyuv/include/libyuv/convert_from_argb.h" 15 #include "third_party/libyuv/include/libyuv/convert_from_argb.h"
15 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 16 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 17 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
17 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" 18 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
18 19
19 extern "C" { 20 extern "C" {
20 #define VPX_CODEC_DISABLE_COMPAT 1 21 #define VPX_CODEC_DISABLE_COMPAT 1
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set screen content mode"; 144 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set screen content mode";
144 145
145 // Set cyclic refresh (aka "top-off") only for lossy encoding. 146 // Set cyclic refresh (aka "top-off") only for lossy encoding.
146 int aq_mode = lossless_encode ? kVp9AqModeNone : kVp9AqModeCyclicRefresh; 147 int aq_mode = lossless_encode ? kVp9AqModeNone : kVp9AqModeCyclicRefresh;
147 ret = vpx_codec_control(codec, VP9E_SET_AQ_MODE, aq_mode); 148 ret = vpx_codec_control(codec, VP9E_SET_AQ_MODE, aq_mode);
148 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set aq mode"; 149 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set aq mode";
149 } 150 }
150 151
151 void FreeImageIfMismatched(bool use_i444, 152 void FreeImageIfMismatched(bool use_i444,
152 const webrtc::DesktopSize& size, 153 const webrtc::DesktopSize& size,
153 scoped_ptr<vpx_image_t>* out_image, 154 std::unique_ptr<vpx_image_t>* out_image,
154 scoped_ptr<uint8_t[]>* out_image_buffer) { 155 std::unique_ptr<uint8_t[]>* out_image_buffer) {
155 if (*out_image) { 156 if (*out_image) {
156 const vpx_img_fmt_t desired_fmt = 157 const vpx_img_fmt_t desired_fmt =
157 use_i444 ? VPX_IMG_FMT_I444 : VPX_IMG_FMT_I420; 158 use_i444 ? VPX_IMG_FMT_I444 : VPX_IMG_FMT_I420;
158 if (!size.equals(webrtc::DesktopSize((*out_image)->w, (*out_image)->h)) || 159 if (!size.equals(webrtc::DesktopSize((*out_image)->w, (*out_image)->h)) ||
159 (*out_image)->fmt != desired_fmt) { 160 (*out_image)->fmt != desired_fmt) {
160 out_image_buffer->reset(); 161 out_image_buffer->reset();
161 out_image->reset(); 162 out_image->reset();
162 } 163 }
163 } 164 }
164 } 165 }
165 166
166 void CreateImage(bool use_i444, 167 void CreateImage(bool use_i444,
167 const webrtc::DesktopSize& size, 168 const webrtc::DesktopSize& size,
168 scoped_ptr<vpx_image_t>* out_image, 169 std::unique_ptr<vpx_image_t>* out_image,
169 scoped_ptr<uint8_t[]>* out_image_buffer) { 170 std::unique_ptr<uint8_t[]>* out_image_buffer) {
170 DCHECK(!size.is_empty()); 171 DCHECK(!size.is_empty());
171 DCHECK(!*out_image_buffer); 172 DCHECK(!*out_image_buffer);
172 DCHECK(!*out_image); 173 DCHECK(!*out_image);
173 174
174 scoped_ptr<vpx_image_t> image(new vpx_image_t()); 175 std::unique_ptr<vpx_image_t> image(new vpx_image_t());
175 memset(image.get(), 0, sizeof(vpx_image_t)); 176 memset(image.get(), 0, sizeof(vpx_image_t));
176 177
177 // libvpx seems to require both to be assigned. 178 // libvpx seems to require both to be assigned.
178 image->d_w = size.width(); 179 image->d_w = size.width();
179 image->w = size.width(); 180 image->w = size.width();
180 image->d_h = size.height(); 181 image->d_h = size.height();
181 image->h = size.height(); 182 image->h = size.height();
182 183
183 // libvpx should derive chroma shifts from|fmt| but currently has a bug: 184 // libvpx should derive chroma shifts from|fmt| but currently has a bug:
184 // https://code.google.com/p/webm/issues/detail?id=627 185 // https://code.google.com/p/webm/issues/detail?id=627
(...skipping 17 matching lines...) Expand all
202 // if the image is not padded out to the next macroblock: crbug.com/119633. 203 // if the image is not padded out to the next macroblock: crbug.com/119633.
203 // Pad the Y, U and V planes' height out to compensate. 204 // Pad the Y, U and V planes' height out to compensate.
204 // Assuming macroblocks are 16x16, aligning the planes' strides above also 205 // Assuming macroblocks are 16x16, aligning the planes' strides above also
205 // macroblock aligned them. 206 // macroblock aligned them.
206 static_assert(kMacroBlockSize == 16, "macroblock_size_not_16"); 207 static_assert(kMacroBlockSize == 16, "macroblock_size_not_16");
207 const int y_rows = ((image->h - 1) & ~(kMacroBlockSize-1)) + kMacroBlockSize; 208 const int y_rows = ((image->h - 1) & ~(kMacroBlockSize-1)) + kMacroBlockSize;
208 const int uv_rows = y_rows >> image->y_chroma_shift; 209 const int uv_rows = y_rows >> image->y_chroma_shift;
209 210
210 // Allocate a YUV buffer large enough for the aligned data & padding. 211 // Allocate a YUV buffer large enough for the aligned data & padding.
211 const int buffer_size = y_stride * y_rows + 2*uv_stride * uv_rows; 212 const int buffer_size = y_stride * y_rows + 2*uv_stride * uv_rows;
212 scoped_ptr<uint8_t[]> image_buffer(new uint8_t[buffer_size]); 213 std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[buffer_size]);
213 214
214 // Reset image value to 128 so we just need to fill in the y plane. 215 // Reset image value to 128 so we just need to fill in the y plane.
215 memset(image_buffer.get(), 128, buffer_size); 216 memset(image_buffer.get(), 128, buffer_size);
216 217
217 // Fill in the information for |image_|. 218 // Fill in the information for |image_|.
218 unsigned char* uchar_buffer = 219 unsigned char* uchar_buffer =
219 reinterpret_cast<unsigned char*>(image_buffer.get()); 220 reinterpret_cast<unsigned char*>(image_buffer.get());
220 image->planes[0] = uchar_buffer; 221 image->planes[0] = uchar_buffer;
221 image->planes[1] = image->planes[0] + y_stride * y_rows; 222 image->planes[1] = image->planes[0] + y_stride * y_rows;
222 image->planes[2] = image->planes[1] + uv_stride * uv_rows; 223 image->planes[2] = image->planes[1] + uv_stride * uv_rows;
223 image->stride[0] = y_stride; 224 image->stride[0] = y_stride;
224 image->stride[1] = uv_stride; 225 image->stride[1] = uv_stride;
225 image->stride[2] = uv_stride; 226 image->stride[2] = uv_stride;
226 227
227 *out_image = std::move(image); 228 *out_image = std::move(image);
228 *out_image_buffer = std::move(image_buffer); 229 *out_image_buffer = std::move(image_buffer);
229 } 230 }
230 231
231 } // namespace 232 } // namespace
232 233
233 // static 234 // static
234 scoped_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP8() { 235 std::unique_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP8() {
235 return make_scoped_ptr(new VideoEncoderVpx(false)); 236 return base::WrapUnique(new VideoEncoderVpx(false));
236 } 237 }
237 238
238 // static 239 // static
239 scoped_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP9() { 240 std::unique_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP9() {
240 return make_scoped_ptr(new VideoEncoderVpx(true)); 241 return base::WrapUnique(new VideoEncoderVpx(true));
241 } 242 }
242 243
243 VideoEncoderVpx::~VideoEncoderVpx() {} 244 VideoEncoderVpx::~VideoEncoderVpx() {}
244 245
245 void VideoEncoderVpx::SetTickClockForTests(base::TickClock* tick_clock) { 246 void VideoEncoderVpx::SetTickClockForTests(base::TickClock* tick_clock) {
246 clock_ = tick_clock; 247 clock_ = tick_clock;
247 } 248 }
248 249
249 void VideoEncoderVpx::SetLosslessEncode(bool want_lossless) { 250 void VideoEncoderVpx::SetLosslessEncode(bool want_lossless) {
250 if (use_vp9_ && (want_lossless != lossless_encode_)) { 251 if (use_vp9_ && (want_lossless != lossless_encode_)) {
251 lossless_encode_ = want_lossless; 252 lossless_encode_ = want_lossless;
252 if (codec_) 253 if (codec_)
253 Configure(webrtc::DesktopSize(codec_->config.enc->g_w, 254 Configure(webrtc::DesktopSize(codec_->config.enc->g_w,
254 codec_->config.enc->g_h)); 255 codec_->config.enc->g_h));
255 } 256 }
256 } 257 }
257 258
258 void VideoEncoderVpx::SetLosslessColor(bool want_lossless) { 259 void VideoEncoderVpx::SetLosslessColor(bool want_lossless) {
259 if (use_vp9_ && (want_lossless != lossless_color_)) { 260 if (use_vp9_ && (want_lossless != lossless_color_)) {
260 lossless_color_ = want_lossless; 261 lossless_color_ = want_lossless;
261 // TODO(wez): Switch to ConfigureCodec() path once libvpx supports it. 262 // TODO(wez): Switch to ConfigureCodec() path once libvpx supports it.
262 // See https://code.google.com/p/webm/issues/detail?id=913. 263 // See https://code.google.com/p/webm/issues/detail?id=913.
263 //if (codec_) 264 //if (codec_)
264 // Configure(webrtc::DesktopSize(codec_->config.enc->g_w, 265 // Configure(webrtc::DesktopSize(codec_->config.enc->g_w,
265 // codec_->config.enc->g_h)); 266 // codec_->config.enc->g_h));
266 codec_.reset(); 267 codec_.reset();
267 } 268 }
268 } 269 }
269 270
270 scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( 271 std::unique_ptr<VideoPacket> VideoEncoderVpx::Encode(
271 const webrtc::DesktopFrame& frame) { 272 const webrtc::DesktopFrame& frame) {
272 DCHECK_LE(32, frame.size().width()); 273 DCHECK_LE(32, frame.size().width());
273 DCHECK_LE(32, frame.size().height()); 274 DCHECK_LE(32, frame.size().height());
274 275
275 // If there is nothing to encode, and nothing to top-off, then return nothing. 276 // If there is nothing to encode, and nothing to top-off, then return nothing.
276 if (frame.updated_region().is_empty() && !encode_unchanged_frame_) 277 if (frame.updated_region().is_empty() && !encode_unchanged_frame_)
277 return nullptr; 278 return nullptr;
278 279
279 // Create or reconfigure the codec to match the size of |frame|. 280 // Create or reconfigure the codec to match the size of |frame|.
280 if (!codec_ || 281 if (!codec_ ||
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 // If the encoder output no changes then there's nothing left to top-off. 319 // If the encoder output no changes then there's nothing left to top-off.
319 encode_unchanged_frame_ = !updated_region.is_empty(); 320 encode_unchanged_frame_ = !updated_region.is_empty();
320 } 321 }
321 322
322 // Read the encoded data. 323 // Read the encoded data.
323 vpx_codec_iter_t iter = nullptr; 324 vpx_codec_iter_t iter = nullptr;
324 bool got_data = false; 325 bool got_data = false;
325 326
326 // TODO(hclam): Make sure we get exactly one frame from the packet. 327 // TODO(hclam): Make sure we get exactly one frame from the packet.
327 // TODO(hclam): We should provide the output buffer to avoid one copy. 328 // TODO(hclam): We should provide the output buffer to avoid one copy.
328 scoped_ptr<VideoPacket> packet( 329 std::unique_ptr<VideoPacket> packet(
329 helper_.CreateVideoPacketWithUpdatedRegion(frame, updated_region)); 330 helper_.CreateVideoPacketWithUpdatedRegion(frame, updated_region));
330 packet->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8); 331 packet->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8);
331 332
332 while (!got_data) { 333 while (!got_data) {
333 const vpx_codec_cx_pkt_t* vpx_packet = 334 const vpx_codec_cx_pkt_t* vpx_packet =
334 vpx_codec_get_cx_data(codec_.get(), &iter); 335 vpx_codec_get_cx_data(codec_.get(), &iter);
335 if (!vpx_packet) 336 if (!vpx_packet)
336 continue; 337 continue;
337 338
338 switch (vpx_packet->kind) { 339 switch (vpx_packet->kind) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 kMacroBlockSize * (y + 1))); 542 kMacroBlockSize * (y + 1)));
542 } 543 }
543 x0 = x1 + 1; 544 x0 = x1 + 1;
544 } 545 }
545 } 546 }
546 updated_region->IntersectWith( 547 updated_region->IntersectWith(
547 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); 548 webrtc::DesktopRect::MakeWH(image_->w, image_->h));
548 } 549 }
549 550
550 } // namespace remoting 551 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/codec/video_encoder_vpx.h ('k') | remoting/codec/video_encoder_vpx_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698