OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/tools/player_x11/gles_video_renderer.h" | 5 #include "media/tools/player_x11/gles_video_renderer.h" |
6 | 6 |
7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
8 #include <EGL/eglext.h> | 8 #include <EGL/eglext.h> |
9 #include <X11/Xutil.h> | 9 #include <X11/Xutil.h> |
10 #include <X11/extensions/Xrender.h> | 10 #include <X11/extensions/Xrender.h> |
(...skipping 26 matching lines...) Expand all Loading... |
37 const media::MediaFormat& media_format) { | 37 const media::MediaFormat& media_format) { |
38 int width = 0; | 38 int width = 0; |
39 int height = 0; | 39 int height = 0; |
40 bool uses_egl_image_ = false; | 40 bool uses_egl_image_ = false; |
41 return ParseMediaFormat(media_format, &width, &height, &uses_egl_image_); | 41 return ParseMediaFormat(media_format, &width, &height, &uses_egl_image_); |
42 } | 42 } |
43 | 43 |
44 void GlesVideoRenderer::OnStop() { | 44 void GlesVideoRenderer::OnStop() { |
45 // TODO(hclam): Context switching seems to be broek so the following | 45 // TODO(hclam): Context switching seems to be broek so the following |
46 // calls may fail. Need to fix them. | 46 // calls may fail. Need to fix them. |
| 47 eglMakeCurrent(egl_display_, EGL_NO_SURFACE, |
| 48 EGL_NO_SURFACE, EGL_NO_CONTEXT); |
47 for (size_t i = 0; i < egl_frames_.size(); ++i) { | 49 for (size_t i = 0; i < egl_frames_.size(); ++i) { |
48 scoped_refptr<media::VideoFrame> frame = egl_frames_[i].first; | 50 scoped_refptr<media::VideoFrame> frame = egl_frames_[i].first; |
49 if (frame->private_buffer()) | 51 if (frame->private_buffer()) |
50 egl_destroy_image_khr_(egl_display_, frame->private_buffer()); | 52 egl_destroy_image_khr_(egl_display_, frame->private_buffer()); |
51 if (egl_frames_[i].second) | 53 if (egl_frames_[i].second) |
52 glDeleteTextures(1, &egl_frames_[i].second); | 54 glDeleteTextures(1, &egl_frames_[i].second); |
53 } | 55 } |
54 egl_frames_.clear(); | 56 egl_frames_.clear(); |
55 eglMakeCurrent(egl_display_, EGL_NO_SURFACE, | |
56 EGL_NO_SURFACE, EGL_NO_CONTEXT); | |
57 eglDestroyContext(egl_display_, egl_context_); | 57 eglDestroyContext(egl_display_, egl_context_); |
58 eglDestroySurface(egl_display_, egl_surface_); | 58 eglDestroySurface(egl_display_, egl_surface_); |
59 } | 59 } |
60 | 60 |
61 // Matrix used for the YUV to RGB conversion. | 61 // Matrix used for the YUV to RGB conversion. |
62 static const float kYUV2RGB[9] = { | 62 static const float kYUV2RGB[9] = { |
63 1.f, 1.f, 1.f, | 63 1.f, 1.f, 1.f, |
64 0.f, -.344f, 1.772f, | 64 0.f, -.344f, 1.772f, |
65 1.403f, -.714f, 0.f, | 65 1.403f, -.714f, 0.f, |
66 }; | 66 }; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 | 168 |
169 scoped_refptr<media::VideoFrame> video_frame; | 169 scoped_refptr<media::VideoFrame> video_frame; |
170 GetCurrentFrame(&video_frame); | 170 GetCurrentFrame(&video_frame); |
171 | 171 |
172 if (!video_frame.get()) { | 172 if (!video_frame.get()) { |
173 return; | 173 return; |
174 } | 174 } |
175 | 175 |
176 if (uses_egl_image_) { | 176 if (uses_egl_image_) { |
177 if (media::VideoFrame::TYPE_EGL_IMAGE == video_frame->type()) { | 177 if (media::VideoFrame::TYPE_EGL_IMAGE == video_frame->type()) { |
178 glActiveTexture(GL_TEXTURE0); | 178 |
179 EGLImageKHR egl_image = | 179 GLuint texture = FindTexture(video_frame); |
180 reinterpret_cast<EGLImageKHR>(video_frame->private_buffer()); | 180 if (texture) { |
181 gl_eglimage_target_texture2d_oes_(GL_TEXTURE_2D, egl_image); | 181 glActiveTexture(GL_TEXTURE0); |
182 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 182 glBindTexture(GL_TEXTURE_2D, texture); |
183 eglSwapBuffers(egl_display_, egl_surface_); | 183 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 184 eglSwapBuffers(egl_display_, egl_surface_); |
| 185 } |
184 } | 186 } |
185 return; | 187 return; |
186 } | 188 } |
187 | 189 |
188 // Convert YUV frame to RGB. | 190 // Convert YUV frame to RGB. |
189 DCHECK(video_frame->format() == media::VideoFrame::YV12 || | 191 DCHECK(video_frame->format() == media::VideoFrame::YV12 || |
190 video_frame->format() == media::VideoFrame::YV16); | 192 video_frame->format() == media::VideoFrame::YV16); |
191 DCHECK(video_frame->stride(media::VideoFrame::kUPlane) == | 193 DCHECK(video_frame->stride(media::VideoFrame::kUPlane) == |
192 video_frame->stride(media::VideoFrame::kVPlane)); | 194 video_frame->stride(media::VideoFrame::kVPlane)); |
193 DCHECK(video_frame->planes() == media::VideoFrame::kNumYUVPlanes); | 195 DCHECK(video_frame->planes() == media::VideoFrame::kNumYUVPlanes); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 } | 228 } |
227 | 229 |
228 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, | 230 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, |
229 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); | 231 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); |
230 } | 232 } |
231 | 233 |
232 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 234 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
233 eglSwapBuffers(egl_display_, egl_surface_); | 235 eglSwapBuffers(egl_display_, egl_surface_); |
234 } | 236 } |
235 | 237 |
| 238 // find if texture exists corresponding to video_frame |
| 239 GLuint GlesVideoRenderer::FindTexture( |
| 240 scoped_refptr<media::VideoFrame> video_frame) { |
| 241 for (size_t i = 0; i < egl_frames_.size(); ++i) { |
| 242 scoped_refptr<media::VideoFrame> frame = egl_frames_[i].first; |
| 243 if (video_frame->private_buffer() == frame->private_buffer()) |
| 244 return egl_frames_[i].second; |
| 245 } |
| 246 return NULL; |
| 247 } |
| 248 |
236 bool GlesVideoRenderer::InitializeGles() { | 249 bool GlesVideoRenderer::InitializeGles() { |
237 // Resize the window to fit that of the video. | 250 // Resize the window to fit that of the video. |
238 XResizeWindow(display_, window_, width_, height_); | 251 XResizeWindow(display_, window_, width_, height_); |
239 | 252 |
240 egl_display_ = eglGetDisplay(display_); | 253 egl_display_ = eglGetDisplay(display_); |
241 if (eglGetError() != EGL_SUCCESS) { | 254 if (eglGetError() != EGL_SUCCESS) { |
242 DLOG(ERROR) << "eglGetDisplay failed."; | 255 DLOG(ERROR) << "eglGetDisplay failed."; |
243 return false; | 256 return false; |
244 } | 257 } |
245 | 258 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 int len; | 379 int len; |
367 glGetProgramInfoLog(program, kErrorSize - 1, &len, log); | 380 glGetProgramInfoLog(program, kErrorSize - 1, &len, log); |
368 log[kErrorSize - 1] = 0; | 381 log[kErrorSize - 1] = 0; |
369 LOG(FATAL) << log; | 382 LOG(FATAL) << log; |
370 } | 383 } |
371 glUseProgram(program); | 384 glUseProgram(program); |
372 glDeleteProgram(program); | 385 glDeleteProgram(program); |
373 } | 386 } |
374 | 387 |
375 void GlesVideoRenderer::CreateTextureAndProgramEgl() { | 388 void GlesVideoRenderer::CreateTextureAndProgramEgl() { |
376 if (!egl_create_image_khr_) { | 389 if (!egl_create_image_khr_) |
377 egl_create_image_khr_ = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC> | 390 egl_create_image_khr_ = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC> |
378 (eglGetProcAddress("eglCreateImageKHR")); | 391 (eglGetProcAddress("eglCreateImageKHR")); |
379 CHECK(egl_create_image_khr_); | 392 if (!egl_destroy_image_khr_) |
380 } | |
381 if (!egl_destroy_image_khr_) { | |
382 egl_destroy_image_khr_ = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC> | 393 egl_destroy_image_khr_ = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC> |
383 (eglGetProcAddress("eglDestroyImageKHR")); | 394 (eglGetProcAddress("eglDestroyImageKHR")); |
384 CHECK(egl_destroy_image_khr_); | |
385 } | |
386 | |
387 if (!gl_eglimage_target_texture2d_oes_) { | |
388 gl_eglimage_target_texture2d_oes_ = | |
389 reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC> | |
390 (eglGetProcAddress("glEGLImageTargetTexture2DOES")); | |
391 CHECK(gl_eglimage_target_texture2d_oes_); | |
392 } | |
393 | |
394 // TODO(wjia): get count from decoder. | 395 // TODO(wjia): get count from decoder. |
395 for (int i = 0; i < 4; i++) { | 396 for (int i = 0; i < 4; i++) { |
396 GLuint texture; | 397 GLuint texture; |
397 EGLint attrib = EGL_NONE; | 398 EGLint attrib = EGL_NONE; |
398 EGLImageKHR egl_image; | 399 EGLImageKHR egl_image; |
399 | 400 |
400 glGenTextures(1, &texture); | 401 glGenTextures(1, &texture); |
401 glBindTexture(GL_TEXTURE_2D, texture); | 402 glBindTexture(GL_TEXTURE_2D, texture); |
402 glTexImage2D( | 403 glTexImage2D( |
403 GL_TEXTURE_2D, | 404 GL_TEXTURE_2D, |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 | 497 |
497 int pos_location = glGetAttribLocation(program, "in_pos"); | 498 int pos_location = glGetAttribLocation(program, "in_pos"); |
498 glEnableVertexAttribArray(pos_location); | 499 glEnableVertexAttribArray(pos_location); |
499 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); | 500 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); |
500 | 501 |
501 int tc_location = glGetAttribLocation(program, "in_tc"); | 502 int tc_location = glGetAttribLocation(program, "in_tc"); |
502 glEnableVertexAttribArray(tc_location); | 503 glEnableVertexAttribArray(tc_location); |
503 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, | 504 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, |
504 kTextureCoords); | 505 kTextureCoords); |
505 } | 506 } |
OLD | NEW |