Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 (crbug.com/520323). |
| 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 get_picture_pending_ = false; | 306 get_picture_pending_ = false; |
| 307 | 307 |
| 308 if (result != PP_OK) { | 308 if (result != PP_OK) { |
| 309 LOG(ERROR) << "VideoDecoder::GetPicture() returned " << result; | 309 LOG(ERROR) << "VideoDecoder::GetPicture() returned " << result; |
| 310 event_handler_->OnVideoDecodeError(); | 310 event_handler_->OnVideoDecodeError(); |
| 311 return; | 311 return; |
| 312 } | 312 } |
| 313 | 313 |
| 314 perf_tracker_->OnFrameDecoded(picture.decode_id); | 314 perf_tracker_->OnFrameDecoded(picture.decode_id); |
| 315 | 315 |
| 316 // Workaround crbug.com/542945 by filling in visible_rect if it isn't set. | |
| 317 if (picture.visible_rect.size.width == 0 || | |
| 318 picture.visible_rect.size.height == 0) { | |
| 319 static bool warning_logged = false; | |
| 320 if (!warning_logged) { | |
| 321 LOG(WARNING) << "PPB_VideoDecoder doesn't set visible_rect."; | |
|
Wez
2015/10/20 04:57:44
What's the point of logging a warning in this case
Sergey Ulanov
2015/10/20 14:37:52
To make it easy to verify if the problem is still
Wez
2015/10/20 17:16:50
You mean easy to see whether the PPAPI has been fi
| |
| 322 warning_logged = true; | |
| 323 } | |
| 324 | |
| 325 picture.visible_rect.size.width = | |
| 326 std::min(frame_size_.width(), picture.texture_size.width); | |
| 327 picture.visible_rect.size.height = | |
| 328 std::min(frame_size_.height(), picture.texture_size.height); | |
| 329 } | |
| 330 | |
| 316 next_picture_.reset(new Picture(&video_decoder_, picture)); | 331 next_picture_.reset(new Picture(&video_decoder_, picture)); |
| 317 | 332 |
| 318 PaintIfNeeded(); | 333 PaintIfNeeded(); |
| 319 GetNextPicture(); | 334 GetNextPicture(); |
| 320 } | 335 } |
| 321 | 336 |
| 322 void PepperVideoRenderer3D::PaintIfNeeded() { | 337 void PepperVideoRenderer3D::PaintIfNeeded() { |
| 323 bool need_repaint = next_picture_ || (force_repaint_ && current_picture_); | 338 bool need_repaint = next_picture_ || (force_repaint_ && current_picture_); |
| 324 if (paint_pending_ || !need_repaint) | 339 if (paint_pending_ || !need_repaint) |
| 325 return; | 340 return; |
| 326 | 341 |
| 327 if (next_picture_) | 342 if (next_picture_) |
| 328 current_picture_ = next_picture_.Pass(); | 343 current_picture_ = next_picture_.Pass(); |
| 329 | 344 |
| 330 force_repaint_ = false; | 345 force_repaint_ = false; |
| 331 | 346 |
| 332 const PP_VideoPicture& picture = current_picture_->picture(); | 347 const PP_VideoPicture& picture = current_picture_->picture(); |
| 333 PP_Resource graphics_3d = graphics_.pp_resource(); | 348 PP_Resource graphics_3d = graphics_.pp_resource(); |
| 334 | 349 |
| 335 EnsureProgramForTexture(picture.texture_target); | 350 EnsureProgramForTexture(picture.texture_target); |
| 336 | 351 |
| 337 gles2_if_->UseProgram(graphics_3d, shader_program_); | 352 gles2_if_->UseProgram(graphics_3d, shader_program_); |
| 338 | 353 |
| 339 // Calculate v_scale passed to the vertex shader. | 354 // Calculate v_scale passed to the vertex shader. |
| 340 double scale_x = picture.visible_rect.size.width; | 355 double scale_x = picture.visible_rect.size.width; |
| 341 double scale_y = picture.visible_rect.size.height; | 356 double scale_y = picture.visible_rect.size.height; |
| 342 if (picture.texture_target != GL_TEXTURE_RECTANGLE_ARB) { | 357 if (picture.texture_target != GL_TEXTURE_RECTANGLE_ARB) { |
| 358 CHECK(picture.texture_size.width > 0 && picture.texture_size.height > 0); | |
| 343 scale_x /= picture.texture_size.width; | 359 scale_x /= picture.texture_size.width; |
| 344 scale_y /= picture.texture_size.height; | 360 scale_y /= picture.texture_size.height; |
| 345 } | 361 } |
| 346 gles2_if_->Uniform2f(graphics_3d, shader_texcoord_scale_location_, | 362 gles2_if_->Uniform2f(graphics_3d, shader_texcoord_scale_location_, |
| 347 scale_x, scale_y); | 363 scale_x, scale_y); |
| 348 | 364 |
| 349 // Set viewport position & dimensions. | 365 // Set viewport position & dimensions. |
| 350 gles2_if_->Viewport(graphics_3d, 0, 0, view_size_.width(), | 366 gles2_if_->Viewport(graphics_3d, 0, 0, view_size_.width(), |
| 351 view_size_.height()); | 367 view_size_.height()); |
| 352 | 368 |
| 353 // Select the texture unit GL_TEXTURE0. | 369 // Select the texture unit GL_TEXTURE0. |
| 354 gles2_if_->ActiveTexture(graphics_3d, GL_TEXTURE0); | 370 gles2_if_->ActiveTexture(graphics_3d, GL_TEXTURE0); |
| 355 | 371 |
| 356 // Select the texture. | 372 // Select the texture. |
| 357 gles2_if_->BindTexture(graphics_3d, picture.texture_target, | 373 gles2_if_->BindTexture(graphics_3d, picture.texture_target, |
| 358 picture.texture_id); | 374 picture.texture_id); |
| 359 | 375 |
| 360 // Select linear filter in case the texture needs to be scaled. | 376 // Select linear filter in case the texture needs to be scaled. |
| 361 gles2_if_->TexParameteri(graphics_3d, picture.texture_target, | 377 gles2_if_->TexParameteri(graphics_3d, picture.texture_target, |
| 362 GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 378 GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 363 | 379 |
| 364 // When view dimensions are a multiple of the frame size then use | 380 // 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 | 381 // nearest-neighbor scaling to achieve crisper image. Linear filter is used in |
| 366 // all other cases. | 382 // all other cases. |
| 367 GLint mag_filter = GL_LINEAR; | 383 GLint mag_filter = GL_LINEAR; |
| 384 CHECK(picture.visible_rect.size.width > 0 && | |
| 385 picture.visible_rect.size.height > 0); | |
| 368 if (view_size_.width() % picture.visible_rect.size.width == 0 && | 386 if (view_size_.width() % picture.visible_rect.size.width == 0 && |
| 369 view_size_.height() % picture.visible_rect.size.height == 0) { | 387 view_size_.height() % picture.visible_rect.size.height == 0) { |
| 370 mag_filter = GL_NEAREST; | 388 mag_filter = GL_NEAREST; |
| 371 } | 389 } |
| 372 gles2_if_->TexParameteri(graphics_3d, picture.texture_target, | 390 gles2_if_->TexParameteri(graphics_3d, picture.texture_target, |
| 373 GL_TEXTURE_MAG_FILTER, mag_filter); | 391 GL_TEXTURE_MAG_FILTER, mag_filter); |
| 374 | 392 |
| 375 // Render texture by drawing a triangle strip with 4 vertices. | 393 // Render texture by drawing a triangle strip with 4 vertices. |
| 376 gles2_if_->DrawArrays(graphics_3d, GL_TRIANGLE_STRIP, 0, 4); | 394 gles2_if_->DrawArrays(graphics_3d, GL_TRIANGLE_STRIP, 0, 4); |
| 377 | 395 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 gles2_if_->AttachShader(graphics_.pp_resource(), shader_program_, shader); | 517 gles2_if_->AttachShader(graphics_.pp_resource(), shader_program_, shader); |
| 500 gles2_if_->DeleteShader(graphics_.pp_resource(), shader); | 518 gles2_if_->DeleteShader(graphics_.pp_resource(), shader); |
| 501 } | 519 } |
| 502 | 520 |
| 503 void PepperVideoRenderer3D::CheckGLError() { | 521 void PepperVideoRenderer3D::CheckGLError() { |
| 504 GLenum error = gles2_if_->GetError(graphics_.pp_resource()); | 522 GLenum error = gles2_if_->GetError(graphics_.pp_resource()); |
| 505 CHECK_EQ(error, static_cast<GLenum>(GL_NO_ERROR)) << "GL error: " << error; | 523 CHECK_EQ(error, static_cast<GLenum>(GL_NO_ERROR)) << "GL error: " << error; |
| 506 } | 524 } |
| 507 | 525 |
| 508 } // namespace remoting | 526 } // namespace remoting |
| OLD | NEW |