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

Side by Side Diff: remoting/client/plugin/pepper_video_renderer_3d.cc

Issue 1411283003: Add workaround for PPB_VideoDecoder not setting visible_rect. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/client/plugin/pepper_video_renderer_3d.h" 5 #include "remoting/client/plugin/pepper_video_renderer_3d.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "ppapi/c/pp_codecs.h" 11 #include "ppapi/c/pp_codecs.h"
12 #include "ppapi/c/ppb_opengles2.h" 12 #include "ppapi/c/ppb_opengles2.h"
13 #include "ppapi/c/ppb_video_decoder.h" 13 #include "ppapi/c/ppb_video_decoder.h"
14 #include "ppapi/cpp/instance.h" 14 #include "ppapi/cpp/instance.h"
15 #include "ppapi/lib/gl/include/GLES2/gl2.h" 15 #include "ppapi/lib/gl/include/GLES2/gl2.h"
16 #include "ppapi/lib/gl/include/GLES2/gl2ext.h" 16 #include "ppapi/lib/gl/include/GLES2/gl2ext.h"
17 #include "remoting/proto/video.pb.h" 17 #include "remoting/proto/video.pb.h"
18 #include "remoting/protocol/performance_tracker.h" 18 #include "remoting/protocol/performance_tracker.h"
19 #include "remoting/protocol/session_config.h" 19 #include "remoting/protocol/session_config.h"
20 20
21 namespace remoting { 21 namespace remoting {
22 22
23 // The implementation here requires that the decoder allocates at least 3 23 // The implementation here requires that the decoder allocates at least 3
24 // pictures. PPB_VideoDecode didn't support this parameter prior to 24 // pictures. PPB_VideoDecoder didn't support this parameter prior to
25 // 1.1, so we have to pass 0 for backwards compatibility with older versions of 25 // 1.1, so we have to pass 0 for backwards compatibility with older versions of
26 // the browser. Currently all API implementations allocate more than 3 buffers 26 // the browser. Currently all API implementations allocate more than 3 buffers
27 // by default. 27 // by default.
28 // 28 //
29 // TODO(sergeyu): Change this to 3 once PPB_VideoDecode v1.1 is enabled on 29 // TODO(sergeyu): Change this to 3 once PPB_VideoDecoder v1.1 is enabled on
30 // stable channel. 30 // stable channel.
Wez 2015/10/19 21:56:16 nit: Is there a bug filed for that work? If so, re
Sergey Ulanov 2015/10/19 22:19:51 Added reference to the bug to get 1.1 API enabled
31 const uint32_t kMinimumPictureCount = 0; // 3 31 const uint32_t kMinimumPictureCount = 0; // 3
32 32
33 class PepperVideoRenderer3D::PendingPacket { 33 class PepperVideoRenderer3D::PendingPacket {
34 public: 34 public:
35 PendingPacket(scoped_ptr<VideoPacket> packet, const base::Closure& done) 35 PendingPacket(scoped_ptr<VideoPacket> packet, const base::Closure& done)
36 : packet_(packet.Pass()), 36 : packet_(packet.Pass()),
37 done_runner_(done) { 37 done_runner_(done) {
38 } 38 }
39 39
40 ~PendingPacket() {} 40 ~PendingPacket() {}
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 webrtc::DesktopRegion dirty_region; 238 webrtc::DesktopRegion dirty_region;
239 for (int i = 0; i < packet->dirty_rects_size(); ++i) { 239 for (int i = 0; i < packet->dirty_rects_size(); ++i) {
240 Rect remoting_rect = packet->dirty_rects(i); 240 Rect remoting_rect = packet->dirty_rects(i);
241 dirty_region.AddRect(webrtc::DesktopRect::MakeXYWH( 241 dirty_region.AddRect(webrtc::DesktopRect::MakeXYWH(
242 remoting_rect.x(), remoting_rect.y(), 242 remoting_rect.x(), remoting_rect.y(),
243 remoting_rect.width(), remoting_rect.height())); 243 remoting_rect.width(), remoting_rect.height()));
244 } 244 }
245 event_handler_->OnVideoFrameDirtyRegion(dirty_region); 245 event_handler_->OnVideoFrameDirtyRegion(dirty_region);
246 } 246 }
247 247
248 if (frame_sizes_) {
249 frame_sizes_->insert(std::make_pair(packet->frame_id(), frame_size_));
250 }
251
248 pending_packets_.push_back( 252 pending_packets_.push_back(
249 new PendingPacket(packet.Pass(), done_runner.Release())); 253 new PendingPacket(packet.Pass(), done_runner.Release()));
250 DecodeNextPacket(); 254 DecodeNextPacket();
251 } 255 }
252 256
253 void PepperVideoRenderer3D::OnInitialized(int32_t result) { 257 void PepperVideoRenderer3D::OnInitialized(int32_t result) {
254 // Assume that VP8 and VP9 codecs are always supported by the browser. 258 // Assume that VP8 and VP9 codecs are always supported by the browser.
255 CHECK_EQ(result, PP_OK) << "VideoDecoder::Initialize() failed: " << result; 259 CHECK_EQ(result, PP_OK) << "VideoDecoder::Initialize() failed: " << result;
256 initialization_finished_ = true; 260 initialization_finished_ = true;
257 261
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 get_picture_pending_ = false; 310 get_picture_pending_ = false;
307 311
308 if (result != PP_OK) { 312 if (result != PP_OK) {
309 LOG(ERROR) << "VideoDecoder::GetPicture() returned " << result; 313 LOG(ERROR) << "VideoDecoder::GetPicture() returned " << result;
310 event_handler_->OnVideoDecodeError(); 314 event_handler_->OnVideoDecodeError();
311 return; 315 return;
312 } 316 }
313 317
314 perf_tracker_->OnFrameDecoded(picture.decode_id); 318 perf_tracker_->OnFrameDecoded(picture.decode_id);
315 319
320 // Workaround crbug.com/542945 by filling in visible_rect if it isn't set.
321 if (picture.visible_rect.size.width == 0 ||
322 picture.visible_rect.size.height == 0 || frame_sizes_) {
323
324 // Enable workaround by creating |frame_sizes_|.
325 if (!frame_sizes_) {
326 LOG(WARNING) << "PPB_VideoDecoder doesn't set visible_rect.";
327 frame_sizes_.reset(new FrameSizesMap());
328 }
329
330 FrameSizesMap::iterator size_it = frame_sizes_->find(picture.decode_id);
331 if (size_it != frame_sizes_->end()) {
332 picture.visible_rect.size.width = size_it->second.width();
333 picture.visible_rect.size.height = size_it->second.height();
334 frame_sizes_->erase(size_it);
335 } else {
336 // For the first few frames |frames_sizes_| will be empty as
337 // |frame_sizes_| is created only after the first picture is received and
338 // it's known that the workaround is necessary. So here we use
339 // |texture_size| as frame size. This may result is some minor visual
340 // artifacts, which will disappear with the next frame processed by
341 // ProcessVideoPacket().
342 picture.visible_rect.size.width = picture.texture_size.width;
343 picture.visible_rect.size.height = picture.texture_size.width;
344 }
345 }
346
316 next_picture_.reset(new Picture(&video_decoder_, picture)); 347 next_picture_.reset(new Picture(&video_decoder_, picture));
317 348
318 PaintIfNeeded(); 349 PaintIfNeeded();
319 GetNextPicture(); 350 GetNextPicture();
320 } 351 }
321 352
322 void PepperVideoRenderer3D::PaintIfNeeded() { 353 void PepperVideoRenderer3D::PaintIfNeeded() {
323 bool need_repaint = next_picture_ || (force_repaint_ && current_picture_); 354 bool need_repaint = next_picture_ || (force_repaint_ && current_picture_);
324 if (paint_pending_ || !need_repaint) 355 if (paint_pending_ || !need_repaint)
325 return; 356 return;
326 357
327 if (next_picture_) 358 if (next_picture_)
328 current_picture_ = next_picture_.Pass(); 359 current_picture_ = next_picture_.Pass();
329 360
330 force_repaint_ = false; 361 force_repaint_ = false;
331 362
332 const PP_VideoPicture& picture = current_picture_->picture(); 363 const PP_VideoPicture& picture = current_picture_->picture();
333 PP_Resource graphics_3d = graphics_.pp_resource(); 364 PP_Resource graphics_3d = graphics_.pp_resource();
334 365
335 EnsureProgramForTexture(picture.texture_target); 366 EnsureProgramForTexture(picture.texture_target);
336 367
337 gles2_if_->UseProgram(graphics_3d, shader_program_); 368 gles2_if_->UseProgram(graphics_3d, shader_program_);
338 369
339 // Calculate v_scale passed to the vertex shader. 370 // Calculate v_scale passed to the vertex shader.
340 double scale_x = picture.visible_rect.size.width; 371 double scale_x = picture.visible_rect.size.width;
341 double scale_y = picture.visible_rect.size.height; 372 double scale_y = picture.visible_rect.size.height;
342 if (picture.texture_target != GL_TEXTURE_RECTANGLE_ARB) { 373 if (picture.texture_target != GL_TEXTURE_RECTANGLE_ARB) {
374 CHECK(picture.texture_size.width > 0 && picture.texture_size.height > 0);
Sergey Ulanov 2015/10/19 21:47:20 These CHECKs will help to diagnose similar issues
343 scale_x /= picture.texture_size.width; 375 scale_x /= picture.texture_size.width;
344 scale_y /= picture.texture_size.height; 376 scale_y /= picture.texture_size.height;
345 } 377 }
346 gles2_if_->Uniform2f(graphics_3d, shader_texcoord_scale_location_, 378 gles2_if_->Uniform2f(graphics_3d, shader_texcoord_scale_location_,
347 scale_x, scale_y); 379 scale_x, scale_y);
348 380
349 // Set viewport position & dimensions. 381 // Set viewport position & dimensions.
350 gles2_if_->Viewport(graphics_3d, 0, 0, view_size_.width(), 382 gles2_if_->Viewport(graphics_3d, 0, 0, view_size_.width(),
351 view_size_.height()); 383 view_size_.height());
352 384
353 // Select the texture unit GL_TEXTURE0. 385 // Select the texture unit GL_TEXTURE0.
354 gles2_if_->ActiveTexture(graphics_3d, GL_TEXTURE0); 386 gles2_if_->ActiveTexture(graphics_3d, GL_TEXTURE0);
355 387
356 // Select the texture. 388 // Select the texture.
357 gles2_if_->BindTexture(graphics_3d, picture.texture_target, 389 gles2_if_->BindTexture(graphics_3d, picture.texture_target,
358 picture.texture_id); 390 picture.texture_id);
359 391
360 // Select linear filter in case the texture needs to be scaled. 392 // Select linear filter in case the texture needs to be scaled.
361 gles2_if_->TexParameteri(graphics_3d, picture.texture_target, 393 gles2_if_->TexParameteri(graphics_3d, picture.texture_target,
362 GL_TEXTURE_MIN_FILTER, GL_LINEAR); 394 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
363 395
364 // When view dimensions are a multiple of the frame size then use 396 // When view dimensions are a multiple of the frame size then use
365 // nearest-neighbor scaling to achieve crisper image. Linear filter is used in 397 // nearest-neighbor scaling to achieve crisper image. Linear filter is used in
366 // all other cases. 398 // all other cases.
367 GLint mag_filter = GL_LINEAR; 399 GLint mag_filter = GL_LINEAR;
400 CHECK(picture.visible_rect.size.width > 0 &&
401 picture.visible_rect.size.height > 0);
368 if (view_size_.width() % picture.visible_rect.size.width == 0 && 402 if (view_size_.width() % picture.visible_rect.size.width == 0 &&
369 view_size_.height() % picture.visible_rect.size.height == 0) { 403 view_size_.height() % picture.visible_rect.size.height == 0) {
370 mag_filter = GL_NEAREST; 404 mag_filter = GL_NEAREST;
371 } 405 }
372 gles2_if_->TexParameteri(graphics_3d, picture.texture_target, 406 gles2_if_->TexParameteri(graphics_3d, picture.texture_target,
373 GL_TEXTURE_MAG_FILTER, mag_filter); 407 GL_TEXTURE_MAG_FILTER, mag_filter);
374 408
375 // Render texture by drawing a triangle strip with 4 vertices. 409 // Render texture by drawing a triangle strip with 4 vertices.
376 gles2_if_->DrawArrays(graphics_3d, GL_TRIANGLE_STRIP, 0, 4); 410 gles2_if_->DrawArrays(graphics_3d, GL_TRIANGLE_STRIP, 0, 4);
377 411
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 gles2_if_->AttachShader(graphics_.pp_resource(), shader_program_, shader); 533 gles2_if_->AttachShader(graphics_.pp_resource(), shader_program_, shader);
500 gles2_if_->DeleteShader(graphics_.pp_resource(), shader); 534 gles2_if_->DeleteShader(graphics_.pp_resource(), shader);
501 } 535 }
502 536
503 void PepperVideoRenderer3D::CheckGLError() { 537 void PepperVideoRenderer3D::CheckGLError() {
504 GLenum error = gles2_if_->GetError(graphics_.pp_resource()); 538 GLenum error = gles2_if_->GetError(graphics_.pp_resource());
505 CHECK_EQ(error, static_cast<GLenum>(GL_NO_ERROR)) << "GL error: " << error; 539 CHECK_EQ(error, static_cast<GLenum>(GL_NO_ERROR)) << "GL error: " << error;
506 } 540 }
507 541
508 } // namespace remoting 542 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698