summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-05 21:31:34 +0000
committerfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-05 21:31:34 +0000
commitc9ed565be014f6dc53c977ec0a4205296e573ba2 (patch)
tree47441e0120535adfad311359c55b78c97a54412b /content
parentfe390ab7e359396a0c57de2839a38d18dc9199a0 (diff)
downloadchromium_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.cc45
-rw-r--r--content/common/gpu/media/vaapi_video_decode_accelerator.cc106
-rw-r--r--content/common/gpu/media/vaapi_video_decode_accelerator.h22
-rw-r--r--content/common/gpu/media/video_decode_accelerator_unittest.cc140
-rw-r--r--content/content_common.gypi2
-rw-r--r--content/content_tests.gypi109
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': [