From ef932ed16a50a6fa0adb801c32f3d4860e880bc9 Mon Sep 17 00:00:00 2001 From: "scherkus@chromium.org" Date: Thu, 14 Apr 2011 22:53:39 +0000 Subject: Draft version of the HW video decode tester and few other changes. Intention is that this tester can be used to decouple HW decode accelerator integration from running the whole Chrome browser. Features: - Independent GUnit executable, which should be possible to use in autotests. - Mimics Renderer process from Gpu video pipeline perspective. * Test bench contains implementation of FakeClient which essentially mimics Renderer process from the GpuVideoDecodeAccelerator's point of view. * FakeClient runs on it's own thread and will communicate with using the IPC messages that are used also within the real use case. * FakeClient will allocate memories using same SharedMemory stuff as the real Renderer code. * Currently reads H.264 Annex B bitstream from file and parses it to NAL units before feeding to the decoder * TODO: Polish and improving the features and configurability. * TODO: GLES texture allocation for textures. - Allows building various test cases and error behaviour as well both on AcceleratedVideoDecoder interface as well as erroneous behaviour from the client. - Allows also checking expected order of calls if we want to enforce certain behaviour across various implementations. Patch by vmr@chromium.org: http://codereview.chromium.org/6720040/ BUG=none TEST=none git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81663 0039d316-1c4b-4281-b951-d872f2087c98 --- media/media.gyp | 1 + media/video/picture.cc | 72 ++++++++++ media/video/picture.h | 65 +++++++++ media/video/video_decode_accelerator.cc | 15 ++ media/video/video_decode_accelerator.h | 237 +++++++++++++++++++++++++++++++- 5 files changed, 386 insertions(+), 4 deletions(-) create mode 100644 media/video/picture.cc create mode 100644 media/video/picture.h create mode 100644 media/video/video_decode_accelerator.cc (limited to 'media') diff --git a/media/media.gyp b/media/media.gyp index 23e1956..60cffe2 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -172,6 +172,7 @@ 'video/ffmpeg_video_allocator.h', 'video/ffmpeg_video_decode_engine.cc', 'video/ffmpeg_video_decode_engine.h', + 'video/video_decode_accelerator.cc', 'video/video_decode_accelerator.h', 'video/video_decode_engine.cc', 'video/video_decode_engine.h', diff --git a/media/video/picture.cc b/media/video/picture.cc new file mode 100644 index 0000000..dd57e4a --- /dev/null +++ b/media/video/picture.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/video/picture.h" + +namespace media { + +// PictureBuffer implementation. +PictureBuffer::PictureBuffer(int32 id, + gfx::Size pixel_size, + std::vector color_format, + MemoryType memory_type, + std::vector data_plane_handles) + : id_(id), + pixel_size_(pixel_size), + color_format_(color_format), + memory_type_(memory_type), + data_plane_handles_(data_plane_handles) { +} + +PictureBuffer::~PictureBuffer() {} + +int32 PictureBuffer::GetId() { + return id_; +} + +gfx::Size PictureBuffer::GetSize() { + return pixel_size_; +} + +const std::vector& PictureBuffer::GetColorFormat() { + return color_format_; +} + +PictureBuffer::MemoryType PictureBuffer::GetMemoryType() { + return memory_type_; +} + +std::vector& PictureBuffer::GetPlaneHandles() { + return data_plane_handles_; +} + +// Picture implementation. +Picture::Picture(PictureBuffer* picture_buffer, gfx::Size decoded_pixel_size, + gfx::Size visible_pixel_size, void* user_handle) + : picture_buffer_(picture_buffer), + decoded_pixel_size_(decoded_pixel_size), + visible_pixel_size_(visible_pixel_size), + user_handle_(user_handle) { +} + +Picture::~Picture() {} + +PictureBuffer* Picture::picture_buffer() { + return picture_buffer_; +} + +gfx::Size Picture::GetDecodedSize() const { + return decoded_pixel_size_; +} + +gfx::Size Picture::GetVisibleSize() const { + return visible_pixel_size_; +} + +void* Picture::GetUserHandle() { + return user_handle_; +} + +} // namespace media + diff --git a/media/video/picture.h b/media/video/picture.h new file mode 100644 index 0000000..ec84453 --- /dev/null +++ b/media/video/picture.h @@ -0,0 +1,65 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_VIDEO_PICTURE_H_ +#define MEDIA_VIDEO_PICTURE_H_ + +#include + +#include "base/compiler_specific.h" +#include "media/video/video_decode_accelerator.h" + +namespace media { + +// TODO(vmr): Evaluate the generalization potential of these interfaces & +// classes and refactor as needed with the rest of media stack. +class PictureBuffer : public VideoDecodeAccelerator::PictureBuffer { + public: + PictureBuffer(int32 id, gfx::Size pixel_size, + std::vector color_format, MemoryType memory_type, + std::vector data_plane_handles); + virtual ~PictureBuffer(); + + // VideoDecodeAccelerator::PictureBuffer implementation. + virtual int32 GetId() OVERRIDE; + virtual gfx::Size GetSize() OVERRIDE; + virtual const std::vector& GetColorFormat() OVERRIDE; + virtual MemoryType GetMemoryType() OVERRIDE; + virtual std::vector& GetPlaneHandles() OVERRIDE; + + private: + int32 id_; + gfx::Size pixel_size_; + std::vector color_format_; + MemoryType memory_type_; + std::vector& data_plane_handles_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(PictureBuffer); +}; + +class Picture : public VideoDecodeAccelerator::Picture { + public: + Picture(PictureBuffer* picture_buffer, gfx::Size decoded_pixel_size, + gfx::Size visible_pixel_size, void* user_handle); + virtual ~Picture(); + + // VideoDecodeAccelerator::Picture implementation. + virtual PictureBuffer* picture_buffer() OVERRIDE; + virtual gfx::Size GetDecodedSize() const OVERRIDE; + virtual gfx::Size GetVisibleSize() const OVERRIDE; + virtual void* GetUserHandle() OVERRIDE; + + private: + // Pointer to the picture buffer which contains this picture. + PictureBuffer* picture_buffer_; + gfx::Size decoded_pixel_size_; + gfx::Size visible_pixel_size_; + void* user_handle_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(Picture); +}; + +} // namespace media + +#endif // MEDIA_VIDEO_PICTURE_H_ diff --git a/media/video/video_decode_accelerator.cc b/media/video/video_decode_accelerator.cc new file mode 100644 index 0000000..c88d48a --- /dev/null +++ b/media/video/video_decode_accelerator.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/video/video_decode_accelerator.h" + +namespace media { + +VideoDecodeAccelerator::~VideoDecodeAccelerator() {} + +VideoDecodeAccelerator::PictureBuffer::~PictureBuffer() {} + +VideoDecodeAccelerator::Picture::~Picture() {} + +} diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index 0c4405f..be799c11 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h @@ -16,34 +16,260 @@ namespace media { typedef Callback0::Type VideoDecodeAcceleratorCallback; +// Enumeration defining global dictionary ranges for various purposes that are +// used to handle the configurations of the video decoder. +enum VideoAttributeKey { + VIDEOATTRIBUTEKEY_TERMINATOR = 0, + + VIDEOATTRIBUTEKEY_BITSTREAM_FORMAT_BASE = 0x100, + // Array of key/value pairs describing video configuration. + // It could include any keys from PP_VideoKey. Its last element shall be + // VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_NONE with no corresponding value. + // An example: + // { + // VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_FOURCC, PP_VIDEODECODECID_VP8, + // VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_VP8_PROFILE, (VP8PROFILE_1 | + // VP8PROFILE_2 | + // VP8PROFILE_3), + // VIDEOATTRIBUTEKEY_TERMINATOR + // }; + // Keys for defining video bitstream format. + // Value is type of PP_VideoCodecFourcc. Commonly known attributes values are + // defined in PP_VideoCodecFourcc enumeration. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_FOURCC, + // Bitrate in bits/s. Attribute value is 32-bit unsigned integer. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_BITRATE, + // Width and height of the input video bitstream, if known by the application. + // Decoder will expect the bitstream to match these values and does memory + // considerations accordingly. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_WIDTH, + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_HEIGHT, + // Following attributes are applicable only in case of VP8. + // Key for VP8 profile attribute. Attribute value is bitmask of flags defined + // in PP_VP8Profile_Dev enumeration. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_VP8_PROFILE, + // Number of partitions per picture. Attribute value is unsigned 32-bit + // integer. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_VP8_NUM_OF_PARTITIONS, + // Following attributes are applicable only in case of H.264. + // Value is bitmask collection from the flags defined in PP_H264Profile. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_PROFILE, + // Value is type of PP_H264Level. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_LEVEL, + // Value is type of PP_H264PayloadFormat_Dev. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_PAYLOADFORMAT, + // Subset for H.264 features, attribute value 0 signifies unsupported. + // This is needed in case decoder has partial support for certain profile. + // Default for features are enabled if they're part of supported profile. + // H264 tool called Flexible Macroblock Ordering. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_FEATURE_FMO, + // H264 tool called Arbitrary Slice Ordering. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_FEATURE_ASO, + // H264 tool called Interlacing. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_FEATURE_INTERLACE, + // H264 tool called Context-Adaptive Binary Arithmetic Coding. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_FEATURE_CABAC, + // H264 tool called Weighted Prediction. + VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_FEATURE_WEIGHTEDPREDICTION, + + VIDEOATTRIBUTEKEY_COLORFORMAT_BASE = 0x1000, + // Keys for definining attributes of a color buffer. Using these attributes + // users can define color spaces in terms of red, green, blue and alpha + // components as well as with combination of luma and chroma values with + // different subsampling schemes. Also planar, semiplanar and interleaved + // formats can be described by using the provided keys as instructed. + // + // Rules for describing the color planes (1 or more) that constitute the whole + // picture are: + // 1. Each plane starts with VIDEOATTRIBUTEKEY_COLORFORMAT_PLANE_PIXEL_SIZE + // attribute telling how many bits per pixel the plane contains. + // 2. VIDEOATTRIBUTEKEY_COLORFORMAT_PLANE_PIXEL_SIZE attribute must be + // followed either by + // a. Red, green and blue components followed optionally by alpha size + // attribute. + // OR + // b. Luma, blue difference chroma and red difference chroma components as + // well as three sampling reference factors that tell how the chroma may + // have been subsampled with respect to luma. + // 3. Description must be terminated with VIDEOATTRIBUTEKEY_COLORFORMAT_NONE + // key with no value for attribute. + // + // For example, semiplanar YCbCr 4:2:2 (2 planes, one containing 8-bit luma, + // the other containing two interleaved chroma data components) may be + // described with the following attributes: + // { + // VIDEOATTRIBUTEKEY_COLORFORMAT_PLANE_PIXEL_SIZE, 8, + // VIDEOATTRIBUTEKEY_COLORFORMAT_LUMA_SIZE, 8, + // VIDEOATTRIBUTEKEY_COLORFORMAT_PLANE_PIXEL_SIZE, 16, + // VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMA_BLUE_SIZE, 8, + // VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMA_RED_SIZE, 8, + // VIDEOATTRIBUTEKEY_COLORFORMAT_HORIZONTAL_SAMPLING_FACTOR_REFERENCE, 4, + // VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMA_HORIZONTAL_SUBSAMPLING_FACTOR, 2, + // VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMA_VERTICAL_SUBSAMPLING_FACTOR, 2 + // VIDEOATTRIBUTEKEY_TERMINATOR + // } + // + // Another example, commonly known 16-bit RGB 565 color format may be + // specified as follows: + // { + // VIDEOATTRIBUTEKEY_COLORFORMAT_PLANE_PIXEL_SIZE, 16, + // VIDEOATTRIBUTEKEY_COLORFORMAT_RED_SIZE, 5, + // VIDEOATTRIBUTEKEY_COLORFORMAT_GREEN_SIZE, 6, + // VIDEOATTRIBUTEKEY_COLORFORMAT_BLUE_SIZE, 5, + // VIDEOATTRIBUTEKEY_TERMINATOR + // } + // Total color component bits per pixel in the picture buffer. + VIDEOATTRIBUTEKEY_COLORFORMAT_PLANE_PIXEL_SIZE, + // Bits of red per pixel in picture buffer. + VIDEOATTRIBUTEKEY_COLORFORMAT_RED_SIZE, + // Bits of green per pixel in picture buffer. + VIDEOATTRIBUTEKEY_COLORFORMAT_GREEN_SIZE, + // Bits of blue per pixel in picture buffer. + VIDEOATTRIBUTEKEY_COLORFORMAT_BLUE_SIZE, + // Bits of alpha in color buffer. + VIDEOATTRIBUTEKEY_COLORFORMAT_ALPHA_SIZE, + // Bits of luma per pixel in color buffer. + VIDEOATTRIBUTEKEY_COLORFORMAT_LUMA_SIZE, + // Bits of blue difference chroma (Cb) data in color buffer. + VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMA_BLUE_SIZE, + // Bits of blue difference chroma (Cr) data in color buffer. + VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMA_RED_SIZE, + // Three keys to describe the subsampling of YCbCr sampled digital video + // signal. For example, 4:2:2 sampling could be defined by setting: + // VIDEOATTRIBUTEKEY_COLORFORMAT_HORIZONTAL_SAMPLING_FACTOR_REFERENCE = 4 + // VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMINANCE_HORIZONTAL_SUBSAMPLING_FACTOR = 2 + // VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMINANCE_VERTICAL_SUBSAMPLING_FACTOR = 2 + VIDEOATTRIBUTEKEY_COLORFORMAT_HORIZONTAL_SAMPLING_FACTOR_REFERENCE, + VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMA_HORIZONTAL_SUBSAMPLING_FACTOR, + VIDEOATTRIBUTEKEY_COLORFORMAT_CHROMA_VERTICAL_SUBSAMPLING_FACTOR, + // Base for telling implementation specific information about the optimal + // number of picture buffers to be provided to the implementation. + VIDEOATTRIBUTEKEY_PICTUREBUFFER_REQUIREMENTS_BASE = 0x10000, + // Following two keys are used to signal how many buffers are needed by the + // implementation as a function of the maximum number of reference frames set + // by the stream. Number of required buffers is + // MAX_REF_FRAMES * REFERENCE_PIC_MULTIPLIER + ADDITIONAL_BUFFERS + VIDEOATTRIBUTEKEY_PICTUREBUFFER_REQUIREMENTS_ADDITIONAL_BUFFERS, + VIDEOATTRIBUTEKEY_PICTUREBUFFER_REQUIREMENTS_REFERENCE_PIC_MULTIPLIER, + // If decoder does not support pixel accurate strides for picture buffer, this + // parameter tells the stride multiple that is needed by the decoder. Plugin + // must obey the given stride in its picture buffer allocations. + VIDEOATTRIBUTEKEY_PICTUREBUFFER_REQUIREMENTS_STRIDE_MULTIPLE, +}; + +enum VideoCodecFourcc { + VIDEOCODECFOURCC_NONE = 0, + VIDEOCODECFOURCC_VP8 = 0x00385056, // a.k.a. Fourcc 'VP8\0'. + VIDEOCODECFOURCC_H264 = 0x31637661, // a.k.a. Fourcc 'avc1'. +}; + +// VP8 specific information to be carried over the APIs. +// Enumeration for flags defining supported VP8 profiles. +enum VP8Profile { + VP8PROFILE_NONE = 0, + VP8PROFILE_0 = 1, + VP8PROFILE_1 = 1 << 1, + VP8PROFILE_2 = 1 << 2, + VP8PROFILE_3 = 1 << 3, +}; + +// H.264 specific information to be carried over the APIs. +// Enumeration for flags defining supported H.264 profiles. +enum H264Profile { + H264PROFILE_NONE = 0, + H264PROFILE_BASELINE = 1, + H264PROFILE_MAIN = 1 << 2, + H264PROFILE_EXTENDED = 1 << 3, + H264PROFILE_HIGH = 1 << 4, + H264PROFILE_HIGH10PROFILE = 1 << 5, + H264PROFILE_HIGH422PROFILE = 1 << 6, + H264PROFILE_HIGH444PREDICTIVEPROFILE = 1 << 7, + H264PROFILE_SCALABLEBASELINE = 1 << 8, + H264PROFILE_SCALABLEHIGH = 1 << 9, + H264PROFILE_STEREOHIGH = 1 << 10, + H264PROFILE_MULTIVIEWHIGH = 1 << 11, +}; + +// Enumeration for defining H.264 level of decoder implementation. +enum H264Level { + H264LEVEL_NONE = 0, + H264LEVEL_10 = 1, + H264LEVEL_1B = H264LEVEL_10 | 1 << 1, + H264LEVEL_11 = H264LEVEL_1B | 1 << 2, + H264LEVEL_12 = H264LEVEL_11 | 1 << 3, + H264LEVEL_13 = H264LEVEL_12 | 1 << 4, + H264LEVEL_20 = H264LEVEL_13 | 1 << 5, + H264LEVEL_21 = H264LEVEL_20 | 1 << 6, + H264LEVEL_22 = H264LEVEL_21 | 1 << 7, + H264LEVEL_30 = H264LEVEL_22 | 1 << 8, + H264LEVEL_31 = H264LEVEL_30 | 1 << 9, + H264LEVEL_32 = H264LEVEL_31 | 1 << 10, + H264LEVEL_40 = H264LEVEL_32 | 1 << 11, + H264LEVEL_41 = H264LEVEL_40 | 1 << 12, + H264LEVEL_42 = H264LEVEL_41 | 1 << 13, + H264LEVEL_50 = H264LEVEL_42 | 1 << 14, + H264LEVEL_51 = H264LEVEL_50 | 1 << 15, +}; + +// Enumeration to describe which payload format is used within the exchanged +// bitstream buffers. +enum H264PayloadFormat { + H264PAYLOADFORMAT_NONE = 0, + // NALUs separated by Start Code. + H264PAYLOADFORMAT_BYTESTREAM = 1, + // Exactly one raw NALU per buffer. + H264PAYLOADFORMAT_ONE_NALU_PER_BUFFER = 1 << 1, + // NALU separated by 1-byte interleaved length field. + H264PAYLOADFORMAT_ONE_BYTE_INTERLEAVED_LENGTH = 1 << 2, + // NALU separated by 2-byte interleaved length field. + H264PAYLOADFORMAT_TWO_BYTE_INTERLEAVED_LENGTH = 1 << 3, + // NALU separated by 4-byte interleaved length field. + H264PAYLOADFORMAT_FOUR_BYTE_INTERLEAVED_LENGTH = 1 << 4, +}; + // Video decoder interface. +// TODO(vmr): Move much of the inner classes to media namespace to simplify code +// that's using it. class VideoDecodeAccelerator { public: - virtual ~VideoDecodeAccelerator() {} + virtual ~VideoDecodeAccelerator(); // Enumeration of potential errors generated by the API. enum Error { VIDEODECODERERROR_NONE = 0, VIDEODECODERERROR_UNINITIALIZED, VIDEODECODERERROR_UNSUPPORTED, + VIDEODECODERERROR_INVALIDINPUT, + VIDEODECODERERROR_MEMFAILURE, VIDEODECODERERROR_INSUFFICIENT_BUFFERS, VIDEODECODERERROR_INSUFFICIENT_RESOURCES, VIDEODECODERERROR_HARDWARE, + VIDEODECODERERROR_UNEXPECTED_FLUSH, }; // Interface expected from PictureBuffers where pictures are stored. class PictureBuffer { public: enum MemoryType { - PICTUREBUFFER_MEMORYTYPE_SYSTEM = 0, + PICTUREBUFFER_MEMORYTYPE_NONE = 0, + PICTUREBUFFER_MEMORYTYPE_SYSTEM, PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE, }; + // Union to represent one data plane in picture buffer. + union DataPlaneHandle { + struct { + uint32 context_id; // GLES context id. + uint32 texture_id; // GLES texture id. + }; + void* sysmem; // Simply a pointer to system memory. + }; virtual ~PictureBuffer(); - virtual uint32 GetId() = 0; + virtual int32 GetId() = 0; virtual gfx::Size GetSize() = 0; virtual const std::vector& GetColorFormat() = 0; virtual MemoryType GetMemoryType() = 0; + virtual std::vector& GetPlaneHandles() = 0; }; class Picture { @@ -76,6 +302,9 @@ class VideoDecodeAccelerator { // the picture buffer size it has provided to the decoder. Thus, there is // no function to query the buffer size from this class. + // Returns the picture buffer where this picture is contained. + virtual PictureBuffer* picture_buffer() = 0; + // Returns the decoded size of the decoded picture in pixels. virtual gfx::Size GetDecodedSize() const = 0; @@ -181,7 +410,7 @@ class VideoDecodeAccelerator { // |callback| contains the callback function pointer. // // Returns true when command successfully accepted. Otherwise false. - virtual bool Abort(VideoDecodeAcceleratorCallback* callback) = 0; + virtual bool Abort(VideoDecodeAcceleratorCallback* callback) = 0; }; } // namespace media -- cgit v1.1