Add vaapi_h264_decoder_unittest program.

    
    The program reads an H.264 bitstream file and writes a file containing
    the decoded frames in I420 format. Alternatively it verifies MD5 sum
    of the decoded frames. It can be used for development verification and
    regression testing.
    
    BUG=none
    TEST=run through H.264.1 Base/Ext/Main profile test streams on link.

Review URL: https://codereview.chromium.org/27498002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250987 0039d316-1c4b-4281-b951-d872f2087c98
parent 3c1a5ac0
...@@ -78,7 +78,7 @@ namespace content { ...@@ -78,7 +78,7 @@ namespace content {
// v // v
// VaapiWrapper frees VASurfaceID. // VaapiWrapper frees VASurfaceID.
// //
class VASurface : public base::RefCountedThreadSafe<VASurface> { class CONTENT_EXPORT VASurface : public base::RefCountedThreadSafe<VASurface> {
public: public:
// Provided by user, will be called when all references to the surface // Provided by user, will be called when all references to the surface
// are released. // are released.
......
...@@ -1521,7 +1521,9 @@ bool VaapiH264Decoder::ProcessSlice(media::H264SliceHeader* slice_hdr) { ...@@ -1521,7 +1521,9 @@ bool VaapiH264Decoder::ProcessSlice(media::H264SliceHeader* slice_hdr) {
return VaapiH264Decoder::kDecodeError; \ return VaapiH264Decoder::kDecodeError; \
} while (0) } while (0)
void VaapiH264Decoder::SetStream(uint8* ptr, size_t size, int32 input_id) { void VaapiH264Decoder::SetStream(const uint8* ptr,
size_t size,
int32 input_id) {
DCHECK(ptr); DCHECK(ptr);
DCHECK(size); DCHECK(size);
......
...@@ -34,7 +34,7 @@ namespace content { ...@@ -34,7 +34,7 @@ namespace content {
// //
// This class must be created, called and destroyed on a single thread, and // This class must be created, called and destroyed on a single thread, and
// does nothing internally on any other thread. // does nothing internally on any other thread.
class VaapiH264Decoder { class CONTENT_EXPORT VaapiH264Decoder {
public: public:
// Callback invoked on the client when a surface is to be displayed. // Callback invoked on the client when a surface is to be displayed.
// Arguments: input buffer id provided at the time of Decode() // Arguments: input buffer id provided at the time of Decode()
...@@ -91,7 +91,7 @@ class VaapiH264Decoder { ...@@ -91,7 +91,7 @@ class VaapiH264Decoder {
// Set current stream data pointer to |ptr| and |size|. Output surfaces // Set current stream data pointer to |ptr| and |size|. Output surfaces
// that are decoded from data in this stream chunk are to be returned along // that are decoded from data in this stream chunk are to be returned along
// with the given |input_id|. // with the given |input_id|.
void SetStream(uint8* ptr, size_t size, int32 input_id); void SetStream(const uint8* ptr, size_t size, int32 input_id);
// Try to decode more of the stream, returning decoded frames asynchronously // Try to decode more of the stream, returning decoded frames asynchronously
// via output_pic_cb_. Return when more stream is needed, when we run out // via output_pic_cb_. Return when more stream is needed, when we run out
......
This diff is collapsed.
...@@ -76,9 +76,13 @@ typedef VAStatus (*VaapiCreateSurfaces8)(VADisplay dpy, ...@@ -76,9 +76,13 @@ typedef VAStatus (*VaapiCreateSurfaces8)(VADisplay dpy,
unsigned int num_surfaces, unsigned int num_surfaces,
VASurfaceAttrib *attrib_list, VASurfaceAttrib *attrib_list,
unsigned int num_attribs); unsigned int num_attribs);
typedef VAStatus (*VaapiDeriveImage)(VADisplay dpy,
VASurfaceID surface,
VAImage* image);
typedef VAStatus (*VaapiDestroyBuffer)(VADisplay dpy, VABufferID buffer_id); typedef VAStatus (*VaapiDestroyBuffer)(VADisplay dpy, VABufferID buffer_id);
typedef VAStatus (*VaapiDestroyConfig)(VADisplay dpy, VAConfigID config_id); typedef VAStatus (*VaapiDestroyConfig)(VADisplay dpy, VAConfigID config_id);
typedef VAStatus (*VaapiDestroyContext)(VADisplay dpy, VAContextID context); typedef VAStatus (*VaapiDestroyContext)(VADisplay dpy, VAContextID context);
typedef VAStatus (*VaapiDestroyImage)(VADisplay dpy, VAImageID image);
typedef VAStatus (*VaapiDestroySurfaces)(VADisplay dpy, typedef VAStatus (*VaapiDestroySurfaces)(VADisplay dpy,
VASurfaceID *surfaces, VASurfaceID *surfaces,
int num_surfaces); int num_surfaces);
...@@ -94,6 +98,9 @@ typedef VADisplay (*VaapiGetDisplay)(Display *dpy); ...@@ -94,6 +98,9 @@ typedef VADisplay (*VaapiGetDisplay)(Display *dpy);
typedef VAStatus (*VaapiInitialize)(VADisplay dpy, typedef VAStatus (*VaapiInitialize)(VADisplay dpy,
int *major_version, int *major_version,
int *minor_version); int *minor_version);
typedef VAStatus (*VaapiMapBuffer)(VADisplay dpy,
VABufferID buf_id,
void** pbuf);
typedef VAStatus (*VaapiPutSurface)(VADisplay dpy, typedef VAStatus (*VaapiPutSurface)(VADisplay dpy,
VASurfaceID surface, VASurfaceID surface,
Drawable draw, Drawable draw,
...@@ -117,6 +124,7 @@ typedef VAStatus (*VaapiSetDisplayAttributes)(VADisplay dpy, ...@@ -117,6 +124,7 @@ typedef VAStatus (*VaapiSetDisplayAttributes)(VADisplay dpy,
int num_attributes); int num_attributes);
typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target); typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target);
typedef VAStatus (*VaapiTerminate)(VADisplay dpy); typedef VAStatus (*VaapiTerminate)(VADisplay dpy);
typedef VAStatus (*VaapiUnmapBuffer)(VADisplay dpy, VABufferID buf_id);
#define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL #define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL
...@@ -125,9 +133,11 @@ VAAPI_SYM(CreateBuffer, vaapi_handle); ...@@ -125,9 +133,11 @@ VAAPI_SYM(CreateBuffer, vaapi_handle);
VAAPI_SYM(CreateConfig, vaapi_handle); VAAPI_SYM(CreateConfig, vaapi_handle);
VAAPI_SYM(CreateContext, vaapi_handle); VAAPI_SYM(CreateContext, vaapi_handle);
VAAPI_SYM(CreateSurfaces, vaapi_handle); VAAPI_SYM(CreateSurfaces, vaapi_handle);
VAAPI_SYM(DeriveImage, vaapi_handle);
VAAPI_SYM(DestroyBuffer, vaapi_handle); VAAPI_SYM(DestroyBuffer, vaapi_handle);
VAAPI_SYM(DestroyConfig, vaapi_handle); VAAPI_SYM(DestroyConfig, vaapi_handle);
VAAPI_SYM(DestroyContext, vaapi_handle); VAAPI_SYM(DestroyContext, vaapi_handle);
VAAPI_SYM(DestroyImage, vaapi_handle);
VAAPI_SYM(DestroySurfaces, vaapi_handle); VAAPI_SYM(DestroySurfaces, vaapi_handle);
VAAPI_SYM(DisplayIsValid, vaapi_handle); VAAPI_SYM(DisplayIsValid, vaapi_handle);
VAAPI_SYM(EndPicture, vaapi_handle); VAAPI_SYM(EndPicture, vaapi_handle);
...@@ -135,11 +145,13 @@ VAAPI_SYM(ErrorStr, vaapi_handle); ...@@ -135,11 +145,13 @@ VAAPI_SYM(ErrorStr, vaapi_handle);
VAAPI_SYM(GetConfigAttributes, vaapi_handle); VAAPI_SYM(GetConfigAttributes, vaapi_handle);
VAAPI_SYM(GetDisplay, vaapi_x11_handle); VAAPI_SYM(GetDisplay, vaapi_x11_handle);
VAAPI_SYM(Initialize, vaapi_handle); VAAPI_SYM(Initialize, vaapi_handle);
VAAPI_SYM(MapBuffer, vaapi_handle);
VAAPI_SYM(PutSurface, vaapi_x11_handle); VAAPI_SYM(PutSurface, vaapi_x11_handle);
VAAPI_SYM(RenderPicture, vaapi_handle); VAAPI_SYM(RenderPicture, vaapi_handle);
VAAPI_SYM(SetDisplayAttributes, vaapi_handle); VAAPI_SYM(SetDisplayAttributes, vaapi_handle);
VAAPI_SYM(SyncSurface, vaapi_x11_handle); VAAPI_SYM(SyncSurface, vaapi_x11_handle);
VAAPI_SYM(Terminate, vaapi_handle); VAAPI_SYM(Terminate, vaapi_handle);
VAAPI_SYM(UnmapBuffer, vaapi_handle);
#undef VAAPI_SYM #undef VAAPI_SYM
...@@ -451,6 +463,37 @@ bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, ...@@ -451,6 +463,37 @@ bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
return true; return true;
} }
bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id,
VAImage* image,
void** mem) {
base::AutoLock auto_lock(va_lock_);
VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id);
VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
// Derive a VAImage from the VASurface
va_res = VAAPI_DeriveImage(va_display_, va_surface_id, image);
VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed");
if (va_res != VA_STATUS_SUCCESS)
return false;
// Map the VAImage into memory
va_res = VAAPI_MapBuffer(va_display_, image->buf, mem);
VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
if (va_res == VA_STATUS_SUCCESS)
return true;
VAAPI_DestroyImage(va_display_, image->image_id);
return false;
}
void VaapiWrapper::ReturnVaImageForTesting(VAImage* image) {
base::AutoLock auto_lock(va_lock_);
VAAPI_UnmapBuffer(va_display_, image->buf);
VAAPI_DestroyImage(va_display_, image->image_id);
}
// static // static
bool VaapiWrapper::PostSandboxInitialization() { bool VaapiWrapper::PostSandboxInitialization() {
vaapi_handle = dlopen("libva.so.1", RTLD_NOW); vaapi_handle = dlopen("libva.so.1", RTLD_NOW);
...@@ -472,9 +515,11 @@ bool VaapiWrapper::PostSandboxInitialization() { ...@@ -472,9 +515,11 @@ bool VaapiWrapper::PostSandboxInitialization() {
VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateConfig, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateConfig, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateContext, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateContext, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateSurfaces, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateSurfaces, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(DeriveImage, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyBuffer, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyBuffer, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyConfig, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyConfig, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyContext, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyContext, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyImage, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroySurfaces, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroySurfaces, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle);
...@@ -482,11 +527,13 @@ bool VaapiWrapper::PostSandboxInitialization() { ...@@ -482,11 +527,13 @@ bool VaapiWrapper::PostSandboxInitialization() {
VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(MapBuffer, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(SetDisplayAttributes, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(SetDisplayAttributes, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle);
VAAPI_DLSYM_OR_RETURN_ON_ERROR(UnmapBuffer, vaapi_handle);
#undef VAAPI_DLSYM #undef VAAPI_DLSYM
return true; return true;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/common/gpu/media/va_surface.h" #include "content/common/gpu/media/va_surface.h"
#include "media/base/video_decoder_config.h" #include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
#include "third_party/libva/va/va.h" #include "third_party/libva/va/va.h"
#include "third_party/libva/va/va_x11.h" #include "third_party/libva/va/va_x11.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
...@@ -81,6 +82,17 @@ class CONTENT_EXPORT VaapiWrapper { ...@@ -81,6 +82,17 @@ class CONTENT_EXPORT VaapiWrapper {
// Returns true if the VAAPI version is less than the specified version. // Returns true if the VAAPI version is less than the specified version.
bool VAAPIVersionLessThan(int major, int minor); bool VAAPIVersionLessThan(int major, int minor);
// Get a VAImage from a VASurface and map it into memory. The VAImage should
// be released using the ReturnVaImage function. Returns true when successful.
// This is intended for testing only.
bool GetVaImageForTesting(VASurfaceID va_surface_id,
VAImage* image,
void** mem);
// Release the VAImage (and the associated memory mapping) obtained from
// GetVaImage(). This is intended for testing only.
void ReturnVaImageForTesting(VAImage* image);
private: private:
VaapiWrapper(); VaapiWrapper();
......
...@@ -1322,6 +1322,33 @@ ...@@ -1322,6 +1322,33 @@
}, },
] ]
}], }],
['chromeos==1 and use_x11 == 1 and target_arch != "arm"', {
'targets': [
{
'target_name': 'vaapi_h264_decoder_unittest',
'type': '<(gtest_target_type)',
'dependencies': [
'content.gyp:content_common',
'../base/base.gyp:base',
'../media/media.gyp:media',
'../testing/gtest.gyp:gtest',
'../third_party/libyuv/libyuv.gyp:libyuv',
'../ui/gfx/gfx.gyp:gfx_geometry',
],
'sources': [
'common/gpu/media/vaapi_h264_decoder_unittest.cc',
],
'include_dirs': [
'<(DEPTH)/third_party/libva',
],
'link_settings': {
'libraries': [
'-lX11',
],
},
},
]
}],
['chromeos==1 and target_arch == "arm"', { ['chromeos==1 and target_arch == "arm"', {
'targets': [ 'targets': [
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment