Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // The bulk of this file is support code; sorry about that. Here's an overview | 5 // The bulk of this file is support code; sorry about that. Here's an overview |
| 6 // to hopefully help readers of this code: | 6 // to hopefully help readers of this code: |
| 7 // - RenderingHelper is charged with interacting with X11, EGL, and GLES2. | 7 // - RenderingHelper is charged with interacting with X11, EGL, and GLES2. |
| 8 // - ClientState is an enum for the state of the decode client used by the test. | 8 // - ClientState is an enum for the state of the decode client used by the test. |
| 9 // - ClientStateNotification is a barrier abstraction that allows the test code | 9 // - ClientStateNotification is a barrier abstraction that allows the test code |
| 10 // to be written sequentially and wait for the decode client to see certain | 10 // to be written sequentially and wait for the decode client to see certain |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "base/process_util.h" | 31 #include "base/process_util.h" |
| 32 #include "base/stl_util.h" | 32 #include "base/stl_util.h" |
| 33 #include "base/string_number_conversions.h" | 33 #include "base/string_number_conversions.h" |
| 34 #include "base/string_split.h" | 34 #include "base/string_split.h" |
| 35 #include "base/stringize_macros.h" | 35 #include "base/stringize_macros.h" |
| 36 #include "base/synchronization/condition_variable.h" | 36 #include "base/synchronization/condition_variable.h" |
| 37 #include "base/synchronization/lock.h" | 37 #include "base/synchronization/lock.h" |
| 38 #include "base/synchronization/waitable_event.h" | 38 #include "base/synchronization/waitable_event.h" |
| 39 #include "base/threading/thread.h" | 39 #include "base/threading/thread.h" |
| 40 #include "base/utf_string_conversions.h" | 40 #include "base/utf_string_conversions.h" |
| 41 | 41 #include "content/common/gpu/media/rendering_helper.h" |
| 42 #if (!defined(OS_CHROMEOS) || !defined(ARCH_CPU_ARMEL)) && !defined(OS_WIN) | |
| 43 #error The VideoAccelerator tests are only supported on cros/ARM/Windows. | |
| 44 #endif | |
| 45 | 42 |
| 46 #if defined(OS_WIN) | 43 #if defined(OS_WIN) |
| 47 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" | 44 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" |
| 48 #else // OS_WIN | 45 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
| 49 #include "content/common/gpu/media/omx_video_decode_accelerator.h" | 46 #include "content/common/gpu/media/omx_video_decode_accelerator.h" |
| 47 #elif defined(OS_MACOSX) | |
| 48 #include "content/common/gpu/media/mac_video_decode_accelerator.h" | |
| 49 #else | |
| 50 #error The VideoAccelerator tests are not supported on this platform. | |
| 50 #endif // defined(OS_WIN) | 51 #endif // defined(OS_WIN) |
| 51 | 52 |
| 52 #include "third_party/angle/include/EGL/egl.h" | |
| 53 | |
| 54 #if defined(OS_WIN) | |
| 55 #include "ui/gl/gl_bindings.h" | |
| 56 #include "ui/gl/gl_context.h" | |
| 57 #include "ui/gl/gl_implementation.h" | |
| 58 #include "ui/gl/gl_surface.h" | |
| 59 #else // OS_WIN | |
| 60 #include "third_party/angle/include/GLES2/gl2.h" | |
| 61 #endif // OS_WIN | |
| 62 | |
| 63 using media::VideoDecodeAccelerator; | 53 using media::VideoDecodeAccelerator; |
| 54 using video_test_util::RenderingHelper; | |
| 64 | 55 |
| 65 namespace { | 56 namespace { |
| 66 | 57 |
| 67 // Values optionally filled in from flags; see main() below. | 58 // Values optionally filled in from flags; see main() below. |
| 68 // The syntax of this variable is: | 59 // The syntax of this variable is: |
| 69 // filename:width:height:numframes:numNALUs:minFPSwithRender:minFPSnoRender | 60 // filename:width:height:numframes:numNALUs:minFPSwithRender:minFPSnoRender |
| 70 // where only the first field is required. Value details: | 61 // where only the first field is required. Value details: |
| 71 // - |filename| must be an h264 Annex B (NAL) stream. | 62 // - |filename| must be an h264 Annex B (NAL) stream. |
| 72 // - |width| and |height| are in pixels. | 63 // - |width| and |height| are in pixels. |
| 73 // - |numframes| is the number of picture frames in the file. | 64 // - |numframes| is the number of picture frames in the file. |
| 74 // - |numNALUs| is the number of NAL units in the stream. | 65 // - |numNALUs| is the number of NAL units in the stream. |
| 75 // - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds | 66 // - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds |
| 76 // expected to be achieved with and without rendering to the screen, resp. | 67 // expected to be achieved with and without rendering to the screen, resp. |
| 77 // (the latter tests just decode speed). | 68 // (the latter tests just decode speed). |
| 78 // - |profile| is the media::H264Profile set during Initialization. | 69 // - |profile| is the media::H264Profile set during Initialization. |
| 79 // An empty value for a numeric field means "ignore". | 70 // An empty value for a numeric field means "ignore". |
| 71 #if defined(OS_MACOSX) | |
| 72 const FilePath::CharType* test_video_data = | |
| 73 FILE_PATH_LITERAL("test-25fps_high.h264:1280:720:249:252:50:175:4"); | |
| 74 #else | |
| 80 const FilePath::CharType* test_video_data = | 75 const FilePath::CharType* test_video_data = |
| 81 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); | 76 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); |
| 77 #endif | |
| 78 | |
| 79 // AAVC data required to initialize the H.264 video decoder. | |
|
Ami GONE FROM CHROMIUM
2012/05/24 21:30:30
Add TODO to drop this?
sail
2012/05/29 03:45:01
Done.
| |
| 80 const uint8_t MP4_EXTRA_DATA[] = { | |
| 81 0x01, 0x64, 0x00, 0x1f, 0xff, 0xe1, 0x00, 0x19, | |
| 82 0x67, 0x64, 0x00, 0x1f, 0xac, 0x34, 0xec, 0x05, | |
| 83 0x00, 0x5b, 0xa1, 0x00, 0x00, 0x03, 0x00, 0x01, | |
| 84 0x00, 0x00, 0x03, 0x00, 0x32, 0x0f, 0x18, 0x31, | |
| 85 0x38, 0x01, 0x00, 0x05, 0x68, 0xef, 0xb2, 0xc8, | |
| 86 0xb0, | |
| 87 }; | |
| 82 | 88 |
| 83 // Parse |data| into its constituent parts and set the various output fields | 89 // Parse |data| into its constituent parts and set the various output fields |
| 84 // accordingly. CHECK-fails on unexpected or missing required data. | 90 // accordingly. CHECK-fails on unexpected or missing required data. |
| 85 // Unspecified optional fields are set to -1. | 91 // Unspecified optional fields are set to -1. |
| 86 void ParseTestVideoData(FilePath::StringType data, | 92 void ParseTestVideoData(FilePath::StringType data, |
| 87 FilePath::StringType* file_name, | 93 FilePath::StringType* file_name, |
| 88 int* width, int* height, | 94 int* width, int* height, |
| 89 int* num_frames, | 95 int* num_frames, |
| 90 int* num_NALUs, | 96 int* num_NALUs, |
| 91 int* min_fps_render, | 97 int* min_fps_render, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 108 if (!elements[4].empty()) | 114 if (!elements[4].empty()) |
| 109 CHECK(base::StringToInt(elements[4], num_NALUs)); | 115 CHECK(base::StringToInt(elements[4], num_NALUs)); |
| 110 if (!elements[5].empty()) | 116 if (!elements[5].empty()) |
| 111 CHECK(base::StringToInt(elements[5], min_fps_render)); | 117 CHECK(base::StringToInt(elements[5], min_fps_render)); |
| 112 if (!elements[6].empty()) | 118 if (!elements[6].empty()) |
| 113 CHECK(base::StringToInt(elements[6], min_fps_no_render)); | 119 CHECK(base::StringToInt(elements[6], min_fps_no_render)); |
| 114 if (!elements[7].empty()) | 120 if (!elements[7].empty()) |
| 115 CHECK(base::StringToInt(elements[7], profile)); | 121 CHECK(base::StringToInt(elements[7], profile)); |
| 116 } | 122 } |
| 117 | 123 |
| 118 // Provides functionality for managing EGL, GLES2 and UI resources. | |
| 119 // This class is not thread safe and thus all the methods of this class | |
| 120 // (except for ctor/dtor) ensure they're being run on a single thread. | |
| 121 class RenderingHelper { | |
| 122 public: | |
| 123 RenderingHelper(); | |
| 124 ~RenderingHelper(); | |
| 125 | |
| 126 // Initialize all structures to prepare to render to one or more windows of | |
| 127 // the specified dimensions. CHECK-fails if any initialization step fails. | |
| 128 // After this returns, texture creation and rendering can be requested. This | |
| 129 // method can be called multiple times, in which case all previously-acquired | |
| 130 // resources and initializations are discarded. If |suppress_swap_to_display| | |
| 131 // then all the usual work is done, except for the final swap of the EGL | |
| 132 // surface to the display. This cuts test times over 50% so is worth doing | |
| 133 // when testing non-rendering-related aspects. | |
| 134 void Initialize(bool suppress_swap_to_display, int num_windows, int width, | |
| 135 int height, base::WaitableEvent* done); | |
| 136 | |
| 137 // Undo the effects of Initialize() and signal |*done|. | |
| 138 void UnInitialize(base::WaitableEvent* done); | |
| 139 | |
| 140 // Return a newly-created GLES2 texture id rendering to a specific window, and | |
| 141 // signal |*done|. | |
| 142 void CreateTexture(int window_id, GLuint* texture_id, | |
| 143 base::WaitableEvent* done); | |
| 144 | |
| 145 // Render |texture_id| to the screen (unless |suppress_swap_to_display_|). | |
| 146 void RenderTexture(GLuint texture_id); | |
| 147 | |
| 148 // Delete |texture_id|. | |
| 149 void DeleteTexture(GLuint texture_id); | |
| 150 | |
| 151 // Platform specific Init/Uninit. | |
| 152 void PlatformInitialize(); | |
| 153 void PlatformUnInitialize(); | |
| 154 | |
| 155 // Platform specific window creation. | |
| 156 EGLNativeWindowType PlatformCreateWindow(int top_left_x, int top_left_y); | |
| 157 | |
| 158 // Platform specific display surface returned here. | |
| 159 EGLDisplay PlatformGetDisplay(); | |
| 160 | |
| 161 EGLDisplay egl_display() { return egl_display_; } | |
| 162 | |
| 163 EGLContext egl_context() { return egl_context_; } | |
| 164 | |
| 165 MessageLoop* message_loop() { return message_loop_; } | |
| 166 | |
| 167 protected: | |
| 168 void Clear(); | |
| 169 | |
| 170 // We ensure all operations are carried out on the same thread by remembering | |
| 171 // where we were Initialized. | |
| 172 MessageLoop* message_loop_; | |
| 173 int width_; | |
| 174 int height_; | |
| 175 bool suppress_swap_to_display_; | |
| 176 | |
| 177 EGLDisplay egl_display_; | |
| 178 EGLContext egl_context_; | |
| 179 std::vector<EGLSurface> egl_surfaces_; | |
| 180 std::map<GLuint, int> texture_id_to_surface_index_; | |
| 181 | |
| 182 #if defined(OS_WIN) | |
| 183 std::vector<HWND> windows_; | |
| 184 #else // OS_WIN | |
| 185 Display* x_display_; | |
| 186 std::vector<Window> x_windows_; | |
| 187 #endif // OS_WIN | |
| 188 }; | |
| 189 | |
| 190 RenderingHelper::RenderingHelper() { | |
| 191 Clear(); | |
| 192 } | |
| 193 | |
| 194 RenderingHelper::~RenderingHelper() { | |
| 195 CHECK_EQ(width_, 0) << "Must call UnInitialize before dtor."; | |
| 196 Clear(); | |
| 197 } | |
| 198 | |
| 199 // Helper for Shader creation. | |
| 200 static void CreateShader( | |
| 201 GLuint program, GLenum type, const char* source, int size) { | |
| 202 GLuint shader = glCreateShader(type); | |
| 203 glShaderSource(shader, 1, &source, &size); | |
| 204 glCompileShader(shader); | |
| 205 int result = GL_FALSE; | |
| 206 glGetShaderiv(shader, GL_COMPILE_STATUS, &result); | |
| 207 if (!result) { | |
| 208 char log[4096]; | |
| 209 glGetShaderInfoLog(shader, arraysize(log), NULL, log); | |
| 210 LOG(FATAL) << log; | |
| 211 } | |
| 212 glAttachShader(program, shader); | |
| 213 glDeleteShader(shader); | |
| 214 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | |
| 215 } | |
| 216 | |
| 217 void RenderingHelper::Initialize( | |
| 218 bool suppress_swap_to_display, | |
| 219 int num_windows, | |
| 220 int width, | |
| 221 int height, | |
| 222 base::WaitableEvent* done) { | |
| 223 // Use width_ != 0 as a proxy for the class having already been | |
| 224 // Initialize()'d, and UnInitialize() before continuing. | |
| 225 if (width_) { | |
| 226 base::WaitableEvent done(false, false); | |
| 227 UnInitialize(&done); | |
| 228 done.Wait(); | |
| 229 } | |
| 230 | |
| 231 suppress_swap_to_display_ = suppress_swap_to_display; | |
| 232 CHECK_GT(width, 0); | |
| 233 CHECK_GT(height, 0); | |
| 234 width_ = width; | |
| 235 height_ = height; | |
| 236 message_loop_ = MessageLoop::current(); | |
| 237 CHECK_GT(num_windows, 0); | |
| 238 | |
| 239 PlatformInitialize(); | |
| 240 | |
| 241 egl_display_ = PlatformGetDisplay(); | |
| 242 | |
| 243 EGLint major; | |
| 244 EGLint minor; | |
| 245 CHECK(eglInitialize(egl_display_, &major, &minor)) << eglGetError(); | |
| 246 static EGLint rgba8888[] = { | |
| 247 EGL_RED_SIZE, 8, | |
| 248 EGL_GREEN_SIZE, 8, | |
| 249 EGL_BLUE_SIZE, 8, | |
| 250 EGL_ALPHA_SIZE, 8, | |
| 251 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, | |
| 252 EGL_NONE, | |
| 253 }; | |
| 254 EGLConfig egl_config; | |
| 255 int num_configs; | |
| 256 CHECK(eglChooseConfig(egl_display_, rgba8888, &egl_config, 1, &num_configs)) | |
| 257 << eglGetError(); | |
| 258 CHECK_GE(num_configs, 1); | |
| 259 static EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; | |
| 260 egl_context_ = eglCreateContext( | |
| 261 egl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); | |
| 262 CHECK_NE(egl_context_, EGL_NO_CONTEXT) << eglGetError(); | |
| 263 | |
| 264 // Per-window/surface X11 & EGL initialization. | |
| 265 for (int i = 0; i < num_windows; ++i) { | |
| 266 // Arrange X windows whimsically, with some padding. | |
| 267 int top_left_x = (width + 20) * (i % 4); | |
| 268 int top_left_y = (height + 12) * (i % 3); | |
| 269 | |
| 270 EGLNativeWindowType window = PlatformCreateWindow(top_left_x, top_left_y); | |
| 271 EGLSurface egl_surface = | |
| 272 eglCreateWindowSurface(egl_display_, egl_config, window, NULL); | |
| 273 egl_surfaces_.push_back(egl_surface); | |
| 274 CHECK_NE(egl_surface, EGL_NO_SURFACE); | |
| 275 } | |
| 276 CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[0], | |
| 277 egl_surfaces_[0], egl_context_)) << eglGetError(); | |
| 278 | |
| 279 static const float kVertices[] = | |
| 280 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; | |
| 281 static const float kTextureCoordsEgl[] = { 0, 1, 0, 0, 1, 1, 1, 0, }; | |
| 282 static const char kVertexShader[] = STRINGIZE( | |
| 283 varying vec2 interp_tc; | |
| 284 attribute vec4 in_pos; | |
| 285 attribute vec2 in_tc; | |
| 286 void main() { | |
| 287 interp_tc = in_tc; | |
| 288 gl_Position = in_pos; | |
| 289 } | |
| 290 ); | |
| 291 static const char kFragmentShaderEgl[] = STRINGIZE( | |
| 292 precision mediump float; | |
| 293 varying vec2 interp_tc; | |
| 294 uniform sampler2D tex; | |
| 295 void main() { | |
| 296 gl_FragColor = texture2D(tex, interp_tc); | |
| 297 } | |
| 298 ); | |
| 299 GLuint program = glCreateProgram(); | |
| 300 CreateShader(program, GL_VERTEX_SHADER, | |
| 301 kVertexShader, arraysize(kVertexShader)); | |
| 302 CreateShader(program, GL_FRAGMENT_SHADER, | |
| 303 kFragmentShaderEgl, arraysize(kFragmentShaderEgl)); | |
| 304 glLinkProgram(program); | |
| 305 int result = GL_FALSE; | |
| 306 glGetProgramiv(program, GL_LINK_STATUS, &result); | |
| 307 if (!result) { | |
| 308 char log[4096]; | |
| 309 glGetShaderInfoLog(program, arraysize(log), NULL, log); | |
| 310 LOG(FATAL) << log; | |
| 311 } | |
| 312 glUseProgram(program); | |
| 313 glDeleteProgram(program); | |
| 314 | |
| 315 glUniform1i(glGetUniformLocation(program, "tex"), 0); | |
| 316 int pos_location = glGetAttribLocation(program, "in_pos"); | |
| 317 glEnableVertexAttribArray(pos_location); | |
| 318 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); | |
| 319 int tc_location = glGetAttribLocation(program, "in_tc"); | |
| 320 glEnableVertexAttribArray(tc_location); | |
| 321 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, | |
| 322 kTextureCoordsEgl); | |
| 323 done->Signal(); | |
| 324 } | |
| 325 | |
| 326 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { | |
| 327 CHECK_EQ(MessageLoop::current(), message_loop_); | |
| 328 CHECK(eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, | |
| 329 EGL_NO_CONTEXT)) << eglGetError(); | |
| 330 CHECK(eglDestroyContext(egl_display_, egl_context_)); | |
| 331 for (size_t i = 0; i < egl_surfaces_.size(); ++i) | |
| 332 CHECK(eglDestroySurface(egl_display_, egl_surfaces_[i])); | |
| 333 CHECK(eglTerminate(egl_display_)); | |
| 334 Clear(); | |
| 335 done->Signal(); | |
| 336 } | |
| 337 | |
| 338 void RenderingHelper::Clear() { | |
| 339 suppress_swap_to_display_ = false; | |
| 340 width_ = 0; | |
| 341 height_ = 0; | |
| 342 texture_id_to_surface_index_.clear(); | |
| 343 message_loop_ = NULL; | |
| 344 egl_display_ = EGL_NO_DISPLAY; | |
| 345 egl_context_ = EGL_NO_CONTEXT; | |
| 346 egl_surfaces_.clear(); | |
| 347 PlatformUnInitialize(); | |
| 348 } | |
| 349 | |
| 350 void RenderingHelper::CreateTexture(int window_id, GLuint* texture_id, | |
| 351 base::WaitableEvent* done) { | |
| 352 if (MessageLoop::current() != message_loop_) { | |
| 353 message_loop_->PostTask( | |
| 354 FROM_HERE, | |
| 355 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), | |
| 356 window_id, texture_id, done)); | |
| 357 return; | |
| 358 } | |
| 359 CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[window_id], | |
| 360 egl_surfaces_[window_id], egl_context_)) | |
| 361 << eglGetError(); | |
| 362 glGenTextures(1, texture_id); | |
| 363 glBindTexture(GL_TEXTURE_2D, *texture_id); | |
| 364 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, | |
| 365 GL_UNSIGNED_BYTE, NULL); | |
| 366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 368 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. | |
| 369 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 371 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | |
| 372 CHECK(texture_id_to_surface_index_.insert( | |
| 373 std::make_pair(*texture_id, window_id)).second); | |
| 374 done->Signal(); | |
| 375 } | |
| 376 | |
| 377 void RenderingHelper::RenderTexture(GLuint texture_id) { | |
| 378 CHECK_EQ(MessageLoop::current(), message_loop_); | |
| 379 glActiveTexture(GL_TEXTURE0); | |
| 380 glBindTexture(GL_TEXTURE_2D, texture_id); | |
| 381 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
| 382 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | |
| 383 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); | |
| 384 if (!suppress_swap_to_display_) { | |
| 385 int window_id = texture_id_to_surface_index_[texture_id]; | |
| 386 CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[window_id], | |
| 387 egl_surfaces_[window_id], egl_context_)) | |
| 388 << eglGetError(); | |
| 389 eglSwapBuffers(egl_display_, egl_surfaces_[window_id]); | |
| 390 } | |
| 391 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); | |
| 392 } | |
| 393 | |
| 394 void RenderingHelper::DeleteTexture(GLuint texture_id) { | |
| 395 glDeleteTextures(1, &texture_id); | |
| 396 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | |
| 397 } | |
| 398 | |
| 399 #if defined(OS_WIN) | |
| 400 void RenderingHelper::PlatformInitialize() {} | |
| 401 | |
| 402 void RenderingHelper::PlatformUnInitialize() { | |
| 403 for (size_t i = 0; i < windows_.size(); ++i) { | |
| 404 DestroyWindow(windows_[i]); | |
| 405 } | |
| 406 windows_.clear(); | |
| 407 } | |
| 408 | |
| 409 EGLNativeWindowType RenderingHelper::PlatformCreateWindow( | |
| 410 int top_left_x, int top_left_y) { | |
| 411 HWND window = CreateWindowEx(0, L"Static", L"VideoDecodeAcceleratorTest", | |
| 412 WS_OVERLAPPEDWINDOW | WS_VISIBLE, top_left_x, | |
| 413 top_left_y, width_, height_, NULL, NULL, NULL, | |
| 414 NULL); | |
| 415 CHECK(window != NULL); | |
| 416 windows_.push_back(window); | |
| 417 return window; | |
| 418 } | |
| 419 | |
| 420 EGLDisplay RenderingHelper::PlatformGetDisplay() { | |
| 421 return eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
| 422 } | |
| 423 | |
| 424 #else // OS_WIN | |
| 425 | |
| 426 void RenderingHelper::PlatformInitialize() { | |
| 427 CHECK(x_display_ = base::MessagePumpForUI::GetDefaultXDisplay()); | |
| 428 } | |
| 429 | |
| 430 void RenderingHelper::PlatformUnInitialize() { | |
| 431 // Destroy resources acquired in Initialize, in reverse-acquisition order. | |
| 432 for (size_t i = 0; i < x_windows_.size(); ++i) { | |
| 433 CHECK(XUnmapWindow(x_display_, x_windows_[i])); | |
| 434 CHECK(XDestroyWindow(x_display_, x_windows_[i])); | |
| 435 } | |
| 436 // Mimic newly created object. | |
| 437 x_display_ = NULL; | |
| 438 x_windows_.clear(); | |
| 439 } | |
| 440 | |
| 441 EGLDisplay RenderingHelper::PlatformGetDisplay() { | |
| 442 return eglGetDisplay(x_display_); | |
| 443 } | |
| 444 | |
| 445 EGLNativeWindowType RenderingHelper::PlatformCreateWindow(int top_left_x, | |
| 446 int top_left_y) { | |
| 447 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); | |
| 448 | |
| 449 XSetWindowAttributes window_attributes; | |
| 450 window_attributes.background_pixel = | |
| 451 BlackPixel(x_display_, DefaultScreen(x_display_)); | |
| 452 window_attributes.override_redirect = true; | |
| 453 | |
| 454 Window x_window = XCreateWindow( | |
| 455 x_display_, DefaultRootWindow(x_display_), | |
| 456 top_left_x, top_left_y, width_, height_, | |
| 457 0 /* border width */, | |
| 458 depth, CopyFromParent /* class */, CopyFromParent /* visual */, | |
| 459 (CWBackPixel | CWOverrideRedirect), &window_attributes); | |
| 460 x_windows_.push_back(x_window); | |
| 461 XStoreName(x_display_, x_window, "VideoDecodeAcceleratorTest"); | |
| 462 XSelectInput(x_display_, x_window, ExposureMask); | |
| 463 XMapWindow(x_display_, x_window); | |
| 464 return x_window; | |
| 465 } | |
| 466 | |
| 467 #endif // OS_WIN | |
| 468 | |
| 469 // State of the EglRenderingVDAClient below. Order matters here as the test | 124 // State of the EglRenderingVDAClient below. Order matters here as the test |
| 470 // makes assumptions about it. | 125 // makes assumptions about it. |
| 471 enum ClientState { | 126 enum ClientState { |
| 472 CS_CREATED, | 127 CS_CREATED, |
| 473 CS_DECODER_SET, | 128 CS_DECODER_SET, |
| 474 CS_INITIALIZED, | 129 CS_INITIALIZED, |
| 475 CS_FLUSHING, | 130 CS_FLUSHING, |
| 476 CS_FLUSHED, | 131 CS_FLUSHED, |
| 477 CS_DONE, | 132 CS_DONE, |
| 478 CS_RESETTING, | 133 CS_RESETTING, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 544 // last play-through (governed by |num_play_throughs|). | 199 // last play-through (governed by |num_play_throughs|). |
| 545 EglRenderingVDAClient(RenderingHelper* rendering_helper, | 200 EglRenderingVDAClient(RenderingHelper* rendering_helper, |
| 546 int rendering_window_id, | 201 int rendering_window_id, |
| 547 ClientStateNotification* note, | 202 ClientStateNotification* note, |
| 548 const std::string& encoded_data, | 203 const std::string& encoded_data, |
| 549 int num_NALUs_per_decode, | 204 int num_NALUs_per_decode, |
| 550 int num_in_flight_decodes, | 205 int num_in_flight_decodes, |
| 551 int num_play_throughs, | 206 int num_play_throughs, |
| 552 int reset_after_frame_num, | 207 int reset_after_frame_num, |
| 553 int delete_decoder_state, | 208 int delete_decoder_state, |
| 209 int frame_width, | |
| 210 int frame_height, | |
| 554 int profile); | 211 int profile); |
| 555 virtual ~EglRenderingVDAClient(); | 212 virtual ~EglRenderingVDAClient(); |
| 556 void CreateDecoder(); | 213 void CreateDecoder(); |
| 557 | 214 |
| 558 // VideoDecodeAccelerator::Client implementation. | 215 // VideoDecodeAccelerator::Client implementation. |
| 559 // The heart of the Client. | 216 // The heart of the Client. |
| 560 virtual void ProvidePictureBuffers( | 217 virtual void ProvidePictureBuffers( |
| 561 uint32 requested_num_of_buffers, | 218 uint32 requested_num_of_buffers, |
| 562 const gfx::Size& dimensions); | 219 const gfx::Size& dimensions); |
| 563 virtual void DismissPictureBuffer(int32 picture_buffer_id); | 220 virtual void DismissPictureBuffer(int32 picture_buffer_id); |
| 564 virtual void PictureReady(const media::Picture& picture); | 221 virtual void PictureReady(const media::Picture& picture); |
| 565 // Simple state changes. | 222 // Simple state changes. |
| 566 virtual void NotifyInitializeDone(); | 223 virtual void NotifyInitializeDone(); |
| 567 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id); | 224 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id); |
| 568 virtual void NotifyFlushDone(); | 225 virtual void NotifyFlushDone(); |
| 569 virtual void NotifyResetDone(); | 226 virtual void NotifyResetDone(); |
| 570 virtual void NotifyError(VideoDecodeAccelerator::Error error); | 227 virtual void NotifyError(VideoDecodeAccelerator::Error error); |
| 571 | 228 |
| 572 // Simple getters for inspecting the state of the Client. | 229 // Simple getters for inspecting the state of the Client. |
| 573 ClientState state() { return state_; } | 230 ClientState state() { return state_; } |
| 574 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } | 231 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } |
| 575 int num_decoded_frames() { return num_decoded_frames_; } | 232 int num_decoded_frames() { return num_decoded_frames_; } |
| 576 EGLDisplay egl_display() { return rendering_helper_->egl_display(); } | |
| 577 EGLContext egl_context() { return rendering_helper_->egl_context(); } | |
| 578 double frames_per_second(); | 233 double frames_per_second(); |
| 579 bool decoder_deleted() { return !decoder_; } | 234 bool decoder_deleted() { return !decoder_; } |
| 580 | 235 |
| 581 private: | 236 private: |
| 582 typedef std::map<int, media::PictureBuffer*> PictureBufferById; | 237 typedef std::map<int, media::PictureBuffer*> PictureBufferById; |
| 583 | 238 |
| 584 void SetState(ClientState new_state); | 239 void SetState(ClientState new_state); |
| 585 | 240 |
| 586 // Delete the associated OMX decoder helper. | 241 // Delete the associated OMX decoder helper. |
| 587 void DeleteDecoder(); | 242 void DeleteDecoder(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 606 std::set<int> outstanding_texture_ids_; | 261 std::set<int> outstanding_texture_ids_; |
| 607 int remaining_play_throughs_; | 262 int remaining_play_throughs_; |
| 608 int reset_after_frame_num_; | 263 int reset_after_frame_num_; |
| 609 int delete_decoder_state_; | 264 int delete_decoder_state_; |
| 610 ClientState state_; | 265 ClientState state_; |
| 611 int num_decoded_frames_; | 266 int num_decoded_frames_; |
| 612 int num_done_bitstream_buffers_; | 267 int num_done_bitstream_buffers_; |
| 613 PictureBufferById picture_buffers_by_id_; | 268 PictureBufferById picture_buffers_by_id_; |
| 614 base::TimeTicks initialize_done_ticks_; | 269 base::TimeTicks initialize_done_ticks_; |
| 615 base::TimeTicks last_frame_delivered_ticks_; | 270 base::TimeTicks last_frame_delivered_ticks_; |
| 271 int frame_width_; | |
| 272 int frame_height_; | |
| 616 int profile_; | 273 int profile_; |
| 617 }; | 274 }; |
| 618 | 275 |
| 619 EglRenderingVDAClient::EglRenderingVDAClient( | 276 EglRenderingVDAClient::EglRenderingVDAClient( |
| 620 RenderingHelper* rendering_helper, | 277 RenderingHelper* rendering_helper, |
| 621 int rendering_window_id, | 278 int rendering_window_id, |
| 622 ClientStateNotification* note, | 279 ClientStateNotification* note, |
| 623 const std::string& encoded_data, | 280 const std::string& encoded_data, |
| 624 int num_NALUs_per_decode, | 281 int num_NALUs_per_decode, |
| 625 int num_in_flight_decodes, | 282 int num_in_flight_decodes, |
| 626 int num_play_throughs, | 283 int num_play_throughs, |
| 627 int reset_after_frame_num, | 284 int reset_after_frame_num, |
| 628 int delete_decoder_state, | 285 int delete_decoder_state, |
| 286 int frame_width, | |
| 287 int frame_height, | |
| 629 int profile) | 288 int profile) |
| 630 : rendering_helper_(rendering_helper), | 289 : rendering_helper_(rendering_helper), |
| 631 rendering_window_id_(rendering_window_id), | 290 rendering_window_id_(rendering_window_id), |
| 632 encoded_data_(encoded_data), num_NALUs_per_decode_(num_NALUs_per_decode), | 291 encoded_data_(encoded_data), num_NALUs_per_decode_(num_NALUs_per_decode), |
| 633 num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0), | 292 num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0), |
| 634 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), | 293 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), |
| 635 note_(note), | 294 note_(note), |
| 636 remaining_play_throughs_(num_play_throughs), | 295 remaining_play_throughs_(num_play_throughs), |
| 637 reset_after_frame_num_(reset_after_frame_num), | 296 reset_after_frame_num_(reset_after_frame_num), |
| 638 delete_decoder_state_(delete_decoder_state), | 297 delete_decoder_state_(delete_decoder_state), |
| 639 state_(CS_CREATED), | 298 state_(CS_CREATED), |
| 640 num_decoded_frames_(0), num_done_bitstream_buffers_(0), | 299 num_decoded_frames_(0), num_done_bitstream_buffers_(0), |
| 300 frame_width_(frame_width), | |
| 301 frame_height_(frame_height), | |
| 641 profile_(profile) { | 302 profile_(profile) { |
| 642 CHECK_GT(num_NALUs_per_decode, 0); | 303 CHECK_GT(num_NALUs_per_decode, 0); |
| 643 CHECK_GT(num_in_flight_decodes, 0); | 304 CHECK_GT(num_in_flight_decodes, 0); |
| 644 CHECK_GT(num_play_throughs, 0); | 305 CHECK_GT(num_play_throughs, 0); |
| 645 } | 306 } |
| 646 | 307 |
| 647 EglRenderingVDAClient::~EglRenderingVDAClient() { | 308 EglRenderingVDAClient::~EglRenderingVDAClient() { |
| 648 DeleteDecoder(); // Clean up in case of expected error. | 309 DeleteDecoder(); // Clean up in case of expected error. |
| 649 CHECK(decoder_deleted()); | 310 CHECK(decoder_deleted()); |
| 650 STLDeleteValues(&picture_buffers_by_id_); | 311 STLDeleteValues(&picture_buffers_by_id_); |
| 651 SetState(CS_DESTROYED); | 312 SetState(CS_DESTROYED); |
| 652 } | 313 } |
| 653 | 314 |
| 654 void EglRenderingVDAClient::CreateDecoder() { | 315 void EglRenderingVDAClient::CreateDecoder() { |
| 655 CHECK(decoder_deleted()); | 316 CHECK(decoder_deleted()); |
| 656 #if defined(OS_WIN) | 317 #if defined(OS_WIN) |
| 657 scoped_refptr<DXVAVideoDecodeAccelerator> decoder = | 318 scoped_refptr<DXVAVideoDecodeAccelerator> decoder = |
| 658 new DXVAVideoDecodeAccelerator(this); | 319 new DXVAVideoDecodeAccelerator(this); |
| 659 #else // OS_WIN | 320 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
| 660 scoped_refptr<OmxVideoDecodeAccelerator> decoder = | 321 scoped_refptr<OmxVideoDecodeAccelerator> decoder = |
| 661 new OmxVideoDecodeAccelerator(this); | 322 new OmxVideoDecodeAccelerator(this); |
| 662 decoder->SetEglState(egl_display(), egl_context()); | 323 decoder->SetEglState( |
| 324 static_cast<EGLDisplay>(rendering_helper->GetGLDisplay()), | |
| 325 static_cast<EGLContext>(rendering_helper->GetGLContext())); | |
| 326 #elif defined(OS_MACOSX) | |
| 327 scoped_refptr<MacVideoDecodeAccelerator> decoder = | |
| 328 new MacVideoDecodeAccelerator(this); | |
| 329 decoder->SetGLContext(rendering_helper_->GetGLContext()); | |
| 330 std::vector<uint8_t> avc_data(MP4_EXTRA_DATA, | |
| 331 MP4_EXTRA_DATA + arraysize(MP4_EXTRA_DATA)); | |
| 332 if (!decoder->SetConfigInfo(frame_width_, frame_height_, avc_data)) { | |
| 333 SetState(CS_ERROR); | |
| 334 return; | |
| 335 } | |
| 663 #endif // OS_WIN | 336 #endif // OS_WIN |
| 664 decoder_ = decoder.release(); | 337 decoder_ = decoder.release(); |
| 665 SetState(CS_DECODER_SET); | 338 SetState(CS_DECODER_SET); |
| 666 if (decoder_deleted()) | 339 if (decoder_deleted()) |
| 667 return; | 340 return; |
| 668 | 341 |
| 669 // Configure the decoder. | 342 // Configure the decoder. |
| 670 media::VideoCodecProfile profile = media::H264PROFILE_BASELINE; | 343 media::VideoCodecProfile profile = media::H264PROFILE_BASELINE; |
| 671 if (profile_ != -1) | 344 if (profile_ != -1) |
| 672 profile = static_cast<media::VideoCodecProfile>(profile_); | 345 profile = static_cast<media::VideoCodecProfile>(profile_); |
| 673 CHECK(decoder_->Initialize(profile)); | 346 CHECK(decoder_->Initialize(profile)); |
| 674 } | 347 } |
| 675 | 348 |
| 676 void EglRenderingVDAClient::ProvidePictureBuffers( | 349 void EglRenderingVDAClient::ProvidePictureBuffers( |
| 677 uint32 requested_num_of_buffers, | 350 uint32 requested_num_of_buffers, |
| 678 const gfx::Size& dimensions) { | 351 const gfx::Size& dimensions) { |
| 679 if (decoder_deleted()) | 352 if (decoder_deleted()) |
| 680 return; | 353 return; |
| 681 std::vector<media::PictureBuffer> buffers; | 354 std::vector<media::PictureBuffer> buffers; |
| 682 | 355 |
| 683 for (uint32 i = 0; i < requested_num_of_buffers; ++i) { | 356 for (uint32 i = 0; i < requested_num_of_buffers; ++i) { |
| 684 uint32 id = picture_buffers_by_id_.size(); | 357 uint32 id = picture_buffers_by_id_.size(); |
| 685 GLuint texture_id; | 358 uint32 texture_id; |
| 686 base::WaitableEvent done(false, false); | 359 base::WaitableEvent done(false, false); |
| 687 rendering_helper_->CreateTexture(rendering_window_id_, &texture_id, &done); | 360 rendering_helper_->CreateTexture(rendering_window_id_, &texture_id, &done); |
| 688 done.Wait(); | 361 done.Wait(); |
| 689 CHECK(outstanding_texture_ids_.insert(texture_id).second); | 362 CHECK(outstanding_texture_ids_.insert(texture_id).second); |
| 690 media::PictureBuffer* buffer = | 363 media::PictureBuffer* buffer = |
| 691 new media::PictureBuffer(id, dimensions, texture_id); | 364 new media::PictureBuffer(id, dimensions, texture_id); |
| 692 CHECK(picture_buffers_by_id_.insert(std::make_pair(id, buffer)).second); | 365 CHECK(picture_buffers_by_id_.insert(std::make_pair(id, buffer)).second); |
| 693 buffers.push_back(*buffer); | 366 buffers.push_back(*buffer); |
| 694 } | 367 } |
| 695 decoder_->AssignPictureBuffers(buffers); | 368 decoder_->AssignPictureBuffers(buffers); |
| 696 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | |
| 697 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); | |
| 698 } | 369 } |
| 699 | 370 |
| 700 void EglRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { | 371 void EglRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { |
| 701 PictureBufferById::iterator it = | 372 PictureBufferById::iterator it = |
| 702 picture_buffers_by_id_.find(picture_buffer_id); | 373 picture_buffers_by_id_.find(picture_buffer_id); |
| 703 CHECK(it != picture_buffers_by_id_.end()); | 374 CHECK(it != picture_buffers_by_id_.end()); |
| 704 CHECK_EQ(outstanding_texture_ids_.erase(it->second->texture_id()), 1U); | 375 CHECK_EQ(outstanding_texture_ids_.erase(it->second->texture_id()), 1U); |
| 705 rendering_helper_->DeleteTexture(it->second->texture_id()); | 376 rendering_helper_->DeleteTexture(it->second->texture_id()); |
| 706 delete it->second; | 377 delete it->second; |
| 707 picture_buffers_by_id_.erase(it); | 378 picture_buffers_by_id_.erase(it); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 // Populate the shared memory buffer w/ the NALU, duplicate its handle, and | 528 // Populate the shared memory buffer w/ the NALU, duplicate its handle, and |
| 858 // hand it off to the decoder. | 529 // hand it off to the decoder. |
| 859 base::SharedMemory shm; | 530 base::SharedMemory shm; |
| 860 CHECK(shm.CreateAndMapAnonymous(end_pos - start_pos)) | 531 CHECK(shm.CreateAndMapAnonymous(end_pos - start_pos)) |
| 861 << start_pos << ", " << end_pos; | 532 << start_pos << ", " << end_pos; |
| 862 memcpy(shm.memory(), encoded_data_.data() + start_pos, end_pos - start_pos); | 533 memcpy(shm.memory(), encoded_data_.data() + start_pos, end_pos - start_pos); |
| 863 base::SharedMemoryHandle dup_handle; | 534 base::SharedMemoryHandle dup_handle; |
| 864 CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle)); | 535 CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle)); |
| 865 media::BitstreamBuffer bitstream_buffer( | 536 media::BitstreamBuffer bitstream_buffer( |
| 866 next_bitstream_buffer_id_++, dup_handle, end_pos - start_pos); | 537 next_bitstream_buffer_id_++, dup_handle, end_pos - start_pos); |
| 867 decoder_->Decode(bitstream_buffer); | 538 // Avoid becoming reentrant by decoding on next event cycle. |
| 539 MessageLoop::current()->PostTask( | |
| 540 FROM_HERE, | |
| 541 base::Bind(&VideoDecodeAccelerator::Decode, decoder_, bitstream_buffer)); | |
| 542 | |
| 868 ++outstanding_decodes_; | 543 ++outstanding_decodes_; |
| 869 encoded_data_next_pos_to_decode_ = end_pos; | 544 encoded_data_next_pos_to_decode_ = end_pos; |
| 870 | 545 |
| 871 if (!remaining_play_throughs_ && | 546 if (!remaining_play_throughs_ && |
| 872 -delete_decoder_state_ == next_bitstream_buffer_id_) { | 547 -delete_decoder_state_ == next_bitstream_buffer_id_) { |
| 873 DeleteDecoder(); | 548 DeleteDecoder(); |
|
Ami GONE FROM CHROMIUM
2012/05/24 21:30:30
I think you missed this comment from my last revie
sail
2012/05/29 03:45:01
Ahh sorry, overlooked that.
I reverted this chang
| |
| 874 } | 549 } |
| 875 } | 550 } |
| 876 | 551 |
| 877 double EglRenderingVDAClient::frames_per_second() { | 552 double EglRenderingVDAClient::frames_per_second() { |
| 878 base::TimeDelta delta = last_frame_delivered_ticks_ - initialize_done_ticks_; | 553 base::TimeDelta delta = last_frame_delivered_ticks_ - initialize_done_ticks_; |
| 879 if (delta.InSecondsF() == 0) | 554 if (delta.InSecondsF() == 0) |
| 880 return 0; | 555 return 0; |
| 881 return num_decoded_frames_ / delta.InSecondsF(); | 556 return num_decoded_frames_ / delta.InSecondsF(); |
| 882 } | 557 } |
| 883 | 558 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 956 base::Thread rendering_thread("EglRenderingVDAClientThread"); | 631 base::Thread rendering_thread("EglRenderingVDAClientThread"); |
| 957 base::Thread::Options options; | 632 base::Thread::Options options; |
| 958 options.message_loop_type = MessageLoop::TYPE_DEFAULT; | 633 options.message_loop_type = MessageLoop::TYPE_DEFAULT; |
| 959 #if defined(OS_WIN) | 634 #if defined(OS_WIN) |
| 960 // For windows the decoding thread initializes the media foundation decoder | 635 // For windows the decoding thread initializes the media foundation decoder |
| 961 // which uses COM. We need the thread to be a UI thread. | 636 // which uses COM. We need the thread to be a UI thread. |
| 962 options.message_loop_type = MessageLoop::TYPE_UI; | 637 options.message_loop_type = MessageLoop::TYPE_UI; |
| 963 #endif // OS_WIN | 638 #endif // OS_WIN |
| 964 | 639 |
| 965 rendering_thread.StartWithOptions(options); | 640 rendering_thread.StartWithOptions(options); |
| 966 RenderingHelper rendering_helper; | 641 scoped_ptr<RenderingHelper> rendering_helper(RenderingHelper::Create()); |
| 967 | 642 |
| 968 base::WaitableEvent done(false, false); | 643 base::WaitableEvent done(false, false); |
| 969 rendering_thread.message_loop()->PostTask( | 644 rendering_thread.message_loop()->PostTask( |
| 970 FROM_HERE, | 645 FROM_HERE, |
| 971 base::Bind(&RenderingHelper::Initialize, | 646 base::Bind(&RenderingHelper::Initialize, |
| 972 base::Unretained(&rendering_helper), | 647 base::Unretained(rendering_helper.get()), |
| 973 suppress_swap_to_display, num_concurrent_decoders, | 648 suppress_swap_to_display, num_concurrent_decoders, |
| 974 frame_width, frame_height, &done)); | 649 frame_width, frame_height, &done)); |
| 975 done.Wait(); | 650 done.Wait(); |
| 976 | 651 |
| 977 // First kick off all the decoders. | 652 // First kick off all the decoders. |
| 978 for (size_t index = 0; index < num_concurrent_decoders; ++index) { | 653 for (size_t index = 0; index < num_concurrent_decoders; ++index) { |
| 979 ClientStateNotification* note = new ClientStateNotification(); | 654 ClientStateNotification* note = new ClientStateNotification(); |
| 980 notes[index] = note; | 655 notes[index] = note; |
| 981 EglRenderingVDAClient* client = new EglRenderingVDAClient( | 656 EglRenderingVDAClient* client = new EglRenderingVDAClient( |
| 982 &rendering_helper, index, | 657 rendering_helper.get(), index, note, data_str, num_NALUs_per_decode, |
| 983 note, data_str, num_NALUs_per_decode, | 658 num_in_flight_decodes, num_play_throughs, reset_after_frame_num, |
| 984 num_in_flight_decodes, num_play_throughs, | 659 delete_decoder_state, frame_width, frame_height, profile); |
| 985 reset_after_frame_num, delete_decoder_state, profile); | |
| 986 clients[index] = client; | 660 clients[index] = client; |
| 987 | 661 |
| 988 rendering_thread.message_loop()->PostTask( | 662 rendering_thread.message_loop()->PostTask( |
| 989 FROM_HERE, | 663 FROM_HERE, |
| 990 base::Bind(&EglRenderingVDAClient::CreateDecoder, | 664 base::Bind(&EglRenderingVDAClient::CreateDecoder, |
| 991 base::Unretained(client))); | 665 base::Unretained(client))); |
| 992 | 666 |
| 993 ASSERT_EQ(note->Wait(), CS_DECODER_SET); | 667 ASSERT_EQ(note->Wait(), CS_DECODER_SET); |
| 994 } | 668 } |
| 995 // Then wait for all the decodes to finish. | 669 // Then wait for all the decodes to finish. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1055 FROM_HERE, | 729 FROM_HERE, |
| 1056 base::Bind(&STLDeleteElements<std::vector<EglRenderingVDAClient*> >, | 730 base::Bind(&STLDeleteElements<std::vector<EglRenderingVDAClient*> >, |
| 1057 &clients)); | 731 &clients)); |
| 1058 rendering_thread.message_loop()->PostTask( | 732 rendering_thread.message_loop()->PostTask( |
| 1059 FROM_HERE, | 733 FROM_HERE, |
| 1060 base::Bind(&STLDeleteElements<std::vector<ClientStateNotification*> >, | 734 base::Bind(&STLDeleteElements<std::vector<ClientStateNotification*> >, |
| 1061 ¬es)); | 735 ¬es)); |
| 1062 rendering_thread.message_loop()->PostTask( | 736 rendering_thread.message_loop()->PostTask( |
| 1063 FROM_HERE, | 737 FROM_HERE, |
| 1064 base::Bind(&RenderingHelper::UnInitialize, | 738 base::Bind(&RenderingHelper::UnInitialize, |
| 1065 base::Unretained(&rendering_helper), | 739 base::Unretained(rendering_helper.get()), |
| 1066 &done)); | 740 &done)); |
| 1067 done.Wait(); | 741 done.Wait(); |
| 1068 rendering_thread.Stop(); | 742 rendering_thread.Stop(); |
| 1069 }; | 743 }; |
| 1070 | 744 |
| 1071 // Test that replay after EOS works fine. | 745 // Test that replay after EOS works fine. |
| 1072 INSTANTIATE_TEST_CASE_P( | 746 INSTANTIATE_TEST_CASE_P( |
| 1073 ReplayAfterEOS, VideoDecodeAcceleratorTest, | 747 ReplayAfterEOS, VideoDecodeAcceleratorTest, |
| 1074 ::testing::Values( | 748 ::testing::Values( |
| 1075 MakeTuple(1, 1, 1, 4, END_OF_STREAM_RESET, CS_RESET))); | 749 MakeTuple(1, 1, 1, 4, END_OF_STREAM_RESET, CS_RESET))); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1149 | 823 |
| 1150 CommandLine::SwitchMap switches = cmd_line->GetSwitches(); | 824 CommandLine::SwitchMap switches = cmd_line->GetSwitches(); |
| 1151 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); | 825 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); |
| 1152 it != switches.end(); ++it) { | 826 it != switches.end(); ++it) { |
| 1153 if (it->first == "test_video_data") { | 827 if (it->first == "test_video_data") { |
| 1154 test_video_data = it->second.c_str(); | 828 test_video_data = it->second.c_str(); |
| 1155 continue; | 829 continue; |
| 1156 } | 830 } |
| 1157 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 831 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
| 1158 } | 832 } |
| 833 | |
| 834 base::ShadowingAtExitManager at_exit_manager; | |
| 835 RenderingHelper::InitializePlatform(); | |
| 836 | |
| 1159 #if defined(OS_WIN) | 837 #if defined(OS_WIN) |
| 1160 base::ShadowingAtExitManager at_exit_manager; | |
| 1161 gfx::InitializeGLBindings(gfx::kGLImplementationEGLGLES2); | |
| 1162 gfx::GLSurface::InitializeOneOff(); | |
| 1163 { | |
| 1164 // Hack to ensure that EGL extension function pointers are initialized. | |
| 1165 scoped_refptr<gfx::GLSurface> surface( | |
| 1166 gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1))); | |
| 1167 scoped_refptr<gfx::GLContext> context( | |
| 1168 gfx::GLContext::CreateGLContext(NULL, surface.get(), | |
| 1169 gfx::PreferIntegratedGpu)); | |
| 1170 context->MakeCurrent(surface.get()); | |
| 1171 } | |
| 1172 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | 838 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); |
| 1173 #endif // OS_WIN | 839 #endif |
| 840 | |
| 1174 return RUN_ALL_TESTS(); | 841 return RUN_ALL_TESTS(); |
| 1175 } | 842 } |
| OLD | NEW |