diff options
author | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-05 21:31:34 +0000 |
---|---|---|
committer | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-05 21:31:34 +0000 |
commit | c9ed565be014f6dc53c977ec0a4205296e573ba2 (patch) | |
tree | 47441e0120535adfad311359c55b78c97a54412b /content | |
parent | fe390ab7e359396a0c57de2839a38d18dc9199a0 (diff) | |
download | chromium_src-c9ed565be014f6dc53c977ec0a4205296e573ba2.zip chromium_src-c9ed565be014f6dc53c977ec0a4205296e573ba2.tar.gz chromium_src-c9ed565be014f6dc53c977ec0a4205296e573ba2.tar.bz2 |
Revert 145556 - Make VideoDecodeAcceleratorTest work for VAVDA and fixed a bunch of bugs the test found
- The bulk of the CL turns RenderingHelperEGL into RenderingHelperGL (by making
it EGL-vs-GLX-agnostic)
- VaapiH264Decoder::AssignPictureBuffer: it's fine to restart decode after a
Reset(), so allow that.
- VaapiH264Decoder::FillVARefFramesFromDPB: faster/clearer error condition, and
small cleanup.
- VaapiH264Decoder::Flush: emit the final in-progress picture.
- VaapiH264Decoder::DecodeOneFrame: insist on having at least two output
surfaces before attempting a decode to avoid running out.
- VaapiVideoDecodeAccelerator::client_ is now a WeakPtr instead of a raw
pointer, to do correct lifetime accounting. This also allows dropping the
helper methods on VAVDA whose only purpose was to triple-check client_'s
presence before dispatching calls on it.
- VaapiVideoDecodeAccelerator::InitialDecodeTask: account for the possibility of
multiple in-flight Decode()s, and remove unnecessary task-posting.
Two remaining issues are:
- the test-25fps.h264 testdata file triggers bug#135548
- the pure-decode performance (at least in Debug) of VAVDA is not as good as the reference that vdatest was originally built for, so some tests "fail" on lower-than-expected fps rates. This probably just needs to be a per-platform expectation.
TBR=brettw@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10701071
TBR=fischman@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10695109
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145559 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/common/gpu/media/rendering_helper_egl.cc (renamed from content/common/gpu/media/rendering_helper_gl.cc) | 324 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_h264_decoder.cc | 45 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_video_decode_accelerator.cc | 106 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_video_decode_accelerator.h | 22 | ||||
-rw-r--r-- | content/common/gpu/media/video_decode_accelerator_unittest.cc | 140 | ||||
-rw-r--r-- | content/content_common.gypi | 2 | ||||
-rw-r--r-- | content/content_tests.gypi | 109 |
7 files changed, 334 insertions, 414 deletions
diff --git a/content/common/gpu/media/rendering_helper_gl.cc b/content/common/gpu/media/rendering_helper_egl.cc index 20fd593..dc15309 100644 --- a/content/common/gpu/media/rendering_helper_gl.cc +++ b/content/common/gpu/media/rendering_helper_egl.cc @@ -6,37 +6,21 @@ #include <map> -#if defined(OS_WIN) -#include "third_party/angle/include/EGL/egl.h" // Must precede ui/gl headers! -#endif - #include "base/bind.h" #include "base/mac/scoped_nsautorelease_pool.h" #include "base/message_loop.h" #include "base/stringize_macros.h" #include "base/synchronization/waitable_event.h" +#include "third_party/angle/include/EGL/egl.h" + +#if defined(OS_WIN) #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface.h" - -#if defined(ARCH_CPU_ARMEL) +#else // OS_WIN #include "third_party/angle/include/GLES2/gl2.h" -#endif // ARCH_CPU_ARMEL - -#if !defined(OS_WIN) && defined(ARCH_CPU_X86_FAMILY) -#define GL_VARIANT_GLX 1 -typedef GLXWindow NativeWindowType; -typedef GLXContext NativeContextType; -struct ScopedPtrXFree { - void operator()(void* x) const { ::XFree(x); } -}; -#else -#define GL_VARIANT_EGL 1 -typedef EGLNativeWindowType NativeWindowType; -typedef EGLContext NativeContextType; -typedef EGLSurface NativeSurfaceType; -#endif +#endif // OS_WIN // Helper for Shader creation. static void CreateShader(GLuint program, @@ -60,10 +44,10 @@ static void CreateShader(GLuint program, namespace video_test_util { -class RenderingHelperGL : public RenderingHelper { +class RenderingHelperEGL : public RenderingHelper { public: - RenderingHelperGL(); - virtual ~RenderingHelperGL(); + RenderingHelperEGL(); + virtual ~RenderingHelperEGL(); // Implement RenderingHelper. virtual void Initialize(bool suppress_swap_to_display, @@ -84,36 +68,37 @@ class RenderingHelperGL : public RenderingHelper { private: void Clear(); - // Make window_id's surface current w/ the GL context, or release the context - // if |window_id < 0|. - void MakeCurrent(int window_id); + // Platform specific Init/Uninit. + void PlatformInitialize(); + void PlatformUnInitialize(); + + // Platform specific window creation. + EGLNativeWindowType PlatformCreateWindow(int top_left_x, int top_left_y); + + // Platform specific display surface returned here. + EGLDisplay PlatformGetDisplay(); MessageLoop* message_loop_; int width_; int height_; bool suppress_swap_to_display_; - NativeContextType gl_context_; + EGLDisplay egl_display_; + EGLContext egl_context_; + std::vector<EGLSurface> egl_surfaces_; std::map<uint32, int> texture_id_to_surface_index_; -#if defined(GL_VARIANT_EGL) - EGLDisplay gl_display_; - std::vector<NativeSurfaceType> gl_surfaces_; -#else - XVisualInfo* x_visual_; -#endif - #if defined(OS_WIN) std::vector<HWND> windows_; -#else +#else // OS_WIN Display* x_display_; std::vector<Window> x_windows_; -#endif +#endif // OS_WIN }; // static RenderingHelper* RenderingHelper::Create() { - return new RenderingHelperGL; + return new RenderingHelperEGL; } // static @@ -133,36 +118,16 @@ void RenderingHelper::InitializePlatform() { #endif // OS_WIN } -RenderingHelperGL::RenderingHelperGL() { +RenderingHelperEGL::RenderingHelperEGL() { Clear(); } -RenderingHelperGL::~RenderingHelperGL() { +RenderingHelperEGL::~RenderingHelperEGL() { CHECK_EQ(width_, 0) << "Must call UnInitialize before dtor."; Clear(); } -void RenderingHelperGL::MakeCurrent(int window_id) { -#if GL_VARIANT_GLX - if (window_id < 0) { - CHECK(glXMakeContextCurrent(x_display_, GLX_NONE, GLX_NONE, NULL)); - } else { - CHECK(glXMakeContextCurrent( - x_display_, x_windows_[window_id], x_windows_[window_id], gl_context_)); - } -#else // EGL - if (window_id < 0) { - CHECK(eglMakeCurrent(gl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT)) << eglGetError(); - } else { - CHECK(eglMakeCurrent(gl_display_, gl_surfaces_[window_id], - gl_surfaces_[window_id], gl_context_)) - << eglGetError(); - } -#endif -} - -void RenderingHelperGL::Initialize(bool suppress_swap_to_display, +void RenderingHelperEGL::Initialize(bool suppress_swap_to_display, int num_windows, int width, int height, @@ -183,43 +148,13 @@ void RenderingHelperGL::Initialize(bool suppress_swap_to_display, message_loop_ = MessageLoop::current(); CHECK_GT(num_windows, 0); -#if GL_VARIANT_GLX - x_display_ = base::MessagePumpForUI::GetDefaultXDisplay(); - gfx::InitializeGLBindings(gfx::kGLImplementationDesktopGL); - CHECK(glXQueryVersion(x_display_, NULL, NULL)); - const int fbconfig_attr[] = { - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, - GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, - GLX_Y_INVERTED_EXT, GL_FALSE, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_ALPHA_SIZE, 1, - GLX_DOUBLEBUFFER, True, - GL_NONE, - }; - int num_fbconfigs; - scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> glx_fb_configs( - glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, - &num_fbconfigs)); - CHECK(glx_fb_configs.get()); - CHECK_GT(num_fbconfigs, 0); - x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]); - CHECK(x_visual_); - gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true); - CHECK(gl_context_); - -#else // EGL -#if defined(OS_WIN) - gl_display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); - CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError(); -#else - x_display_ = base::MessagePumpForUI::GetDefaultXDisplay(); - gl_display_ = eglGetDisplay(x_display_); - CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError(); -#endif + PlatformInitialize(); + + egl_display_ = PlatformGetDisplay(); + + EGLint major; + EGLint minor; + CHECK(eglInitialize(egl_display_, &major, &minor)) << eglGetError(); static EGLint rgba8888[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, @@ -230,14 +165,13 @@ void RenderingHelperGL::Initialize(bool suppress_swap_to_display, }; EGLConfig egl_config; int num_configs; - CHECK(eglChooseConfig(gl_display_, rgba8888, &egl_config, 1, &num_configs)) + CHECK(eglChooseConfig(egl_display_, rgba8888, &egl_config, 1, &num_configs)) << eglGetError(); CHECK_GE(num_configs, 1); static EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - gl_context_ = eglCreateContext( - gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); - CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError(); -#endif + egl_context_ = eglCreateContext( + egl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); + CHECK_NE(egl_context_, EGL_NO_CONTEXT) << eglGetError(); // Per-window/surface X11 & EGL initialization. for (int i = 0; i < num_windows; ++i) { @@ -245,63 +179,28 @@ void RenderingHelperGL::Initialize(bool suppress_swap_to_display, int top_left_x = (width + 20) * (i % 4); int top_left_y = (height + 12) * (i % 3); -#if defined(OS_WIN) - NativeWindowType window = - CreateWindowEx(0, L"Static", 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); -#else - int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); - CHECK_EQ(depth, x_visual_->depth); - - XSetWindowAttributes window_attributes; - window_attributes.background_pixel = - BlackPixel(x_display_, DefaultScreen(x_display_)); - window_attributes.override_redirect = true; - - NativeWindowType 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); - XStoreName(x_display_, window, "VideoDecodeAcceleratorTest"); - XSelectInput(x_display_, window, ExposureMask); - XMapWindow(x_display_, window); - x_windows_.push_back(window); -#endif - -#if GL_VARIANT_EGL - NativeSurfaceType egl_surface = - eglCreateWindowSurface(gl_display_, egl_config, window, NULL); - gl_surfaces_.push_back(egl_surface); + EGLNativeWindowType window = PlatformCreateWindow(top_left_x, top_left_y); + EGLSurface egl_surface = + eglCreateWindowSurface(egl_display_, egl_config, window, NULL); + egl_surfaces_.push_back(egl_surface); CHECK_NE(egl_surface, EGL_NO_SURFACE); -#endif - MakeCurrent(i); } + CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[0], + egl_surfaces_[0], egl_context_)) << eglGetError(); static const float kVertices[] = { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; - static const float kTextureCoords[] = { 0, 1, 0, 0, 1, 1, 1, 0, }; + static const float kTextureCoordsEgl[] = { 0, 1, 0, 0, 1, 1, 1, 0, }; static const char kVertexShader[] = STRINGIZE( varying vec2 interp_tc; attribute vec4 in_pos; attribute vec2 in_tc; void main() { -#if GL_VARIANT_GLX - interp_tc = vec2(in_tc.x, 1.0 - in_tc.y); -#else // EGL interp_tc = in_tc; -#endif gl_Position = in_pos; }); - static const char kFragmentShader[] = STRINGIZE( -#if GL_VARIANT_EGL + static const char kFragmentShaderEgl[] = STRINGIZE( precision mediump float; -#endif varying vec2 interp_tc; uniform sampler2D tex; void main() { @@ -311,7 +210,7 @@ void RenderingHelperGL::Initialize(bool suppress_swap_to_display, CreateShader(program, GL_VERTEX_SHADER, kVertexShader, arraysize(kVertexShader)); CreateShader(program, GL_FRAGMENT_SHADER, - kFragmentShader, arraysize(kFragmentShader)); + kFragmentShaderEgl, arraysize(kFragmentShaderEgl)); glLinkProgram(program); int result = GL_FALSE; glGetProgramiv(program, GL_LINK_STATUS, &result); @@ -329,27 +228,24 @@ void RenderingHelperGL::Initialize(bool suppress_swap_to_display, glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); int tc_location = glGetAttribLocation(program, "in_tc"); glEnableVertexAttribArray(tc_location); - glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); + glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, + kTextureCoordsEgl); done->Signal(); } -void RenderingHelperGL::UnInitialize(base::WaitableEvent* done) { +void RenderingHelperEGL::UnInitialize(base::WaitableEvent* done) { CHECK_EQ(MessageLoop::current(), message_loop_); -#if GL_VARIANT_GLX - - glXDestroyContext(x_display_, gl_context_); -#else // EGL - MakeCurrent(-1); - CHECK(eglDestroyContext(gl_display_, gl_context_)); - for (size_t i = 0; i < gl_surfaces_.size(); ++i) - CHECK(eglDestroySurface(gl_display_, gl_surfaces_[i])); - CHECK(eglTerminate(gl_display_)); -#endif + 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_)); Clear(); done->Signal(); } -void RenderingHelperGL::CreateTexture(int window_id, +void RenderingHelperEGL::CreateTexture(int window_id, uint32 texture_target, uint32* texture_id, base::WaitableEvent* done) { @@ -361,7 +257,9 @@ void RenderingHelperGL::CreateTexture(int window_id, return; } CHECK_EQ(static_cast<uint32>(GL_TEXTURE_2D), texture_target); - MakeCurrent(window_id); + 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, @@ -372,65 +270,86 @@ void RenderingHelperGL::CreateTexture(int window_id, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); + CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); CHECK(texture_id_to_surface_index_.insert( std::make_pair(*texture_id, window_id)).second); done->Signal(); } -void RenderingHelperGL::RenderTexture(uint32 texture_id) { +void RenderingHelperEGL::RenderTexture(uint32 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); - if (suppress_swap_to_display_) - return; - - int window_id = texture_id_to_surface_index_[texture_id]; - MakeCurrent(window_id); -#if GL_VARIANT_GLX - glXSwapBuffers(x_display_, x_windows_[window_id]); -#else // EGL - eglSwapBuffers(gl_display_, gl_surfaces_[window_id]); CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); -#endif + if (!suppress_swap_to_display_) { + int window_id = texture_id_to_surface_index_[texture_id]; + CHECK(eglMakeCurrent(egl_display_, egl_surfaces_[window_id], + egl_surfaces_[window_id], egl_context_)) + << eglGetError(); + eglSwapBuffers(egl_display_, egl_surfaces_[window_id]); + } + CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); } -void RenderingHelperGL::DeleteTexture(uint32 texture_id) { +void RenderingHelperEGL::DeleteTexture(uint32 texture_id) { glDeleteTextures(1, &texture_id); CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); } -void* RenderingHelperGL::GetGLContext() { - return gl_context_; +void* RenderingHelperEGL::GetGLContext() { + return egl_context_; } -void* RenderingHelperGL::GetGLDisplay() { -#if GL_VARIANT_GLX - return x_display_; -#else // EGL - return gl_display_; -#endif +void* RenderingHelperEGL::GetGLDisplay() { + return egl_display_; } -void RenderingHelperGL::Clear() { +void RenderingHelperEGL::Clear() { suppress_swap_to_display_ = false; width_ = 0; height_ = 0; texture_id_to_surface_index_.clear(); message_loop_ = NULL; - gl_context_ = NULL; -#if GL_VARIANT_EGL - gl_display_ = EGL_NO_DISPLAY; - gl_surfaces_.clear(); -#endif + egl_display_ = EGL_NO_DISPLAY; + egl_context_ = EGL_NO_CONTEXT; + egl_surfaces_.clear(); + PlatformUnInitialize(); +} #if defined(OS_WIN) +void RenderingHelperEGL::PlatformInitialize() {} + +void RenderingHelperEGL::PlatformUnInitialize() { for (size_t i = 0; i < windows_.size(); ++i) { DestroyWindow(windows_[i]); } windows_.clear(); -#else +} + +EGLNativeWindowType RenderingHelperEGL::PlatformCreateWindow( + int top_left_x, int top_left_y) { + HWND window = CreateWindowEx(0, L"Static", 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; +} + +EGLDisplay RenderingHelperEGL::PlatformGetDisplay() { + return eglGetDisplay(EGL_DEFAULT_DISPLAY); +} + +#else // OS_WIN + +void RenderingHelperEGL::PlatformInitialize() { + CHECK(x_display_ = base::MessagePumpForUI::GetDefaultXDisplay()); +} + +void RenderingHelperEGL::PlatformUnInitialize() { // 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])); @@ -439,7 +358,34 @@ void RenderingHelperGL::Clear() { // Mimic newly created object. x_display_ = NULL; x_windows_.clear(); -#endif } +EGLDisplay RenderingHelperEGL::PlatformGetDisplay() { + return eglGetDisplay(x_display_); +} + +EGLNativeWindowType RenderingHelperEGL::PlatformCreateWindow(int top_left_x, + int top_left_y) { + 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; + + 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 + } // namespace video_test_util diff --git a/content/common/gpu/media/vaapi_h264_decoder.cc b/content/common/gpu/media/vaapi_h264_decoder.cc index 29a11c4..d4a5676 100644 --- a/content/common/gpu/media/vaapi_h264_decoder.cc +++ b/content/common/gpu/media/vaapi_h264_decoder.cc @@ -580,8 +580,6 @@ bool VaapiH264Decoder::AssignPictureBuffer(int32 picture_buffer_id, bool VaapiH264Decoder::CreateVASurfaces() { DCHECK_NE(pic_width_, -1); DCHECK_NE(pic_height_, -1); - if (state_ == kAfterReset) - return true; DCHECK_EQ(state_, kInitialized); // Allocate VASurfaces in driver. @@ -675,27 +673,24 @@ int VaapiH264Decoder::FillVARefFramesFromDPB(VAPictureH264 *va_pics, // Can only be called when all surfaces are already bound // to textures (cannot be run at the same time as AssignPictureBuffer). bool VaapiH264Decoder::AssignSurfaceToPoC(int poc) { - DCHECK_GT(num_available_decode_surfaces_, 0) << decode_surfaces_.size(); - // Find a surface not currently holding data used for reference and/or // to be displayed and mark it as used. DecodeSurfaces::iterator iter = decode_surfaces_.begin(); for (; iter != decode_surfaces_.end(); ++iter) { - if (!iter->second->available()) - continue; - - --num_available_decode_surfaces_; - DCHECK_GE(num_available_decode_surfaces_, 0); - - // Associate with input id and poc and mark as unavailable. - iter->second->Acquire(curr_input_id_, poc); - DVLOG(4) << "Will use surface " << iter->second->va_surface_id() - << " for POC " << iter->second->poc() - << " input ID: " << iter->second->input_id(); - bool inserted = poc_to_decode_surfaces_.insert(std::make_pair( - poc, iter->second.get())).second; - DCHECK(inserted); - return true; + if (iter->second->available()) { + --num_available_decode_surfaces_; + DCHECK_GE(num_available_decode_surfaces_, 0); + + // Associate with input id and poc and mark as unavailable. + iter->second->Acquire(curr_input_id_, poc); + DVLOG(4) << "Will use surface " << iter->second->va_surface_id() + << " for POC " << iter->second->poc() + << " input ID: " << iter->second->input_id(); + bool inserted = poc_to_decode_surfaces_.insert(std::make_pair(poc, + iter->second.get())).second; + DCHECK(inserted); + return true; + } } // Could not find an available surface. @@ -894,7 +889,7 @@ bool VaapiH264Decoder::SendVASliceParam(H264SliceHeader* slice_hdr) { SHDRToSP(slice_beta_offset_div2); if (((slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) && - pps->weighted_pred_flag) || + pps->weighted_pred_flag) || (slice_hdr->IsBSlice() && pps->weighted_bipred_idc == 1)) { SHDRToSP(luma_log2_weight_denom); SHDRToSP(chroma_log2_weight_denom); @@ -1506,7 +1501,6 @@ bool VaapiH264Decoder::OutputPic(H264Picture* pic) { bool VaapiH264Decoder::Flush() { // Output all pictures that are waiting to be outputted. - FinishPrevFrameIfPresent(); H264Picture::PtrVector to_output; dpb_.GetNotOutputtedPicsAppending(to_output); // Sort them by ascending POC to output in order. @@ -1986,7 +1980,7 @@ VaapiH264Decoder::DecResult VaapiH264Decoder::DecodeInitial(int32 input_id) { // have all reference pictures that they may require. // fallthrough default: - // Skip everything unless it's SPS or an IDR slice (if after reset). + // Skip everything unless it's PPS or an IDR slice (if after reset). DVLOG(4) << "Skipping NALU"; break; } @@ -2014,6 +2008,9 @@ VaapiH264Decoder::DecResult VaapiH264Decoder::DecodeOneFrame(int32 input_id) { if (state_ != kDecoding) { DVLOG(1) << "Decoder not ready: error in stream or not initialized"; return kDecodeError; + } else if (num_available_decode_surfaces_ < 1) { + DVLOG(4) << "No output surfaces available"; + return kNoOutputAvailable; } // All of the actions below might result in decoding a picture from @@ -2022,10 +2019,6 @@ VaapiH264Decoder::DecResult VaapiH264Decoder::DecodeOneFrame(int32 input_id) { // Note: this may drop some already decoded frames if there are errors // further in the stream, but we are OK with that. while (1) { - if (num_available_decode_surfaces_ < 1) { - DVLOG(4) << "No output surfaces available"; - return kNoOutputAvailable; - } par_res = parser_.AdvanceToNextNALU(&nalu); if (par_res == H264Parser::kEOStream) return kNeedMoreStreamData; diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index 389d406..239e7fa 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc @@ -21,6 +21,7 @@ do { \ if (!(result)) { \ DVLOG(1) << log; \ + Destroy(); \ NotifyError(error_code); \ return ret; \ } \ @@ -43,11 +44,9 @@ void VaapiVideoDecodeAccelerator::NotifyError(Error error) { DVLOG(1) << "Notifying of error " << error; - if (client_) { + if (client_) client_->NotifyError(error); - client_ptr_factory_.InvalidateWeakPtrs(); - } - Destroy(); + client_ = NULL; } VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( @@ -58,10 +57,9 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( input_ready_(&lock_), output_ready_(&lock_), message_loop_(MessageLoop::current()), - client_ptr_factory_(client), - client_(client_ptr_factory_.GetWeakPtr()), + client_(client), decoder_thread_("VaapiDecoderThread") { - DCHECK(client); + DCHECK(client_); } VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() { @@ -89,10 +87,15 @@ bool VaapiVideoDecodeAccelerator::Initialize( state_ = kInitialized; message_loop_->PostTask(FROM_HERE, base::Bind( - &Client::NotifyInitializeDone, client_)); + &VaapiVideoDecodeAccelerator::NotifyInitializeDone, this)); return true; } +void VaapiVideoDecodeAccelerator::NotifyInitializeDone() { + DCHECK_EQ(message_loop_, MessageLoop::current()); + client_->NotifyInitializeDone(); +} + // TODO(posciak, fischman): try to move these to constructor parameters, // but while removing SetEglState from OVDA as well for symmetry. void VaapiVideoDecodeAccelerator::SetGlxState(Display* x_display, @@ -102,6 +105,14 @@ void VaapiVideoDecodeAccelerator::SetGlxState(Display* x_display, glx_context_ = glx_context; } +void VaapiVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) { + DCHECK_EQ(message_loop_, MessageLoop::current()); + + DVLOG(4) << "Notifying end of input buffer " << input_buffer_id; + if (client_) + client_->NotifyEndOfBitstreamBuffer(input_buffer_id); +} + void VaapiVideoDecodeAccelerator::SyncAndNotifyPictureReady(int32 input_id, int32 output_id) { DCHECK_EQ(message_loop_, MessageLoop::current()); @@ -115,9 +126,11 @@ void VaapiVideoDecodeAccelerator::SyncAndNotifyPictureReady(int32 input_id, PLATFORM_FAILURE, ); // And notify the client a picture is ready to be displayed. + media::Picture picture(output_id, input_id); DVLOG(4) << "Notifying output picture id " << output_id << " for input "<< input_id << " is ready"; - client_->PictureReady(media::Picture(output_id, input_id)); + if (client_) + client_->PictureReady(picture); } void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer( @@ -146,16 +159,6 @@ void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer( void VaapiVideoDecodeAccelerator::InitialDecodeTask() { DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); - // Since multiple Decode()'s can be in flight at once, it's possible that a - // Decode() that seemed like an initial one is actually later in the stream - // and we're already kDecoding. Let the normal DecodeTask take over in that - // case. - { - base::AutoLock auto_lock(lock_); - if (state_ != kInitialized && state_ != kIdle) - return; - } - // Try to initialize or resume playback after reset. for (;;) { if (!GetInputBuffer()) @@ -166,23 +169,10 @@ void VaapiVideoDecodeAccelerator::InitialDecodeTask() { curr_input_buffer_->id); switch (res) { case VaapiH264Decoder::kReadyToDecode: - if (state_ == kInitialized) { - base::AutoLock auto_lock(lock_); - state_ = kPicturesRequested; - int num_pics = decoder_.GetRequiredNumOfPictures(); - gfx::Size size(decoder_.pic_width(), decoder_.pic_height()); - DVLOG(1) << "Requesting " << num_pics << " pictures of size: " - << size.width() << "x" << size.height(); - message_loop_->PostTask(FROM_HERE, base::Bind( - &Client::ProvidePictureBuffers, client_, - num_pics, size, GL_TEXTURE_2D)); - } else { - base::AutoLock auto_lock(lock_); - DCHECK_EQ(state_, kIdle); - state_ = kDecoding; - decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( - &VaapiVideoDecodeAccelerator::DecodeTask, this)); - } + message_loop_->PostTask(FROM_HERE, base::Bind( + &VaapiVideoDecodeAccelerator::ReadyToDecode, this, + decoder_.GetRequiredNumOfPictures(), + gfx::Size(decoder_.pic_width(), decoder_.pic_height()))); return; case VaapiH264Decoder::kNeedMoreStreamData: @@ -256,9 +246,8 @@ void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer() { DCHECK(curr_input_buffer_.get()); int32 id = curr_input_buffer_->id; curr_input_buffer_.reset(); - DVLOG(4) << "End of input buffer " << id; message_loop_->PostTask(FROM_HERE, base::Bind( - &Client::NotifyEndOfBitstreamBuffer, client_, id)); + &VaapiVideoDecodeAccelerator::NotifyInputBufferRead, this, id)); } bool VaapiVideoDecodeAccelerator::GetOutputBuffers() { @@ -328,6 +317,29 @@ void VaapiVideoDecodeAccelerator::DecodeTask() { } } +void VaapiVideoDecodeAccelerator::ReadyToDecode(int num_pics, + const gfx::Size& size) { + DCHECK_EQ(message_loop_, MessageLoop::current()); + + base::AutoLock auto_lock(lock_); + switch (state_) { + case kInitialized: + DVLOG(1) << "Requesting " << num_pics << " pictures of size: " + << size.width() << "x" << size.height(); + if (client_) + client_->ProvidePictureBuffers(num_pics, size, GL_TEXTURE_2D); + state_ = kPicturesRequested; + break; + case kIdle: + state_ = kDecoding; + decoder_thread_.message_loop()->PostTask(FROM_HERE, + base::Bind(&VaapiVideoDecodeAccelerator::DecodeTask, this)); + break; + default: + NOTREACHED() << "Invalid state"; + } +} + void VaapiVideoDecodeAccelerator::Decode( const media::BitstreamBuffer& bitstream_buffer) { DCHECK_EQ(message_loop_, MessageLoop::current()); @@ -440,8 +452,8 @@ void VaapiVideoDecodeAccelerator::FinishFlush() { state_ = kIdle; - message_loop_->PostTask(FROM_HERE, base::Bind( - &Client::NotifyFlushDone, client_)); + if (client_) + client_->NotifyFlushDone(); DVLOG(1) << "Flush finished"; } @@ -483,22 +495,18 @@ void VaapiVideoDecodeAccelerator::FinishReset() { base::AutoLock auto_lock(lock_); if (state_ != kResetting) { - DCHECK(state_ == kDestroying || state_ == kUninitialized) << state_; + DCHECK_EQ(state_, kDestroying); return; // We could've gotten destroyed already. } // Drop all remaining input buffers, if present. - while (!input_buffers_.empty()) { - message_loop_->PostTask(FROM_HERE, base::Bind( - &Client::NotifyEndOfBitstreamBuffer, client_, - input_buffers_.front()->id)); + while (!input_buffers_.empty()) input_buffers_.pop(); - } state_ = kIdle; - message_loop_->PostTask(FROM_HERE, base::Bind( - &Client::NotifyResetDone, client_)); + if (client_) + client_->NotifyResetDone(); DVLOG(1) << "Reset finished"; } @@ -513,7 +521,7 @@ void VaapiVideoDecodeAccelerator::Destroy() { base::AutoLock auto_lock(lock_); state_ = kDestroying; - client_ptr_factory_.InvalidateWeakPtrs(); + client_ = NULL; { base::AutoUnlock auto_unlock(lock_); diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h index 6624792..30ca7d6 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h @@ -16,14 +16,12 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" #include "base/message_loop.h" #include "base/shared_memory.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "base/threading/non_thread_safe.h" #include "base/threading/thread.h" -#include "content/common/content_export.h" #include "content/common/gpu/media/vaapi_h264_decoder.h" #include "media/base/bitstream_buffer.h" #include "media/video/picture.h" @@ -32,8 +30,7 @@ // Class to provide video decode acceleration for Intel systems with hardware // support for it, and on which libva is available. // Decoding tasks are performed in a separate decoding thread. -class CONTENT_EXPORT VaapiVideoDecodeAccelerator : - public media::VideoDecodeAccelerator { +class VaapiVideoDecodeAccelerator : public media::VideoDecodeAccelerator { public: VaapiVideoDecodeAccelerator( Client* client, @@ -55,10 +52,22 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator : private: virtual ~VaapiVideoDecodeAccelerator(); + void NotifyInitializeDone(); + + // Notify the client that the input buffer has been consumed. + void NotifyInputBufferRead(int input_buffer_id); + // Ensure data has been synced with the output texture and notify // the client it is ready for displaying. void SyncAndNotifyPictureReady(int32 input_id, int32 output_id); + // Posted by the decoder thread to notify VAVDA that the decoder has + // initially parsed the stream and is ready to decode. If the pictures have + // not yet been requested, it will request the client to provide |num_pics| + // textures of given |size| and wait for them, otherwise will post + // a DecodeTask directly. + void ReadyToDecode(int num_pics, const gfx::Size& size); + // Notify the client that an error has occurred and decoding cannot continue. void NotifyError(Error error); @@ -175,9 +184,8 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator : MessageLoop* message_loop_; // To expose client callbacks from VideoDecodeAccelerator. - // NOTE: all calls to these objects *MUST* be executed on message_loop_. - base::WeakPtrFactory<Client> client_ptr_factory_; - base::WeakPtr<Client> client_; + // NOTE: all calls to this object *MUST* be executed on message_loop_. + Client* client_; base::Thread decoder_thread_; content::VaapiH264Decoder decoder_; diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc index 792782f..5b392fb 100644 --- a/content/common/gpu/media/video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc @@ -4,13 +4,12 @@ // // The bulk of this file is support code; sorry about that. Here's an overview // to hopefully help readers of this code: -// - RenderingHelper is charged with interacting with X11/{EGL/GLES2,GLX/GL} or -// Win/EGL. +// - RenderingHelper is charged with interacting with X11, EGL, and GLES2. // - ClientState is an enum for the state of the decode client used by the test. // - ClientStateNotification is a barrier abstraction that allows the test code // to be written sequentially and wait for the decode client to see certain // state transitions. -// - GLRenderingVDAClient is a VideoDecodeAccelerator::Client implementation +// - EglRenderingVDAClient is a VideoDecodeAccelerator::Client implementation // - Finally actual TEST cases are at the bottom of this file, using the above // infrastructure. @@ -43,12 +42,10 @@ #if defined(OS_WIN) #include "content/common/gpu/media/dxva_video_decode_accelerator.h" +#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) +#include "content/common/gpu/media/omx_video_decode_accelerator.h" #elif defined(OS_MACOSX) #include "content/common/gpu/media/mac_video_decode_accelerator.h" -#elif defined(ARCH_CPU_X86_FAMILY) -#include "content/common/gpu/media/vaapi_video_decode_accelerator.h" -#elif defined(ARCH_CPU_ARMEL) -#include "content/common/gpu/media/omx_video_decode_accelerator.h" #else #error The VideoAccelerator tests are not supported on this platform. #endif // defined(OS_WIN) @@ -114,19 +111,19 @@ void ParseTestVideoData(FilePath::StringType data, CHECK(base::StringToInt(elements[7], profile)); } -// State of the GLRenderingVDAClient below. Order matters here as the test +// State of the EglRenderingVDAClient below. Order matters here as the test // makes assumptions about it. enum ClientState { - CS_CREATED = 0, - CS_DECODER_SET = 1, - CS_INITIALIZED = 2, - CS_FLUSHING = 3, - CS_FLUSHED = 4, - CS_DONE = 5, - CS_RESETTING = 6, - CS_RESET = 7, - CS_ERROR = 8, - CS_DESTROYED = 9, + CS_CREATED, + CS_DECODER_SET, + CS_INITIALIZED, + CS_FLUSHING, + CS_FLUSHED, + CS_DONE, + CS_RESETTING, + CS_RESET, + CS_ERROR, + CS_DESTROYED, CS_MAX, // Must be last entry. }; @@ -177,7 +174,7 @@ enum ResetPoint { // Client that can accept callbacks from a VideoDecodeAccelerator and is used by // the TESTs below. -class GLRenderingVDAClient : public VideoDecodeAccelerator::Client { +class EglRenderingVDAClient : public VideoDecodeAccelerator::Client { public: // Doesn't take ownership of |rendering_helper| or |note|, which must outlive // |*this|. @@ -190,7 +187,7 @@ class GLRenderingVDAClient : public VideoDecodeAccelerator::Client { // calls have been made, N>=0 means interpret as ClientState. // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the // last play-through (governed by |num_play_throughs|). - GLRenderingVDAClient(RenderingHelper* rendering_helper, + EglRenderingVDAClient(RenderingHelper* rendering_helper, int rendering_window_id, ClientStateNotification* note, const std::string& encoded_data, @@ -202,7 +199,7 @@ class GLRenderingVDAClient : public VideoDecodeAccelerator::Client { int frame_width, int frame_height, int profile); - virtual ~GLRenderingVDAClient(); + virtual ~EglRenderingVDAClient(); void CreateDecoder(); // VideoDecodeAccelerator::Client implementation. @@ -264,7 +261,7 @@ class GLRenderingVDAClient : public VideoDecodeAccelerator::Client { int profile_; }; -GLRenderingVDAClient::GLRenderingVDAClient( +EglRenderingVDAClient::EglRenderingVDAClient( RenderingHelper* rendering_helper, int rendering_window_id, ClientStateNotification* note, @@ -294,37 +291,29 @@ GLRenderingVDAClient::GLRenderingVDAClient( CHECK_GT(num_play_throughs, 0); } -GLRenderingVDAClient::~GLRenderingVDAClient() { +EglRenderingVDAClient::~EglRenderingVDAClient() { DeleteDecoder(); // Clean up in case of expected error. CHECK(decoder_deleted()); STLDeleteValues(&picture_buffers_by_id_); SetState(CS_DESTROYED); } -static bool DoNothingReturnTrue() { return true; } - -void GLRenderingVDAClient::CreateDecoder() { +void EglRenderingVDAClient::CreateDecoder() { CHECK(decoder_deleted()); #if defined(OS_WIN) scoped_refptr<DXVAVideoDecodeAccelerator> decoder = new DXVAVideoDecodeAccelerator(this); -#elif defined(OS_MACOSX) - scoped_refptr<MacVideoDecodeAccelerator> decoder = - new MacVideoDecodeAccelerator(this); - decoder->SetCGLContext( - static_cast<CGLContextObj>(rendering_helper_->GetGLContext())); -#elif defined(ARCH_CPU_ARMEL) +#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) scoped_refptr<OmxVideoDecodeAccelerator> decoder = new OmxVideoDecodeAccelerator(this); decoder->SetEglState( static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()), static_cast<EGLContext>(rendering_helper_->GetGLContext())); -#elif defined(ARCH_CPU_X86_FAMILY) - scoped_refptr<VaapiVideoDecodeAccelerator> decoder = - new VaapiVideoDecodeAccelerator(this, base::Bind(&DoNothingReturnTrue)); - decoder->SetGlxState( - static_cast<Display*>(rendering_helper_->GetGLDisplay()), - static_cast<GLXContext>(rendering_helper_->GetGLContext())); +#elif defined(OS_MACOSX) + scoped_refptr<MacVideoDecodeAccelerator> decoder = + new MacVideoDecodeAccelerator(this); + decoder->SetCGLContext( + static_cast<CGLContextObj>(rendering_helper_->GetGLContext())); #endif // OS_WIN decoder_ = decoder.release(); SetState(CS_DECODER_SET); @@ -338,7 +327,7 @@ void GLRenderingVDAClient::CreateDecoder() { CHECK(decoder_->Initialize(profile)); } -void GLRenderingVDAClient::ProvidePictureBuffers( +void EglRenderingVDAClient::ProvidePictureBuffers( uint32 requested_num_of_buffers, const gfx::Size& dimensions, uint32 texture_target) { @@ -362,7 +351,7 @@ void GLRenderingVDAClient::ProvidePictureBuffers( decoder_->AssignPictureBuffers(buffers); } -void GLRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { +void EglRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { PictureBufferById::iterator it = picture_buffers_by_id_.find(picture_buffer_id); CHECK(it != picture_buffers_by_id_.end()); @@ -372,7 +361,7 @@ void GLRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { picture_buffers_by_id_.erase(it); } -void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { +void EglRenderingVDAClient::PictureReady(const media::Picture& picture) { // We shouldn't be getting pictures delivered after Reset has completed. CHECK_LT(state_, CS_RESET); @@ -407,26 +396,21 @@ void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { decoder_->ReusePictureBuffer(picture.picture_buffer_id()); } -void GLRenderingVDAClient::NotifyInitializeDone() { +void EglRenderingVDAClient::NotifyInitializeDone() { SetState(CS_INITIALIZED); initialize_done_ticks_ = base::TimeTicks::Now(); for (int i = 0; i < num_in_flight_decodes_; ++i) DecodeNextNALUs(); - DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_); } -void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( +void EglRenderingVDAClient::NotifyEndOfBitstreamBuffer( int32 bitstream_buffer_id) { - // TODO(fischman): this test currently relies on this notification to make - // forward progress during a Reset(). But the VDA::Reset() API doesn't - // guarantee this, so stop relying on it (and remove the notifications from - // VaapiVideoDecodeAccelerator::FinishReset()). ++num_done_bitstream_buffers_; --outstanding_decodes_; DecodeNextNALUs(); } -void GLRenderingVDAClient::NotifyFlushDone() { +void EglRenderingVDAClient::NotifyFlushDone() { if (decoder_deleted()) return; SetState(CS_FLUSHED); @@ -438,13 +422,12 @@ void GLRenderingVDAClient::NotifyFlushDone() { SetState(CS_RESETTING); } -void GLRenderingVDAClient::NotifyResetDone() { +void EglRenderingVDAClient::NotifyResetDone() { if (decoder_deleted()) return; if (reset_after_frame_num_ == MID_STREAM_RESET) { reset_after_frame_num_ = END_OF_STREAM_RESET; - DecodeNextNALUs(); return; } @@ -459,7 +442,7 @@ void GLRenderingVDAClient::NotifyResetDone() { DeleteDecoder(); } -void GLRenderingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) { +void EglRenderingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) { SetState(CS_ERROR); } @@ -469,7 +452,7 @@ static bool LookingAtNAL(const std::string& encoded, size_t pos) { encoded[pos + 2] == 0 && encoded[pos + 3] == 1; } -void GLRenderingVDAClient::SetState(ClientState new_state) { +void EglRenderingVDAClient::SetState(ClientState new_state) { note_->Notify(new_state); state_ = new_state; if (!remaining_play_throughs_ && new_state == delete_decoder_state_) { @@ -478,7 +461,7 @@ void GLRenderingVDAClient::SetState(ClientState new_state) { } } -void GLRenderingVDAClient::DeleteDecoder() { +void EglRenderingVDAClient::DeleteDecoder() { if (decoder_deleted()) return; decoder_->Destroy(); @@ -494,7 +477,7 @@ void GLRenderingVDAClient::DeleteDecoder() { SetState(static_cast<ClientState>(i)); } -void GLRenderingVDAClient::GetRangeForNextNALUs( +void EglRenderingVDAClient::GetRangeForNextNALUs( size_t start_pos, size_t* end_pos) { *end_pos = start_pos; CHECK(LookingAtNAL(encoded_data_, start_pos)); @@ -511,7 +494,7 @@ void GLRenderingVDAClient::GetRangeForNextNALUs( } } -void GLRenderingVDAClient::DecodeNextNALUs() { +void EglRenderingVDAClient::DecodeNextNALUs() { if (decoder_deleted()) return; if (encoded_data_next_pos_to_decode_ == encoded_data_.size()) { @@ -545,7 +528,7 @@ void GLRenderingVDAClient::DecodeNextNALUs() { } } -double GLRenderingVDAClient::frames_per_second() { +double EglRenderingVDAClient::frames_per_second() { base::TimeDelta delta = last_frame_delivered_ticks_ - initialize_done_ticks_; if (delta.InSecondsF() == 0) return 0; @@ -557,26 +540,17 @@ double GLRenderingVDAClient::frames_per_second() { // - Number of concurrent decoders. // - Number of concurrent in-flight Decode() calls per decoder. // - Number of play-throughs. -// - reset_after_frame_num: see GLRenderingVDAClient ctor. -// - delete_decoder_phase: see GLRenderingVDAClient ctor. +// - reset_after_frame_num: see EglRenderingVDAClient ctor. +// - delete_decoder_phase: see EglRenderingVDAClient ctor. class VideoDecodeAcceleratorTest : public ::testing::TestWithParam< Tuple6<int, int, int, int, ResetPoint, ClientState> > { }; -// Helper so that gtest failures emit a more readable version of the tuple than -// its byte representation. -::std::ostream& operator<<( - ::std::ostream& os, - const Tuple6<int, int, int, int, ResetPoint, ClientState>& t) { - return os << t.a << ", " << t.b << ", " << t.c << ", " << t.d << ", " << t.e - << ", " << t.f; -} - // Wait for |note| to report a state and if it's not |expected_state| then // assert |client| has deleted its decoder. static void AssertWaitForStateOrDeleted(ClientStateNotification* note, - GLRenderingVDAClient* client, + EglRenderingVDAClient* client, ClientState expected_state) { ClientState state = note->Wait(); if (state == expected_state) return; @@ -620,20 +594,20 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { if (num_frames > 0 && reset_after_frame_num >= 0) num_frames += reset_after_frame_num; - // Suppress GL swapping in all but a few tests, to cut down overall test - // runtime. + // Suppress EGL surface swapping in all but a few tests, to cut down overall + // test runtime. const bool suppress_swap_to_display = num_NALUs_per_decode > 1; std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL); - std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); + std::vector<EglRenderingVDAClient*> clients(num_concurrent_decoders, NULL); // Read in the video data. std::string data_str; CHECK(file_util::ReadFileToString(FilePath(test_video_file), &data_str)) - << "test_video_file: " << FilePath(test_video_file).MaybeAsASCII(); + << "test_video_file: " << test_video_file; // Initialize the rendering helper. - base::Thread rendering_thread("GLRenderingVDAClientThread"); + base::Thread rendering_thread("EglRenderingVDAClientThread"); base::Thread::Options options; options.message_loop_type = MessageLoop::TYPE_DEFAULT; #if defined(OS_WIN) @@ -658,7 +632,7 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { for (size_t index = 0; index < num_concurrent_decoders; ++index) { ClientStateNotification* note = new ClientStateNotification(); notes[index] = note; - GLRenderingVDAClient* client = new GLRenderingVDAClient( + EglRenderingVDAClient* client = new EglRenderingVDAClient( rendering_helper.get(), index, note, data_str, num_NALUs_per_decode, num_in_flight_decodes, num_play_throughs, reset_after_frame_num, delete_decoder_state, frame_width, frame_height, profile); @@ -666,7 +640,7 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { rendering_thread.message_loop()->PostTask( FROM_HERE, - base::Bind(&GLRenderingVDAClient::CreateDecoder, + base::Bind(&EglRenderingVDAClient::CreateDecoder, base::Unretained(client))); ASSERT_EQ(note->Wait(), CS_DECODER_SET); @@ -717,7 +691,7 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { // allowed to finish. if (delete_decoder_state < CS_FLUSHED) continue; - GLRenderingVDAClient* client = clients[i]; + EglRenderingVDAClient* client = clients[i]; if (num_frames > 0) EXPECT_EQ(client->num_decoded_frames(), num_frames); if (num_NALUs > 0 && reset_after_frame_num < 0) { @@ -732,7 +706,7 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { rendering_thread.message_loop()->PostTask( FROM_HERE, - base::Bind(&STLDeleteElements<std::vector<GLRenderingVDAClient*> >, + base::Bind(&STLDeleteElements<std::vector<EglRenderingVDAClient*> >, &clients)); rendering_thread.message_loop()->PostTask( FROM_HERE, @@ -823,14 +797,6 @@ int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args. CommandLine::Init(argc, argv); - // Needed to enable DVLOG through --vmodule. - CHECK(logging::InitLogging( - NULL, - logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, - logging::DONT_LOCK_LOG_FILE, - logging::APPEND_TO_OLD_LOG_FILE, - logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS)); - CommandLine* cmd_line = CommandLine::ForCurrentProcess(); DCHECK(cmd_line); @@ -841,8 +807,6 @@ int main(int argc, char **argv) { test_video_data = it->second.c_str(); continue; } - if (it->first == "v" || it->first == "vmodule") - continue; LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; } diff --git a/content/content_common.gypi b/content/content_common.gypi index cb1860f..d7412c7 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -424,7 +424,7 @@ ], }, }], - ['target_arch != "arm" and (OS=="linux" or chromeos == 1)', { + ['chromeos == 1', { 'sources': [ 'common/gpu/media/h264_dpb.cc', 'common/gpu/media/h264_dpb.h', diff --git a/content/content_tests.gypi b/content/content_tests.gypi index b4cdba7..fd5d201 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -579,61 +579,62 @@ }, ], 'conditions': [ - ['chromeos==1 or OS=="linux" or OS=="win" or OS=="mac"', { + ['target_arch=="arm" or OS=="win" or OS=="mac"', { 'targets': [ - { - 'target_name': 'video_decode_accelerator_unittest', - 'type': 'executable', - 'dependencies': [ - 'content', - '../base/base.gyp:base', - '../testing/gtest.gyp:gtest', - '../media/media.gyp:media', - '../ui/gl/gl.gyp:gl', - '../ui/ui.gyp:ui', - ], - 'include_dirs': [ - '<(DEPTH)/third_party/angle/include', - ], - 'sources': [ - 'common/gpu/media/rendering_helper.h', - 'common/gpu/media/rendering_helper_mac.mm', - 'common/gpu/media/rendering_helper_gl.cc', - 'common/gpu/media/video_decode_accelerator_unittest.cc', - ], - 'conditions': [ - ['target_arch=="arm"', { - # TODO(fischman): remove this name override when autotest config - # is ready. - 'target_name': 'omx_video_decode_accelerator_unittest', - 'include_dirs': [ - '<(DEPTH)/third_party/openmax/il', - ], - }], - ['OS=="mac"', { - 'sources!': [ - 'common/gpu/media/rendering_helper_gl.cc', - ], - }], - ['OS=="win"', { - 'dependencies': [ - '../third_party/angle/src/build_angle.gyp:libEGL', - '../third_party/angle/src/build_angle.gyp:libGLESv2', - ], - }], - ['win_use_allocator_shim==1', { - 'dependencies': [ - '../base/allocator/allocator.gyp:allocator', - ], - }], - ['target_arch != "arm" and (OS=="linux" or chromeos == 1)', { - 'include_dirs': [ - '<(DEPTH)/third_party/libva', - ], - }], - ], - }, - ] + { + 'conditions': [ + ['target_arch=="arm"', { + 'target_name': 'omx_video_decode_accelerator_unittest', + 'include_dirs': [ + '<(DEPTH)/third_party/openmax/il', + ], + }], + ['OS=="mac"', { + 'target_name': 'video_decode_accelerator_unittest', + 'dependencies': [ + '../ui/gl/gl.gyp:gl', + '../ui/ui.gyp:ui', + ], + 'sources!': [ + 'common/gpu/media/rendering_helper_egl.cc', + ], + }], + ['OS=="win"', { + 'target_name': 'dxva_video_decode_accelerator_unittest', + 'dependencies': [ + '../third_party/angle/src/build_angle.gyp:libEGL', + '../third_party/angle/src/build_angle.gyp:libGLESv2', + '../ui/gl/gl.gyp:gl', + ], + 'conditions': [ + ['win_use_allocator_shim==1', { + 'dependencies': [ + '../base/allocator/allocator.gyp:allocator', + ], + }], + ], + }], + ], + 'defines!': ['CONTENT_IMPLEMENTATION'], + 'type': 'executable', + 'dependencies': [ + '../base/base.gyp:base', + 'content', + '../testing/gtest.gyp:gtest', + '../media/media.gyp:media', + '../ui/ui.gyp:ui', + ], + 'include_dirs': [ + '<(DEPTH)/third_party/angle/include', + ], + 'sources': [ + 'common/gpu/media/rendering_helper.h', + 'common/gpu/media/rendering_helper_mac.mm', + 'common/gpu/media/rendering_helper_egl.cc', + 'common/gpu/media/video_decode_accelerator_unittest.cc', + ], + } + ], }], ['chromeos == 1', { 'targets': [ |