Index: content/common/gpu/media/video_decode_accelerator_unittest.cc |
=================================================================== |
--- content/common/gpu/media/video_decode_accelerator_unittest.cc (revision 114547) |
+++ content/common/gpu/media/video_decode_accelerator_unittest.cc (working copy) |
@@ -22,12 +22,11 @@ |
// gtest uses as struct names (inside a namespace). This means that |
// #include'ing gtest after anything that pulls in X.h fails to compile. |
// This is http://code.google.com/p/googletest/issues/detail?id=371 |
-#include "testing/gtest/include/gtest/gtest.h" |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
See the comment above this line for why it's inclu
ananta
2011/12/17 00:40:25
Sorry about that. Restored. I did this to fix a li
|
- |
#include "base/at_exit.h" |
#include "base/bind.h" |
#include "base/command_line.h" |
#include "base/file_util.h" |
+#include "base/process_util.h" |
#include "base/stl_util.h" |
#include "base/string_number_conversions.h" |
#include "base/string_split.h" |
@@ -36,12 +35,22 @@ |
#include "base/synchronization/lock.h" |
#include "base/synchronization/waitable_event.h" |
#include "base/threading/thread.h" |
+#include "base/utf_string_conversions.h" |
+ |
+#if (defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)) || defined(OS_WIN) |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
If you negate this up here & #error out, then afte
ananta
2011/12/17 00:40:25
Done.
|
+#if defined(OS_WIN) |
+#include "content/common/gpu/media/dxva_video_decode_accelerator.h" |
+#else // OS_WIN |
#include "content/common/gpu/media/omx_video_decode_accelerator.h" |
+#endif // defined(OS_WIN) |
+#endif // (defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)) || defined(OS_WIN) |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
#include "third_party/angle/include/EGL/egl.h" |
#include "third_party/angle/include/GLES2/gl2.h" |
-#if !defined(OS_CHROMEOS) || !defined(ARCH_CPU_ARMEL) |
-#error This test (and OmxVideoDecodeAccelerator) are only supported on cros/ARM! |
+#if !defined(OS_CHROMEOS) && !defined(ARCH_CPU_ARMEL) && !defined(OS_WIN) |
+#error The VideoAccelerator tests are only supported on cros/ARM/Windows. |
#endif |
using media::VideoDecodeAccelerator; |
@@ -61,7 +70,7 @@ |
// (the latter tests just decode speed). |
// - |profile| is the media::H264Profile set during Initialization. |
// An empty value for a numeric field means "ignore". |
-const char* test_video_data = "test-25fps.h264:320:240:250:258:50:175:1"; |
+std::string test_video_data = "test-25fps.h264:320:240:250:258:50:175:1"; |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
style guide prohibits global vars of class type, w
ananta
2011/12/17 00:40:25
Restored.
|
// Parse |data| into its constituent parts and set the various output fields |
// accordingly. CHECK-fails on unexpected or missing required data. |
@@ -98,18 +107,35 @@ |
CHECK(base::StringToInt(elements[7], profile)); |
} |
+// Helper for Shader creation. |
+static void CreateShader( |
+ GLuint program, GLenum type, const char* source, int size) { |
+ GLuint shader = glCreateShader(type); |
+ glShaderSource(shader, 1, &source, &size); |
+ glCompileShader(shader); |
+ int result = GL_FALSE; |
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &result); |
+ if (!result) { |
+ char log[4096]; |
+ glGetShaderInfoLog(shader, arraysize(log), NULL, log); |
+ LOG(FATAL) << log; |
+ } |
+ glAttachShader(program, shader); |
+ glDeleteShader(shader); |
+ CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
+} |
-// Helper for managing X11, EGL, and GLES2 resources. Xlib is not thread-safe, |
-// and GL state is thread-specific, so all the methods of this class (except for |
-// ctor/dtor) ensure they're being run on a single thread. |
+// Provides base functionality for managing EGL and GLES2 resources. |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Why move this below CreateShader above? It makes
ananta
2011/12/17 00:40:25
Moved this back to just before Initialize.
The Cre
Ami GONE FROM CHROMIUM
2011/12/19 22:53:44
Hahahahahahaha - now it's harder to diff between p
|
+// This class is not thread safe and thus all the methods of this class |
+// (except for ctor/dtor) ensure they're being run on a single thread. |
// |
-// TODO(fischman): consider moving this into media/ if we can de-dup some of the |
-// code that ends up getting copy/pasted all over the place (esp. the GL setup |
-// code). |
-class RenderingHelper { |
+// TODO(fischman): consider moving this into media/ if we can de-dup some of |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
TODO can be dropped now that the media/ version of
ananta
2011/12/17 00:40:25
Done.
|
+// the code that ends up getting copy/pasted all over the place (esp. the GL |
+// setup code). |
+class RenderingHelperBase { |
public: |
- explicit RenderingHelper(); |
- ~RenderingHelper(); |
+ RenderingHelperBase(); |
+ virtual ~RenderingHelperBase(); |
// Initialize all structures to prepare to render to one or more windows of |
// the specified dimensions. CHECK-fails if any initialization step fails. |
@@ -119,12 +145,17 @@ |
// then all the usual work is done, except for the final swap of the EGL |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
s/EGL// ?
ananta
2011/12/17 00:40:25
I just copied this as is from the existing comment
Ami GONE FROM CHROMIUM
2011/12/19 22:53:44
My point was that in the DXVA case the surfaces ar
|
// surface to the display. This cuts test times over 50% so is worth doing |
// when testing non-rendering-related aspects. |
- void Initialize(bool suppress_swap_to_display, int num_windows, |
- int width, int height, base::WaitableEvent* done); |
+ virtual void Initialize( |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
You've introduced a de-facto requirement that subc
ananta
2011/12/17 00:40:25
Done.
|
+ bool suppress_swap_to_display, int num_windows, |
+ int width, int height, base::WaitableEvent* done); |
// Undo the effects of Initialize() and signal |*done|. |
- void UnInitialize(base::WaitableEvent* done); |
+ virtual void UnInitialize(base::WaitableEvent* done); |
+ // Platform specific window creation. |
+ virtual EGLNativeWindowType PlatformCreateWindow(int top_left_x, |
+ int top_left_y) PURE; |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Is PURE cross-platform? I've only ever seen =0 in
ananta
2011/12/17 00:40:25
Done.
|
+ |
// Return a newly-created GLES2 texture id rendering to a specific window, and |
// signal |*done|. |
void CreateTexture(int window_id, GLuint* texture_id, |
@@ -136,72 +167,46 @@ |
// Delete |texture_id|. |
void DeleteTexture(GLuint texture_id); |
- EGLDisplay egl_display() { return egl_display_; } |
- EGLContext egl_context() { return egl_context_; } |
+ EGLDisplay egl_display() { |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
single-line
ananta
2011/12/17 00:40:25
Done.
|
+ return egl_display_; |
+ } |
+ |
+ EGLContext egl_context() { |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
single line
ananta
2011/12/17 00:40:25
Done.
|
+ return egl_context_; |
+ } |
+ |
MessageLoop* message_loop() { return message_loop_; } |
- private: |
- // Zero-out internal state. Helper for ctor & UnInitialize(). |
+ protected: |
void Clear(); |
- bool suppress_swap_to_display_; |
+ // We ensure all operations are carried out on the same thread by remembering |
+ // where we were Initialized. |
+ MessageLoop* message_loop_; |
int width_; |
int height_; |
- Display* x_display_; |
- std::vector<Window> x_windows_; |
+ bool suppress_swap_to_display_; |
+ int num_windows_; |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Never used.
ananta
2011/12/17 00:40:25
Removed
|
+ |
EGLDisplay egl_display_; |
EGLContext egl_context_; |
std::vector<EGLSurface> egl_surfaces_; |
std::map<GLuint, int> texture_id_to_surface_index_; |
- // We ensure all operations are carried out on the same thread by remembering |
- // where we were Initialized. |
- MessageLoop* message_loop_; |
}; |
-RenderingHelper::RenderingHelper() { |
+RenderingHelperBase::RenderingHelperBase() { |
Clear(); |
} |
-RenderingHelper::~RenderingHelper() { |
- CHECK_EQ(width_, 0) << "Must call UnInitialize before dtor."; |
+RenderingHelperBase::~RenderingHelperBase() { |
+ Clear(); |
} |
-void RenderingHelper::Clear() { |
- suppress_swap_to_display_ = false; |
- width_ = 0; |
- height_ = 0; |
- x_display_ = NULL; |
- x_windows_.clear(); |
- egl_display_ = EGL_NO_DISPLAY; |
- egl_context_ = EGL_NO_CONTEXT; |
- egl_surfaces_.clear(); |
- texture_id_to_surface_index_.clear(); |
- message_loop_ = NULL; |
-} |
- |
-// Helper for Shader creation. |
-static void CreateShader( |
- GLuint program, GLenum type, const char* source, int size) { |
- GLuint shader = glCreateShader(type); |
- glShaderSource(shader, 1, &source, &size); |
- glCompileShader(shader); |
- int result = GL_FALSE; |
- glGetShaderiv(shader, GL_COMPILE_STATUS, &result); |
- if (!result) { |
- char log[4096]; |
- glGetShaderInfoLog(shader, arraysize(log), NULL, log); |
- LOG(FATAL) << log; |
- } |
- glAttachShader(program, shader); |
- glDeleteShader(shader); |
- CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
-} |
- |
-void RenderingHelper::Initialize( |
- bool suppress_swap_to_display, |
- int num_windows, |
- int width, int height, |
- base::WaitableEvent* done) { |
+void RenderingHelperBase::Initialize(bool suppress_swap_to_display, |
+ int num_windows, |
+ int width, |
+ int height, |
+ base::WaitableEvent* done) { |
// Use width_ != 0 as a proxy for the class having already been |
// Initialize()'d, and UnInitialize() before continuing. |
if (width_) { |
@@ -217,16 +222,8 @@ |
height_ = height; |
message_loop_ = MessageLoop::current(); |
CHECK_GT(num_windows, 0); |
+ num_windows_ = num_windows; |
- // Per-display X11 & EGL initialization. |
- CHECK(x_display_ = XOpenDisplay(NULL)); |
- int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); |
- XSetWindowAttributes window_attributes; |
- window_attributes.background_pixel = |
- BlackPixel(x_display_, DefaultScreen(x_display_)); |
- window_attributes.override_redirect = true; |
- |
- egl_display_ = eglGetDisplay(x_display_); |
EGLint major; |
EGLint minor; |
CHECK(eglInitialize(egl_display_, &major, &minor)) << eglGetError(); |
@@ -253,25 +250,15 @@ |
// Arrange X windows whimsically, with some padding. |
int top_left_x = (width + 20) * (i % 4); |
int top_left_y = (height + 12) * (i % 3); |
- Window x_window = XCreateWindow( |
- x_display_, DefaultRootWindow(x_display_), |
- top_left_x, top_left_y, width_, height_, |
- 0 /* border width */, |
- depth, CopyFromParent /* class */, CopyFromParent /* visual */, |
- (CWBackPixel | CWOverrideRedirect), &window_attributes); |
- x_windows_.push_back(x_window); |
- XStoreName(x_display_, x_window, "OmxVideoDecodeAcceleratorTest"); |
- XSelectInput(x_display_, x_window, ExposureMask); |
- XMapWindow(x_display_, x_window); |
+ EGLNativeWindowType window = PlatformCreateWindow(top_left_x, top_left_y); |
EGLSurface egl_surface = |
- eglCreateWindowSurface(egl_display_, egl_config, x_window, NULL); |
+ eglCreateWindowSurface(egl_display_, egl_config, window, NULL); |
egl_surfaces_.push_back(egl_surface); |
CHECK_NE(egl_surface, EGL_NO_SURFACE); |
} |
CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[0], |
egl_surfaces_[0], egl_context_)) << eglGetError(); |
- |
// GLES2 initialization. Note: This is pretty much copy/pasted from |
// media/tools/player_x11/gles_video_renderer.cc, with some simplification |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Drop the Note: since that file is now gone.
ananta
2011/12/17 00:40:25
Done.
|
// applied. |
@@ -319,40 +306,43 @@ |
glEnableVertexAttribArray(tc_location); |
glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, |
kTextureCoordsEgl); |
- |
- done->Signal(); |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Since neither impl does anything after calling thi
|
} |
-void RenderingHelper::UnInitialize(base::WaitableEvent* done) { |
+void RenderingHelperBase::UnInitialize(base::WaitableEvent* done) { |
CHECK_EQ(MessageLoop::current(), message_loop_); |
- // Destroy resources acquired in Initialize, in reverse-acquisition order. |
CHECK(eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, |
EGL_NO_CONTEXT)) << eglGetError(); |
CHECK(eglDestroyContext(egl_display_, egl_context_)); |
for (size_t i = 0; i < egl_surfaces_.size(); ++i) |
CHECK(eglDestroySurface(egl_display_, egl_surfaces_[i])); |
CHECK(eglTerminate(egl_display_)); |
- for (size_t i = 0; i < x_windows_.size(); ++i) { |
- CHECK(XUnmapWindow(x_display_, x_windows_[i])); |
- CHECK(XDestroyWindow(x_display_, x_windows_[i])); |
- } |
- // Mimic newly-created object. |
Clear(); |
- done->Signal(); |
} |
-void RenderingHelper::CreateTexture(int window_id, GLuint* texture_id, |
- base::WaitableEvent* done) { |
+void RenderingHelperBase::Clear() { |
+ suppress_swap_to_display_ = false; |
+ width_ = 0; |
+ height_ = 0; |
+ texture_id_to_surface_index_.clear(); |
+ message_loop_ = NULL; |
+ num_windows_ = 0; |
+ egl_display_ = EGL_NO_DISPLAY; |
+ egl_context_ = EGL_NO_CONTEXT; |
+ egl_surfaces_.clear(); |
+} |
+ |
+void RenderingHelperBase::CreateTexture(int window_id, GLuint* texture_id, |
+ base::WaitableEvent* done) { |
+ CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[window_id], |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Why is this before the trampoline?
ananta
2011/12/17 00:40:25
Stupid mistake :(
|
+ egl_surfaces_[window_id], egl_context_)) |
+ << eglGetError(); |
if (MessageLoop::current() != message_loop_) { |
message_loop_->PostTask( |
FROM_HERE, |
- base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), |
+ base::Bind(&RenderingHelperBase::CreateTexture, base::Unretained(this), |
window_id, texture_id, done)); |
return; |
} |
- CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[window_id], |
- egl_surfaces_[window_id], egl_context_)) |
- << eglGetError(); |
glGenTextures(1, texture_id); |
glBindTexture(GL_TEXTURE_2D, *texture_id); |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, |
@@ -368,13 +358,14 @@ |
done->Signal(); |
} |
-void RenderingHelper::RenderTexture(GLuint texture_id) { |
+void RenderingHelperBase::RenderTexture(GLuint texture_id) { |
CHECK_EQ(MessageLoop::current(), message_loop_); |
glActiveTexture(GL_TEXTURE0); |
glBindTexture(GL_TEXTURE_2D, texture_id); |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); |
+ |
if (!suppress_swap_to_display_) { |
int window_id = texture_id_to_surface_index_[texture_id]; |
CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[window_id], |
@@ -385,11 +376,182 @@ |
CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); |
} |
-void RenderingHelper::DeleteTexture(GLuint texture_id) { |
+void RenderingHelperBase::DeleteTexture(GLuint texture_id) { |
glDeleteTextures(1, &texture_id); |
CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
} |
+#if defined(OS_WIN) |
+// Provides Windows specific functionality for managing resources like HWND's |
+// The OpenGL and GLES management is provided by the RenderingHelperBase class. |
+class Win32RenderingHelper : public RenderingHelperBase { |
+ public: |
+ Win32RenderingHelper(); |
+ virtual ~Win32RenderingHelper(); |
+ |
+ virtual void Initialize( |
+ bool suppress_swap_to_display, int num_windows, |
+ int width, int height, base::WaitableEvent* done) OVERRIDE; |
+ |
+ virtual void UnInitialize(base::WaitableEvent* done) OVERRIDE; |
+ |
+ EGLNativeWindowType PlatformCreateWindow(int top_left_x, |
+ int top_left_y) OVERRIDE; |
+ private: |
+ void Clear(); |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
This shadows the base-class Clear (which isn't vir
ananta
2011/12/17 00:40:25
Replaced this with a virtual override combo Platfo
|
+ |
+ std::vector<HWND> windows_; |
+}; |
+ |
+Win32RenderingHelper::Win32RenderingHelper() |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Single line.
ananta
2011/12/17 00:40:25
Done.
|
+ : windows_(NULL) { |
+} |
+ |
+Win32RenderingHelper::~Win32RenderingHelper() { |
+ Clear(); |
+} |
+ |
+void Win32RenderingHelper::Initialize(bool suppress_swap_to_display, |
+ int num_windows, |
+ int width, |
+ int height, |
+ base::WaitableEvent* done) { |
+ egl_display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ RenderingHelperBase::Initialize(suppress_swap_to_display, num_windows, width, |
+ height, done); |
+ done->Signal(); |
+} |
+ |
+void Win32RenderingHelper::UnInitialize(base::WaitableEvent* done) { |
+ RenderingHelperBase::UnInitialize(done); |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
No need to undo the eglGetDisplay() from Initializ
ananta
2011/12/17 00:40:25
That happens in the base class Clear function. We
|
+ Clear(); |
+ done->Signal(); |
+} |
+ |
+void Win32RenderingHelper::Clear() { |
+ for (size_t i = 0; i < windows_.size(); ++i) { |
+ DestroyWindow(windows_[i]); |
+ } |
+ windows_.clear(); |
+} |
+ |
+EGLNativeWindowType Win32RenderingHelper::PlatformCreateWindow( |
+ int top_left_x, int top_left_y) { |
+ HWND window = CreateWindowEx(0, |
+ L"Static", |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Wrap a bit more aggressively?
ananta
2011/12/17 00:40:25
Done.
|
+ L"VideoDecodeAcceleratorTest", |
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE, |
+ top_left_x, |
+ top_left_y, |
+ width_, |
+ height_, |
+ NULL, |
+ NULL, |
+ NULL, |
+ NULL); |
+ CHECK(window != NULL); |
+ windows_.push_back(window); |
+ return window; |
+} |
+ |
+#else // OS_WIN |
+ |
+// Provides X11 specific functionality for managing X11 resources. The OpenGL |
+// and GLES management is provided by the RenderingHelperBase class. |
+class OmxRenderingHelper : public RenderingHelperBase { |
+ public: |
+ explicit OmxRenderingHelper(); |
+ ~OmxRenderingHelper(); |
+ |
+ // Initialize all structures to prepare to render to one or more windows of |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Commentary isn't necessary for OVERRIDEs. Just pr
ananta
2011/12/17 00:40:25
Done.
|
+ // the specified dimensions. CHECK-fails if any initialization step fails. |
+ // After this returns, texture creation and rendering can be requested. This |
+ // method can be called multiple times, in which case all previously-acquired |
+ // resources and initializations are discarded. If |suppress_swap_to_display| |
+ // then all the usual work is done, except for the final swap of the EGL |
+ // surface to the display. This cuts test times over 50% so is worth doing |
+ // when testing non-rendering-related aspects. |
+ virtual void Initialize( |
+ bool suppress_swap_to_display, int num_windows, |
+ int width, int height, base::WaitableEvent* done) OVERRIDE; |
+ |
+ // Undo the effects of Initialize() and signal |*done|. |
+ virtual void UnInitialize(base::WaitableEvent* done) OVERRIDE; |
+ |
+ virtual EGLNativeWindowType PlatformCreateWindow(int top_left_x, |
+ int top_left_y) OVERRIDE; |
+ |
+ |
+ private: |
+ // Zero-out internal state. Helper for ctor & UnInitialize(). |
+ void Clear(); |
+ |
+ Display* x_display_; |
+ std::vector<Window> x_windows_; |
+}; |
+ |
+OmxRenderingHelper::OmxRenderingHelper() { |
+ Clear(); |
+} |
+ |
+OmxRenderingHelper::~OmxRenderingHelper() { |
+ CHECK_EQ(width_, 0) << "Must call UnInitialize before dtor."; |
+} |
+ |
+void OmxRenderingHelper::Clear() { |
+ x_display_ = NULL; |
+ x_windows_.clear(); |
+} |
+ |
+void OmxRenderingHelper::Initialize( |
+ bool suppress_swap_to_display, |
+ int num_windows, |
+ int width, int height, |
+ base::WaitableEvent* done) { |
+ // Per-display X11 & EGL initialization. |
+ CHECK(x_display_ = XOpenDisplay(NULL)); |
+ int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); |
+ XSetWindowAttributes window_attributes; |
+ window_attributes.background_pixel = |
+ BlackPixel(x_display_, DefaultScreen(x_display_)); |
+ window_attributes.override_redirect = true; |
+ |
+ egl_display_ = eglGetDisplay(x_display_); |
+ |
+ RenderingHelperBase::Initialize(suppress_swap_to_display, num_windows, |
+ width, height, done); |
+ done->Signal(); |
+} |
+ |
+void OmxRenderingHelper::UnInitialize(base::WaitableEvent* done) { |
+ RenderingHelperBase::Uninitialize(); |
+ // Destroy resources acquired in Initialize, in reverse-acquisition order. |
+ for (size_t i = 0; i < x_windows_.size(); ++i) { |
+ CHECK(XUnmapWindow(x_display_, x_windows_[i])); |
+ CHECK(XDestroyWindow(x_display_, x_windows_[i])); |
+ } |
+ // Mimic newly-created object. |
+ Clear(); |
+ done->Signal(); |
+} |
+ |
+EGLNativeWindowType OmxRenderingHelper::PlatformCreateWindow(int top_left_x, |
+ int top_left_y) { |
+ Window x_window = XCreateWindow( |
+ x_display_, DefaultRootWindow(x_display_), |
+ top_left_x, top_left_y, width_, height_, |
+ 0 /* border width */, |
+ depth, CopyFromParent /* class */, CopyFromParent /* visual */, |
+ (CWBackPixel | CWOverrideRedirect), &window_attributes); |
+ x_windows_.push_back(x_window); |
+ XStoreName(x_display_, x_window, "VideoDecodeAcceleratorTest"); |
+ XSelectInput(x_display_, x_window, ExposureMask); |
+ XMapWindow(x_display_, x_window); |
+ return x_window; |
+} |
+ |
+#endif // OS_WIN |
+ |
// State of the EglRenderingVDAClient below. Order matters here as the test |
// makes assumptions about it. |
enum ClientState { |
@@ -463,7 +625,7 @@ |
// |delete_decoder_state| indicates when the underlying decoder should be |
// Destroy()'d and deleted and can take values: N<0: delete after -N Decode() |
// calls have been made, N>=0 means interpret as ClientState. |
- EglRenderingVDAClient(RenderingHelper* rendering_helper, |
+ EglRenderingVDAClient(RenderingHelperBase* rendering_helper, |
int rendering_window_id, |
ClientStateNotification* note, |
const std::string& encoded_data, |
@@ -514,7 +676,8 @@ |
// Request decode of the next batch of NALUs in the encoded data. |
void DecodeNextNALUs(); |
- RenderingHelper* rendering_helper_; |
+ RenderingHelperBase* rendering_helper_; |
+ |
int rendering_window_id_; |
std::string encoded_data_; |
const int num_NALUs_per_decode_; |
@@ -523,7 +686,11 @@ |
size_t encoded_data_next_pos_to_decode_; |
int next_bitstream_buffer_id_; |
ClientStateNotification* note_; |
+#if defined(OS_WIN) |
+ scoped_refptr<DXVAVideoDecodeAccelerator> decoder_; |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
Can this simply store a scoped_refptr<media::Video
ananta
2011/12/17 00:40:25
Done.
|
+#else // OS_WIN |
scoped_refptr<OmxVideoDecodeAccelerator> decoder_; |
+#endif // OS_WIN |
std::set<int> outstanding_texture_ids_; |
int reset_after_frame_num_; |
int delete_decoder_state_; |
@@ -537,7 +704,7 @@ |
}; |
EglRenderingVDAClient::EglRenderingVDAClient( |
- RenderingHelper* rendering_helper, |
+ RenderingHelperBase* rendering_helper, |
int rendering_window_id, |
ClientStateNotification* note, |
const std::string& encoded_data, |
@@ -569,8 +736,13 @@ |
void EglRenderingVDAClient::CreateDecoder() { |
CHECK(decoder_deleted()); |
+#if defined(OS_WIN) |
+ decoder_ = new DXVAVideoDecodeAccelerator(this, |
+ base::GetCurrentProcessHandle()); |
+#else // OS_WIN |
decoder_ = new OmxVideoDecodeAccelerator(this); |
decoder_->SetEglState(egl_display(), egl_context()); |
+#endif // OS_WIN |
SetState(CS_DECODER_SET); |
if (decoder_deleted()) |
return; |
@@ -785,7 +957,7 @@ |
// - Number of concurrent in-flight Decode() calls per decoder. |
// - reset_after_frame_num: see EglRenderingVDAClient ctor. |
// - delete_decoder_phase: see EglRenderingVDAClient ctor. |
-class OmxVideoDecodeAcceleratorTest |
+class VideoDecodeAcceleratorTest |
: public ::testing::TestWithParam< |
Tuple5<int, int, int, ResetPoint, ClientState> > { |
}; |
@@ -809,7 +981,7 @@ |
// Test the most straightforward case possible: data is decoded from a single |
// chunk and rendered to the screen. |
-TEST_P(OmxVideoDecodeAcceleratorTest, TestSimpleDecode) { |
+TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { |
// Can be useful for debugging VLOGs from OVDA. |
// logging::SetMinLogLevel(-1); |
@@ -845,17 +1017,22 @@ |
// Read in the video data. |
std::string data_str; |
- CHECK(file_util::ReadFileToString(FilePath(test_video_file), &data_str)); |
+ CHECK(file_util::ReadFileToString(FilePath(UTF8ToWide(test_video_file)), |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
This is win-specific.
Instead use FILE_PATH_LITERA
ananta
2011/12/17 00:40:25
Done.
|
+ &data_str)); |
// Initialize the rendering helper. |
base::Thread rendering_thread("EglRenderingVDAClientThread"); |
rendering_thread.Start(); |
- RenderingHelper rendering_helper; |
+#if defined(OS_WIN) |
+ Win32RenderingHelper rendering_helper; |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
A crazy idea appears: if you named both renderingh
ananta
2011/12/17 00:40:25
Done.
|
+#else // OS_WIN |
+ OmxRenderingHelper rendering_helper; |
+#endif // OS_WIN |
base::WaitableEvent done(false, false); |
rendering_thread.message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&RenderingHelper::Initialize, |
+ base::Bind(&RenderingHelperBase::Initialize, |
base::Unretained(&rendering_helper), |
suppress_swap_to_display, num_concurrent_decoders, |
frame_width, frame_height, &done)); |
@@ -889,7 +1066,8 @@ |
// We expect initialization to fail only when more than the supported |
// number of decoders is instantiated. Assert here that something else |
// didn't trigger failure. |
- ASSERT_GT(num_concurrent_decoders, kMinSupportedNumConcurrentDecoders); |
+ ASSERT_GT(num_concurrent_decoders, |
+ static_cast<size_t>(kMinSupportedNumConcurrentDecoders)); |
continue; |
} |
ASSERT_EQ(state, CS_INITIALIZED); |
@@ -937,7 +1115,7 @@ |
¬es)); |
rendering_thread.message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&RenderingHelper::UnInitialize, |
+ base::Bind(&RenderingHelperBase::UnInitialize, |
base::Unretained(&rendering_helper), |
&done)); |
done.Wait(); |
@@ -947,14 +1125,14 @@ |
// Test that Reset() mid-stream works fine and doesn't affect decoding even when |
// Decode() calls are made during the reset. |
INSTANTIATE_TEST_CASE_P( |
- MidStreamReset, OmxVideoDecodeAcceleratorTest, |
+ MidStreamReset, VideoDecodeAcceleratorTest, |
::testing::Values( |
MakeTuple(1, 1, 1, static_cast<ResetPoint>(100), CS_RESET))); |
// Test that Destroy() mid-stream works fine (primarily this is testing that no |
// crashes occur). |
INSTANTIATE_TEST_CASE_P( |
- TearDownTiming, OmxVideoDecodeAcceleratorTest, |
+ TearDownTiming, VideoDecodeAcceleratorTest, |
::testing::Values( |
MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_DECODER_SET), |
MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_INITIALIZED), |
@@ -970,7 +1148,7 @@ |
// Test that decoding various variation works: multiple concurrent decoders and |
// multiple NALUs per Decode() call. |
INSTANTIATE_TEST_CASE_P( |
- DecodeVariations, OmxVideoDecodeAcceleratorTest, |
+ DecodeVariations, VideoDecodeAcceleratorTest, |
::testing::Values( |
MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET), |
MakeTuple(1, 1, 10, END_OF_STREAM_RESET, CS_RESET), |
@@ -991,7 +1169,7 @@ |
// Find out how many concurrent decoders can go before we exhaust system |
// resources. |
INSTANTIATE_TEST_CASE_P( |
- ResourceExhaustion, OmxVideoDecodeAcceleratorTest, |
+ ResourceExhaustion, VideoDecodeAcceleratorTest, |
::testing::Values( |
// +0 hack below to promote enum to int. |
MakeTuple(1, kMinSupportedNumConcurrentDecoders + 0, 1, |
@@ -1009,16 +1187,23 @@ |
int main(int argc, char **argv) { |
testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args. |
- CommandLine cmd_line(argc, argv); // Must run after InitGoogleTest. |
- CommandLine::SwitchMap switches = cmd_line.GetSwitches(); |
+ CommandLine::Init(argc, argv); |
+ |
+ CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
+ DCHECK(cmd_line); |
+ |
+ CommandLine::SwitchMap switches = cmd_line->GetSwitches(); |
for (CommandLine::SwitchMap::const_iterator it = switches.begin(); |
it != switches.end(); ++it) { |
if (it->first == "test_video_data") { |
+#if defined(OS_WIN) |
Ami GONE FROM CHROMIUM
2011/12/16 07:38:54
FILE_PATH_LITERAL should let you lose this.
ananta
2011/12/17 00:40:25
Done.
|
+ test_video_data = WideToUTF8(it->second); |
+#else // OS_WIN |
test_video_data = it->second.c_str(); |
+#endif // OS_WIN |
continue; |
} |
LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
} |
- |
return RUN_ALL_TESTS(); |
} |