15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <GLES2/gl2.h> 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <GLES2/gl2ext.h> 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <string.h> 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <vector> 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/c/ppb_opengles2.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/completion_callback.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/graphics_3d.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/graphics_3d_client.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/instance.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/media_stream_video_track.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/module.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/rect.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/var.h" 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ppapi/cpp/var_dictionary.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/video_frame.h" 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// When compiling natively on Windows, PostMessage can be #define-d to 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// something else. 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef PostMessage 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#undef PostMessage 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Assert |context_| isn't holding any GL Errors. Done as a macro instead of a 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// function to preserve line number information in the failure message. 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define AssertNoGLError() \ 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch PP_DCHECK(!glGetError()); 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This object is the global object representing this plugin library as long 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// as it is loaded. 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MediaStreamVideoModule : public pp::Module { 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamVideoModule() : pp::Module() {} 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~MediaStreamVideoModule() {} 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual pp::Instance* CreateInstance(PP_Instance instance); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MediaStreamVideoDemoInstance : public pp::Instance, 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public pp::Graphics3DClient { 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamVideoDemoInstance(PP_Instance instance, pp::Module* module); 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~MediaStreamVideoDemoInstance(); 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // pp::Instance implementation (see PPP_Instance). 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void DidChangeView(const pp::Rect& position, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const pp::Rect& clip_ignored); 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void HandleMessage(const pp::Var& message_data); 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // pp::Graphics3DClient implementation. 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Graphics3DContextLost() { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) InitGL(); 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTextures(); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Render(); 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void DrawYUV(); 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void DrawRGB(); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Render(); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // GL-related functions. 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void InitGL(); 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GLuint CreateTexture(int32_t width, int32_t height, int unit, bool rgba); 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CreateGLObjects(); 76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch void CreateShader(GLuint program, GLenum type, const char* source); 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PaintFinished(int32_t result); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void CreateTextures(); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void ConfigureTrack(); 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // MediaStreamVideoTrack callbacks. 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void OnConfigure(int32_t result); 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnGetFrame(int32_t result, pp::VideoFrame frame); 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Size position_size_; 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool is_painting_; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool needs_paint_; 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_bgra_; 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GLuint program_yuv_; 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GLuint program_rgb_; 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GLuint buffer_; 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint texture_y_; 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint texture_u_; 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint texture_v_; 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GLuint texture_rgb_; 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::MediaStreamVideoTrack video_track_; 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::CompletionCallbackFactory<MediaStreamVideoDemoInstance> callback_factory_; 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<int32_t> attrib_list_; 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // MediaStreamVideoTrack attributes: 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool need_config_; 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PP_VideoFrame_Format attrib_format_; 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int32_t attrib_width_; 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int32_t attrib_height_; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Owned data. 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Graphics3D* context_; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Size frame_size_; 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MediaStreamVideoDemoInstance::MediaStreamVideoDemoInstance( 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_Instance instance, pp::Module* module) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : pp::Instance(instance), 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Graphics3DClient(this), 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_painting_(false), 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) needs_paint_(false), 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_bgra_(false), 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) texture_y_(0), 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) texture_u_(0), 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) texture_v_(0), 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) texture_rgb_(0), 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_factory_(this), 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) need_config_(false), 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_format_(PP_VIDEOFRAME_FORMAT_I420), 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_width_(0), 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_height_(0), 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context_(NULL) { 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) { 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Unable to initialize GL PPAPI!")); 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch assert(false); 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MediaStreamVideoDemoInstance::~MediaStreamVideoDemoInstance() { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete context_; 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamVideoDemoInstance::DidChangeView( 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const pp::Rect& position, const pp::Rect& clip_ignored) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (position.width() == 0 || position.height() == 0) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (position.size() == position_size_) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) position_size_ = position.size(); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Initialize graphics. 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) InitGL(); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Render(); 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamVideoDemoInstance::HandleMessage(const pp::Var& var_message) { 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!var_message.is_dictionary()) { 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Invalid message!")); 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pp::VarDictionary var_dictionary_message(var_message); 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string command = var_dictionary_message.Get("command").AsString(); 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (command == "init") { 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pp::Var var_track = var_dictionary_message.Get("track"); 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!var_track.is_resource()) 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pp::Resource resource_track = var_track.AsResource(); 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) video_track_ = pp::MediaStreamVideoTrack(resource_track); 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ConfigureTrack(); 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (command == "format") { 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string str_format = var_dictionary_message.Get("format").AsString(); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (str_format == "YV12") { 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_format_ = PP_VIDEOFRAME_FORMAT_YV12; 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (str_format == "I420") { 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_format_ = PP_VIDEOFRAME_FORMAT_I420; 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (str_format == "BGRA") { 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_format_ = PP_VIDEOFRAME_FORMAT_BGRA; 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_format_ = PP_VIDEOFRAME_FORMAT_UNKNOWN; 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) need_config_ = true; 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (command == "size") { 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_width_ = var_dictionary_message.Get("width").AsInt(); 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) attrib_height_ = var_dictionary_message.Get("height").AsInt(); 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) need_config_ = true; 186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Invalid command!")); 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamVideoDemoInstance::InitGL() { 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_DCHECK(position_size_.width() && position_size_.height()); 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_painting_ = false; 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete context_; 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32_t attributes[] = { 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0, 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_RED_SIZE, 8, 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0, 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_SAMPLES, 0, 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_WIDTH, position_size_.width(), 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_HEIGHT, position_size_.height(), 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_GRAPHICS3DATTRIB_NONE, 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context_ = new pp::Graphics3D(this, attributes); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_DCHECK(!context_->is_null()); 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glSetCurrentContextPPAPI(context_->pp_resource()); 213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Set viewport window size and clear color bit. 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glClearColor(1, 0, 0, 1); 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glClear(GL_COLOR_BUFFER_BIT); 217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glViewport(0, 0, position_size_.width(), position_size_.height()); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BindGraphics(*context_); 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssertNoGLError(); 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateGLObjects(); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamVideoDemoInstance::DrawYUV() { 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static const float kColorMatrix[9] = { 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1.1643828125f, 1.1643828125f, 1.1643828125f, 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0.0f, -0.39176171875f, 2.017234375f, 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1.59602734375f, -0.81296875f, 0.0f 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glUseProgram(program_yuv_); 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glUniform1i(glGetUniformLocation(program_yuv_, "y_texture"), 0); 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glUniform1i(glGetUniformLocation(program_yuv_, "u_texture"), 1); 235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glUniform1i(glGetUniformLocation(program_yuv_, "v_texture"), 2); 236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glUniformMatrix3fv(glGetUniformLocation(program_yuv_, "color_matrix"), 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1, GL_FALSE, kColorMatrix); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AssertNoGLError(); 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLint pos_location = glGetAttribLocation(program_yuv_, "a_position"); 241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLint tc_location = glGetAttribLocation(program_yuv_, "a_texCoord"); 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AssertNoGLError(); 243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glEnableVertexAttribArray(pos_location); 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, 0); 245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glEnableVertexAttribArray(tc_location); 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<float*>(0) + 16); // Skip position coordinates. 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AssertNoGLError(); 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AssertNoGLError(); 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamVideoDemoInstance::DrawRGB() { 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glUseProgram(program_rgb_); 256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glUniform1i(glGetUniformLocation(program_rgb_, "rgb_texture"), 3); 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AssertNoGLError(); 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLint pos_location = glGetAttribLocation(program_rgb_, "a_position"); 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLint tc_location = glGetAttribLocation(program_rgb_, "a_texCoord"); 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AssertNoGLError(); 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glEnableVertexAttribArray(pos_location); 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, 0); 264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glEnableVertexAttribArray(tc_location); 265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<float*>(0) + 16); // Skip position coordinates. 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AssertNoGLError(); 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamVideoDemoInstance::Render() { 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_DCHECK(!is_painting_); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_painting_ = true; 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) needs_paint_ = false; 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (texture_y_) { 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DrawRGB(); 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DrawYUV(); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glClear(GL_COLOR_BUFFER_BIT); 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::CompletionCallback cb = callback_factory_.NewCallback( 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &MediaStreamVideoDemoInstance::PaintFinished); 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context_->SwapBuffers(cb); 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamVideoDemoInstance::PaintFinished(int32_t result) { 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_painting_ = false; 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (needs_paint_) 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Render(); 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GLuint MediaStreamVideoDemoInstance::CreateTexture( 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int32_t width, int32_t height, int unit, bool rgba) { 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint texture_id; 297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glGenTextures(1, &texture_id); 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssertNoGLError(); 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Assign parameters. 301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glActiveTexture(GL_TEXTURE0 + unit); 302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glBindTexture(GL_TEXTURE_2D, texture_id); 303c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 305c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 306c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Allocate texture. 308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexImage2D(GL_TEXTURE_2D, 0, 309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch rgba ? GL_BGRA_EXT : GL_LUMINANCE, 310c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch width, height, 0, 311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch rgba ? GL_BGRA_EXT : GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssertNoGLError(); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return texture_id; 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamVideoDemoInstance::CreateGLObjects() { 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Code and constants for shader. 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const char kVertexShader[] = 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "varying vec2 v_texCoord; \n" 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "attribute vec4 a_position; \n" 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "attribute vec2 a_texCoord; \n" 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "void main() \n" 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "{ \n" 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " v_texCoord = a_texCoord; \n" 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " gl_Position = a_position; \n" 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "}"; 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static const char kFragmentShaderYUV[] = 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "precision mediump float; \n" 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "varying vec2 v_texCoord; \n" 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "uniform sampler2D y_texture; \n" 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "uniform sampler2D u_texture; \n" 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "uniform sampler2D v_texture; \n" 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "uniform mat3 color_matrix; \n" 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "void main() \n" 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "{ \n" 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " vec3 yuv; \n" 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " yuv.x = texture2D(y_texture, v_texCoord).r; \n" 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " yuv.y = texture2D(u_texture, v_texCoord).r; \n" 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " yuv.z = texture2D(v_texture, v_texCoord).r; \n" 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " vec3 rgb = color_matrix * (yuv - vec3(0.0625, 0.5, 0.5));\n" 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " gl_FragColor = vec4(rgb, 1.0); \n" 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "}"; 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static const char kFragmentShaderRGB[] = 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "precision mediump float; \n" 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "varying vec2 v_texCoord; \n" 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "uniform sampler2D rgb_texture; \n" 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "void main() \n" 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "{ \n" 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " gl_FragColor = texture2D(rgb_texture, v_texCoord); \n" 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "}"; 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Create shader programs. 355c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch program_yuv_ = glCreateProgram(); 356c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CreateShader(program_yuv_, GL_VERTEX_SHADER, kVertexShader); 357c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CreateShader(program_yuv_, GL_FRAGMENT_SHADER, kFragmentShaderYUV); 358c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glLinkProgram(program_yuv_); 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AssertNoGLError(); 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 361c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch program_rgb_ = glCreateProgram(); 362c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CreateShader(program_rgb_, GL_VERTEX_SHADER, kVertexShader); 363c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CreateShader(program_rgb_, GL_FRAGMENT_SHADER, kFragmentShaderRGB); 364c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glLinkProgram(program_rgb_); 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssertNoGLError(); 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Assign vertex positions and texture coordinates to buffers for use in 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // shader program. 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const float kVertices[] = { 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) -1, 1, -1, -1, 0, 1, 0, -1, // Position coordinates. 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0, 1, 0, -1, 1, 1, 1, -1, // Position coordinates. 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0, 0, 0, 1, 1, 0, 1, 1, // Texture coordinates. 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 0, 0, 1, 1, 0, 1, 1, // Texture coordinates. 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 376c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glGenBuffers(1, &buffer_); 377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glBindBuffer(GL_ARRAY_BUFFER, buffer_); 378c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, GL_STATIC_DRAW); 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssertNoGLError(); 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamVideoDemoInstance::CreateShader( 383c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLuint program, GLenum type, const char* source) { 384c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLuint shader = glCreateShader(type); 385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLint length = static_cast<GLint>(strlen(source) + 1); 386c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glShaderSource(shader, 1, &source, &length); 387c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glCompileShader(shader); 388c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glAttachShader(program, shader); 389c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glDeleteShader(shader); 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamVideoDemoInstance::CreateTextures() { 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32_t width = frame_size_.width(); 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32_t height = frame_size_.height(); 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (width == 0 || height == 0) 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (texture_y_) 398c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glDeleteTextures(1, &texture_y_); 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (texture_u_) 400c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glDeleteTextures(1, &texture_u_); 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (texture_v_) 402c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glDeleteTextures(1, &texture_v_); 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (texture_rgb_) 404c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glDeleteTextures(1, &texture_rgb_); 405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) texture_y_ = CreateTexture(width, height, 0, false); 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) texture_u_ = CreateTexture(width / 2, height / 2, 1, false); 408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) texture_v_ = CreateTexture(width / 2, height / 2, 2, false); 409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) texture_rgb_ = CreateTexture(width, height, 3, true); 410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamVideoDemoInstance::ConfigureTrack() { 413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const int32_t attrib_list[] = { 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT, attrib_format_, 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PP_MEDIASTREAMVIDEOTRACK_ATTRIB_WIDTH, attrib_width_, 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PP_MEDIASTREAMVIDEOTRACK_ATTRIB_HEIGHT, attrib_height_, 417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE 418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) video_track_.Configure(attrib_list, callback_factory_.NewCallback( 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &MediaStreamVideoDemoInstance::OnConfigure)); 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamVideoDemoInstance::OnConfigure(int32_t result) { 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) video_track_.GetFrame(callback_factory_.NewCallbackWithOutput( 425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &MediaStreamVideoDemoInstance::OnGetFrame)); 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamVideoDemoInstance::OnGetFrame( 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32_t result, pp::VideoFrame frame) { 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result != PP_OK) 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* data = static_cast<const char*>(frame.GetDataBuffer()); 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Size size; 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame.GetSize(&size); 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (size != frame_size_) { 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame_size_ = size; 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTextures(); 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_bgra_ = (frame.GetFormat() == PP_VIDEOFRAME_FORMAT_BGRA); 442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32_t width = frame_size_.width(); 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32_t height = frame_size_.height(); 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!is_bgra_) { 446c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glActiveTexture(GL_TEXTURE0); 447c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, 448c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data += width * height; 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) width /= 2; 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) height /= 2; 453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 454c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glActiveTexture(GL_TEXTURE1); 455c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, 456c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data += width * height; 459c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glActiveTexture(GL_TEXTURE2); 460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, 461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 463c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glActiveTexture(GL_TEXTURE3); 464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, 465c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GL_BGRA_EXT, GL_UNSIGNED_BYTE, data); 466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_painting_) 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) needs_paint_ = true; 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Render(); 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) video_track_.RecycleFrame(frame); 474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (need_config_) { 475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ConfigureTrack(); 476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) need_config_ = false; 477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) video_track_.GetFrame(callback_factory_.NewCallbackWithOutput( 479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &MediaStreamVideoDemoInstance::OnGetFrame)); 480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)pp::Instance* MediaStreamVideoModule::CreateInstance(PP_Instance instance) { 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new MediaStreamVideoDemoInstance(instance, this); 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // anonymous namespace 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace pp { 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Factory function for your specialization of the Module object. 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Module* CreateModule() { 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new MediaStreamVideoModule(); 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace pp 495