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
