blob: 7ea44e91ef2208cee76ab7fd3a2e7b57e5034dbd [file] [log] [blame]
Name
QCOM_motion_estimation
Name Strings
GL_QCOM_motion_estimation
Contributors
Jonathan Wicks
Sam Holmes
Jeff Leger
Contacts
Jeff Leger <jleger@qti.qualcomm.com>
Status
Complete
Version
Last Modified Date: March 19, 2020
Revision: 1.0
Number
OpenGL ES Extension #326
Dependencies
Requires OpenGL ES 2.0
This extension is written against the OpenGL ES 3.2 Specification.
This extension interacts with OES_EGL_image_external.
Overview
Motion estimation, also referred to as optical flow, is the process of
producing motion vectors that convey the 2D transformation from a reference
image to a target image. There are various uses of motion estimation, such as
frame extrapolation, compression, object tracking, etc.
This extension adds support for motion estimation in OpenGL ES by adding
functions which take the reference and target images and populate an
output texture containing the corresponding motion vectors.
New Procedures and Functions
void TexEstimateMotionQCOM(uint ref,
uint target,
uint output);
void TexEstimateMotionRegionsQCOM(uint ref,
uint target,
uint output,
uint mask);
New Tokens
Accepted by the <pname> parameter of GetIntegerv, GetInteger64v, and GetFloatv:
MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM 0x8C90
MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM 0x8C91
Additions to the OpenGL ES 3.2 Specification
Add two new rows in Table 21.40 "Implementation Dependent Values"
Get Value Type Get Command Minimum Value Description Sec
--------- ---- ----------- ------------- ----------- ------
MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM Z+ GetIntegerv 1 The block size in X 8.19
MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM Z+ GetIntegerv 1 The block size in Y 8.19
Additions to Chapter 8 of the OpenGL ES 3.2 Specification
The commands
void TexEstimateMotionQCOM(uint ref,
uint target,
uint output);
void TexEstimateMotionRegionsQCOM(uint ref,
uint target,
uint output,
uint mask);
are called to perfom the motion estimation based on the contents of the two input
textures, <ref> and <target>. The results of the motion estimation are stored in
the <output> texture.
The <ref> and <target> must be either be GL_R8 2D textures, or backed by EGLImages where
the underlying format contain a luminance plane. The <ref> and <target> dimension must
be identical and must be an exact multiple of the search block size. While <ref> and <target>
can have multiple levels, the implementation only reads from the base level.
The resulting motion vectors are stored in a 2D texture <output> of the format GL_RGBA16F,
ready to be used by other application shaders and stages. While <output> can have multiple
levels, the implementation only writes to the base level. The <output> dimensions
must be set as follows so that it can hold one vector per search block:
output.width = ref.width / MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM
output.height = ref.height / MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM
Each texel in the <output> texture represents the estimated motion in pixels, for the supported
search block size, from the <ref> texture to the <target> target texture. Implementations may
generate sub-pixel motion vectors, in which case the returned vector components may have fractional
values. The motion vector X and Y components are provided in the R and G channels respectively.
The B and A components are currently undefined and left for future expansion. If no motion is
detected for a block, or if the <mask> texture indicates that the block should be skipped, then
the R and G channels will be set to zero, indicating no motion.
The <mask> texture is used to control the region-of-interest which can help to reduce the
overall workload. The <mask> texture dimensions must exactly match that of the <output>
texture and the format must be GL_R8UI. While <mask> can have multiple levels, the
implementation only reads from the base level. For any texel with a value of 0 in the <mask>
motion estimation will not be performed for the corresponding block. Any non-zero texel value
will produce a motion vector result in the <output> result. The <mask> only controls the vector
basepoint. Therefore it is possible for an unmasked block to produce a vector that lands in the
masked block.
Errors
INVALID_OPERATION is generated if any of the textures passed in are invalid
INVALID_OPERATION is generated if the texture types are not TEXTURE_2D or TEXTURE_EXTERNAL_OES
INVALID_OPERATION is generated if <ref> is not of the format GL_R8, or when backed by an EGLImage,
when the underlying internal format does not contain a luminance plane.
INVALID_OPERATION is generated if <target> is not of the format GL_R8, or when backed by an EGLImage,
when the underlying internal format does not contain a luminance plane.
INVALID_OPERATION is generated if the <ref> and <target> textures do not have
identical dimensions
INVALID_OPERATION is generated if the <output> texture is not of the format GL_RGBA16F
INVALID_OPERATION is generated if the <mask> texture is not of the format GL_R8UI
INVALID_OPERATION is generated if the <output> or <mask> dimensions are not
ref.[width/height] / MOTION_ESTIMATION_SEARCH_BLOCK_[X,Y]_QCOM
Interactions with OES_EGL_image_external
If OES_EGL_image_external is supported, then the <ref> and/or <target> parameters to
TexEstimateMotionQCOM and TexEstimateMotionRegionsQCOM may be backed by an EGLImage.
Issues
(1) What should the pixel data of the input textures <ref> and <target> contain?
Resolved: Motion estimation tracks the brightness across the input textures. To produce
the best results, it is recommended that the texels in the <ref> and <target> textures
represent some measure of the luminance/luma. OpenGL ES does not currently expose
a Y8 or Y plane only format, so GL_R8 can be used. Alternatively, a texture backed by
and EGLImage, which has an underlying format where luminance is contained in a separate plane,
can also be used. If starting with an RGBA8 texture one way to convert it to GL_R8 would be
to perform a copy and use code such as the following:
fragColor = rgb_2_yuv(texture(tex, texcoord).rgb, itu_601_full_range).r;\n"
(2) Why use GL_RGBA16F instead of GL_RG16F for storing the motion vector output?
Resolved: While only the R and G channels are currently used, it was decided to use
a format with more channels for future expansion. A floating point format was chosen
to support implementations with sub-pixel precision without enforcing any particular precision
requirements other than what can be represented in a 16-bit floating point number.
(3) Why is the motion estimation quality not defined?
Resolved: The intention of this specification is to estimate the motion between
the two input textures. Implementations should aim to produce the highest quality estimations
but since the results are estimations there are no prescribed steps for how the vectors
must be generated.
Revision History
Rev. Date Author Changes
---- ---------- -------- -----------------------------------------
1.0 03/19/2020 Jonathan Wicks Initial public version