15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iostream> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <sstream> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/ppb_console.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_opengles2.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/dev/video_decoder_client_dev.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/dev/video_decoder_dev.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/graphics_3d.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/graphics_3d_client.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/rect.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/examples/video_decode/testdata.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/lib/gl/include/GLES2/gl2.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/lib/gl/include/GLES2/gl2ext.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use assert as a poor-man's CHECK, even in non-debug mode. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Since <assert.h> redefines assert on every inclusion (it doesn't use 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// include-guards), make sure this is the last file #include'd in this file. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef NDEBUG 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assert |context_| isn't holding any GL Errors. Done as a macro instead of a 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function to preserve line number information in the failure message. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define assertNoGLError() \ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!gles2_if_->GetError(context_->pp_resource())); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PictureBufferInfo { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_PictureBuffer_Dev buffer; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLenum texture_target; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Shader { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shader() : program(0), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texcoord_scale_location(0) {} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint program; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint texcoord_scale_location; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoDecodeDemoInstance : public pp::Instance, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public pp::Graphics3DClient, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public pp::VideoDecoderClient_Dev { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecodeDemoInstance(PP_Instance instance, pp::Module* module); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~VideoDecodeDemoInstance(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pp::Instance implementation (see PPP_Instance). 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DidChangeView(const pp::Rect& position, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& clip_ignored); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pp::Graphics3DClient implementation. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Graphics3DContextLost() { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(vrk/fischman): Properly reset after a lost graphics context. In 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // particular need to delete context_ and re-create textures. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Probably have to recreate the decoder from scratch, because old textures 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can still be outstanding in the decoder! 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(false && "Unexpectedly lost graphics context"); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pp::VideoDecoderClient_Dev implementation. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ProvidePictureBuffers( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource decoder, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t req_num_of_bufs, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_Size& dimensions, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t texture_target); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DismissPictureBuffer(PP_Resource decoder, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t picture_buffer_id); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void PictureReady(PP_Resource decoder, const PP_Picture_Dev& picture); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void NotifyError(PP_Resource decoder, PP_VideoDecodeError_Dev error); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum { kNumConcurrentDecodes = 7, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kNumDecoders = 2 }; // Baked into viewport rendering. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A single decoder's client interface. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DecoderClient { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecoderClient(VideoDecodeDemoInstance* gles2, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VideoDecoder_Dev* decoder); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~DecoderClient(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecodeNextNALUs(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Per-decoder implementation of part of pp::VideoDecoderClient_Dev. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ProvidePictureBuffers( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t req_num_of_bufs, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Size dimensions, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t texture_target); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DismissPictureBuffer(int32_t picture_buffer_id); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PictureBufferInfo& GetPictureBufferInfoById(int id); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VideoDecoder_Dev* decoder() { return decoder_; } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecodeNextNALU(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecoderFlushDone(int32_t result); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecodeDemoInstance* gles2_; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VideoDecoder_Dev* decoder_; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallbackFactory<DecoderClient> callback_factory_; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int next_picture_buffer_id_; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int next_bitstream_buffer_id_; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t encoded_data_next_pos_to_decode_; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<int> bitstream_ids_at_decoder_; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of texture buffers indexed by buffer id. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<int, PictureBufferInfo> PictureBufferMap; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PictureBufferMap picture_buffers_by_id_; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of bitstream buffers indexed by id. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<int, pp::Buffer_Dev*> BitstreamBufferMap; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BitstreamBufferMap bitstream_buffers_by_id_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize Video Decoders. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitializeDecoders(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GL-related functions. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitGL(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint CreateTexture(int32_t width, int32_t height, GLenum texture_target); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateGLObjects(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Create2DProgramOnce(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateRectangleARBProgramOnce(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shader CreateProgram(const char* vertex_shader, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* fragment_shader); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateShader(GLuint program, GLenum type, const char* source, int size); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteTexture(GLuint id); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PaintFinished(int32_t result, PP_Resource decoder, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int picture_buffer_id); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Log an error to the developer console and stderr (though the latter may be 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // closed due to sandboxing or blackholed for other reasons) by creating a 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // temporary of this type and streaming to it. Example usage: 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LogError(this).s() << "Hello world: " << 42; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class LogError { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogError(VideoDecodeDemoInstance* demo) : demo_(demo) {} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~LogError() { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& msg = stream_.str(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demo_->console_if_->Log(demo_->pp_instance(), PP_LOGLEVEL_ERROR, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var(msg).pp_var()); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::cerr << msg << std::endl; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Impl note: it would have been nicer to have LogError derive from 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // std::ostringstream so that it can be streamed to directly, but lookup 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rules turn streamed string literals to hex pointers on output. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::ostringstream& s() { return stream_; } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecodeDemoInstance* demo_; // Unowned. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::ostringstream stream_; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size plugin_size_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_painting_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When decode outpaces render, we queue up decoded pictures for later 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // painting. Elements are <decoder,picture>. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<std::pair<PP_Resource, PP_Picture_Dev> > pictures_pending_paint_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_frames_rendered_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_TimeTicks first_frame_delivered_ticks_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_TimeTicks last_swap_request_ticks_; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_TimeTicks swap_ticks_; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallbackFactory<VideoDecodeDemoInstance> callback_factory_; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unowned pointers. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PPB_Console* console_if_; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PPB_Core* core_if_; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PPB_OpenGLES2* gles2_if_; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Owned data. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics3D* context_; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<int, DecoderClient*> Decoders; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Decoders video_decoders_; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shader program to draw GL_TEXTURE_2D target. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shader shader_2d_; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shader shader_rectangle_arb_; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoDecodeDemoInstance::DecoderClient::DecoderClient( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecodeDemoInstance* gles2, pp::VideoDecoder_Dev* decoder) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : gles2_(gles2), decoder_(decoder), callback_factory_(this), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_picture_buffer_id_(0), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_bitstream_buffer_id_(0), encoded_data_next_pos_to_decode_(0) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoDecodeDemoInstance::DecoderClient::~DecoderClient() { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete decoder_; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_ = NULL; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin(); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != bitstream_buffers_by_id_.end(); ++it) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete it->second; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffers_by_id_.clear(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin(); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != picture_buffers_by_id_.end(); ++it) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_->DeleteTexture(it->second.buffer.texture_id); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_buffers_by_id_.clear(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module* module) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pp::Instance(instance), pp::Graphics3DClient(this), 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VideoDecoderClient_Dev(this), 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) is_painting_(false), 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_frames_rendered_(0), 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_frame_delivered_ticks_(-1), 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swap_ticks_(0), 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_factory_(this), 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch console_if_(static_cast<const PPB_Console*>( 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch module->GetBrowserInterface(PPB_CONSOLE_INTERFACE))), 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch core_if_(static_cast<const PPB_Core*>( 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch module->GetBrowserInterface(PPB_CORE_INTERFACE))), 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gles2_if_(static_cast<const PPB_OpenGLES2*>( 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE))), 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_(NULL) { 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch assert(console_if_); 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch assert(core_if_); 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch assert(gles2_if_); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoDecodeDemoInstance::~VideoDecodeDemoInstance() { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shader_2d_.program) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->DeleteProgram(context_->pp_resource(), shader_2d_.program); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shader_rectangle_arb_.program) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->DeleteProgram( 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), shader_rectangle_arb_.program); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Decoders::iterator it = video_decoders_.begin(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != video_decoders_.end(); ++it) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete it->second; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video_decoders_.clear(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete context_; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DidChangeView( 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& position, const pp::Rect& clip_ignored) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (position.width() == 0 || position.height() == 0) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plugin_size_.width()) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(position.size() == plugin_size_); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_size_ = position.size(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize graphics. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitGL(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDecoders(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::InitializeDecoders() { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(video_decoders_.empty()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kNumDecoders; ++i) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecoderClient* client = new DecoderClient( 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, new pp::VideoDecoder_Dev( 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this, *context_, PP_VIDEODECODER_H264PROFILE_MAIN)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!client->decoder()->is_null()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(video_decoders_.insert(std::make_pair( 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client->decoder()->pp_resource(), client)).second); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client->DecodeNextNALUs(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone( 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result, int bitstream_buffer_id) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(bitstream_ids_at_decoder_.erase(bitstream_buffer_id) == 1); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BitstreamBufferMap::iterator it = 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffers_by_id_.find(bitstream_buffer_id); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(it != bitstream_buffers_by_id_.end()); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete it->second; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffers_by_id_.erase(it); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecodeNextNALUs(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone(int32_t result) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(result == PP_OK); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that each bitstream buffer ID we handed to the decoder got handed 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // back to us. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(bitstream_ids_at_decoder_.empty()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete decoder_; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_ = NULL; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pos + 3 < kDataLen && 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded[pos] == 0 && encoded[pos + 1] == 0 && 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded[pos + 2] == 0 && encoded[pos + 3] == 1; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DecoderClient::GetNextNALUBoundary( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start_pos, size_t* end_pos) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(LookingAtNAL(kData, start_pos)); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end_pos = start_pos; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end_pos += 4; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (*end_pos + 3 < kDataLen && 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !LookingAtNAL(kData, *end_pos)) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++*end_pos; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*end_pos + 3 >= kDataLen) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end_pos = kDataLen; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALUs() { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (encoded_data_next_pos_to_decode_ <= kDataLen && 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_ids_at_decoder_.size() < kNumConcurrentDecodes) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecodeNextNALU(); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALU() { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (encoded_data_next_pos_to_decode_ == kDataLen) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++encoded_data_next_pos_to_decode_; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallback cb = callback_factory_.NewCallback( 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->Flush(cb); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start_pos = encoded_data_next_pos_to_decode_; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t end_pos; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetNextNALUBoundary(start_pos, &end_pos); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Buffer_Dev* buffer = new pp::Buffer_Dev(gles2_, end_pos - start_pos); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_VideoBitstreamBuffer_Dev bitstream_buffer; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id = ++next_bitstream_buffer_id_; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffer.id = id; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffer.size = end_pos - start_pos; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffer.data = buffer->pp_resource(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer->data(), kData + start_pos, end_pos - start_pos); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(bitstream_buffers_by_id_.insert(std::make_pair(id, buffer)).second); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallback cb = 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_factory_.NewCallback( 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone, id); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(bitstream_ids_at_decoder_.insert(id).second); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded_data_next_pos_to_decode_ = end_pos; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->Decode(bitstream_buffer, cb); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::ProvidePictureBuffers(PP_Resource decoder, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t req_num_of_bufs, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_Size& dimensions, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t texture_target) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecoderClient* client = video_decoders_[decoder]; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(client); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client->ProvidePictureBuffers(req_num_of_bufs, dimensions, texture_target); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DecoderClient::ProvidePictureBuffers( 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t req_num_of_bufs, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Size dimensions, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t texture_target) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PP_PictureBuffer_Dev> buffers; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 0; i < req_num_of_bufs; ++i) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PictureBufferInfo info; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.buffer.size = dimensions; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.texture_target = texture_target; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.buffer.texture_id = gles2_->CreateTexture( 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dimensions.width, dimensions.height, info.texture_target); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id = ++next_picture_buffer_id_; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.buffer.id = id; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffers.push_back(info.buffer); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(picture_buffers_by_id_.insert(std::make_pair(id, info)).second); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->AssignPictureBuffers(buffers); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PictureBufferInfo& 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoDecodeDemoInstance::DecoderClient::GetPictureBufferInfoById( 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PictureBufferMap::iterator it = picture_buffers_by_id_.find(id); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(it != picture_buffers_by_id_.end()); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return it->second; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder, 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t picture_buffer_id) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecoderClient* client = video_decoders_[decoder]; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(client); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client->DismissPictureBuffer(picture_buffer_id); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer( 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t picture_buffer_id) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_->DeleteTexture(GetPictureBufferInfoById( 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_buffer_id).buffer.texture_id); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_buffers_by_id_.erase(picture_buffer_id); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_Picture_Dev& picture) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_frame_delivered_ticks_ == -1) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_painting_) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pictures_pending_paint_.push_back(std::make_pair(decoder, picture)); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecoderClient* client = video_decoders_[decoder]; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(client); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PictureBufferInfo& info = 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client->GetPictureBufferInfoById(picture.picture_buffer_id); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!is_painting_); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_painting_ = true; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = 0; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y = 0; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (client != video_decoders_.begin()->second) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = plugin_size_.width() / kNumDecoders; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = plugin_size_.height() / kNumDecoders; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info.texture_target == GL_TEXTURE_2D) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Create2DProgramOnce(); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->UseProgram(context_->pp_resource(), shader_2d_.program); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->Uniform2f( 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), shader_2d_.texcoord_scale_location, 1.0, 1.0); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(info.texture_target == GL_TEXTURE_RECTANGLE_ARB); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateRectangleARBProgramOnce(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->UseProgram( 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), shader_rectangle_arb_.program); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->Uniform2f(context_->pp_resource(), 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_rectangle_arb_.texcoord_scale_location, 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.buffer.size.width, 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.buffer.size.height); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->Viewport(context_->pp_resource(), x, y, 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_size_.width() / kNumDecoders, 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_size_.height() / kNumDecoders); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->BindTexture( 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), info.texture_target, info.buffer.texture_id); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->UseProgram(context_->pp_resource(), 0); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallback cb = 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_factory_.NewCallback( 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &VideoDecodeDemoInstance::PaintFinished, decoder, info.buffer.id); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_swap_request_ticks_ = core_if_->GetTimeTicks(); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::NotifyError(PP_Resource decoder, 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_VideoDecodeError_Dev error) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogError(this).s() << "Received error: " << error; 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(false && "Unexpected error; see stderr for details"); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This object is the global object representing this plugin library as long 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as it is loaded. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoDecodeDemoModule : public pp::Module { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecodeDemoModule() : pp::Module() {} 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~VideoDecodeDemoModule() {} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual pp::Instance* CreateInstance(PP_Instance instance) { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new VideoDecodeDemoInstance(instance, this); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::InitGL() { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(plugin_size_.width() && plugin_size_.height()); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_painting_ = false; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!context_); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t context_attributes[] = { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_RED_SIZE, 8, 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0, 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_SAMPLES, 0, 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(), 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(), 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_NONE, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_ = new pp::Graphics3D(this, context_attributes); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!context_->is_null()); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(BindGraphics(*context_)); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear color bit. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateGLObjects(); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::PaintFinished(int32_t result, PP_Resource decoder, 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int picture_buffer_id) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(result == PP_OK); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_painting_ = false; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_frames_rendered_; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_frames_rendered_ % 50 == 0) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogError(this).s() << "Rendered frames: " << num_frames_rendered_ 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", fps: " << fps << ", with average ms/swap of: " 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ms_per_swap; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecoderClient* client = video_decoders_[decoder]; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (client && client->decoder()) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client->decoder()->ReusePictureBuffer(picture_buffer_id); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pictures_pending_paint_.empty()) { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<PP_Resource, PP_Picture_Dev> decoder_picture = 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pictures_pending_paint_.front(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pictures_pending_paint_.pop_front(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PictureReady(decoder_picture.first, decoder_picture.second); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width, 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t height, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLenum texture_target) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint texture_id; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assign parameters. 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->BindTexture(context_->pp_resource(), texture_target, texture_id); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->TexParameteri( 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), texture_target, GL_TEXTURE_MIN_FILTER, 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_NEAREST); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->TexParameteri( 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), texture_target, GL_TEXTURE_MAG_FILTER, 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_NEAREST); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->TexParameterf( 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_S, 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_CLAMP_TO_EDGE); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->TexParameterf( 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_T, 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_CLAMP_TO_EDGE); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (texture_target == GL_TEXTURE_2D) { 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->TexImage2D( 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), texture_target, 0, GL_RGBA, width, height, 0, 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_RGBA, GL_UNSIGNED_BYTE, NULL); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return texture_id; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::DeleteTexture(GLuint id) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::CreateGLObjects() { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assign vertex positions and texture coordinates to buffers for use in 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shader program. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const float kVertices[] = { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates. 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint buffer; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->BufferData(context_->pp_resource(), GL_ARRAY_BUFFER, 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(kVertices), kVertices, GL_STATIC_DRAW); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kVertexShader[] = 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "varying vec2 v_texCoord; \n" 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "attribute vec4 a_position; \n" 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "attribute vec2 a_texCoord; \n" 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "uniform vec2 v_scale; \n" 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void main() \n" 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{ \n" 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " v_texCoord = v_scale * a_texCoord; \n" 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " gl_Position = a_position; \n" 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::Create2DProgramOnce() { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shader_2d_.program) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kFragmentShader2D[] = 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "precision mediump float; \n" 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "varying vec2 v_texCoord; \n" 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "uniform sampler2D s_texture; \n" 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void main() \n" 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{" 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " gl_FragColor = texture2D(s_texture, v_texCoord); \n" 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_2d_ = CreateProgram(kVertexShader, kFragmentShader2D); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::CreateRectangleARBProgramOnce() { 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shader_rectangle_arb_.program) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kFragmentShaderRectangle[] = 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "#extension GL_ARB_texture_rectangle : require\n" 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "precision mediump float; \n" 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "varying vec2 v_texCoord; \n" 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "uniform sampler2DRect s_texture; \n" 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void main() \n" 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{" 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " gl_FragColor = texture2DRect(s_texture, v_texCoord).rgba; \n" 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_rectangle_arb_ = 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProgram(kVertexShader, kFragmentShaderRectangle); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Shader VideoDecodeDemoInstance::CreateProgram(const char* vertex_shader, 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* fragment_shader) { 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shader shader; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create shader program. 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader.program = gles2_if_->CreateProgram(context_->pp_resource()); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateShader(shader.program, GL_VERTEX_SHADER, vertex_shader, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strlen(vertex_shader)); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateShader(shader.program, GL_FRAGMENT_SHADER, fragment_shader, 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strlen(fragment_shader)); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->LinkProgram(context_->pp_resource(), shader.program); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->UseProgram(context_->pp_resource(), shader.program); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->Uniform1i( 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->GetUniformLocation( 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), shader.program, "s_texture"), 0); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader.texcoord_scale_location = gles2_if_->GetUniformLocation( 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), shader.program, "v_scale"); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint pos_location = gles2_if_->GetAttribLocation( 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), shader.program, "a_position"); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint tc_location = gles2_if_->GetAttribLocation( 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), shader.program, "a_texCoord"); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2, 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_FLOAT, GL_FALSE, 0, 0); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->VertexAttribPointer( 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0, 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<float*>(0) + 8); // Skip position coordinates. 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->UseProgram(context_->pp_resource(), 0); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return shader; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecodeDemoInstance::CreateShader( 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint program, GLenum type, const char* source, int size) { 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->CompileShader(context_->pp_resource(), shader); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->AttachShader(context_->pp_resource(), program, shader); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->DeleteShader(context_->pp_resource(), shader); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Factory function for your specialization of the Module object. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Module* CreateModule() { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new VideoDecodeDemoModule(); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace pp 689