This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Android Demo for video texture can not work

I am wroking with Anand in shanghai.

He gave us a demo to create eglimage on android.

But it can not work .

=======================================

int main(int argc, char** argv) {
EGLBoolean returnValue;
EGLConfig myConfig = {0};

EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
EGLint s_configAttribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE,8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_SAMPLE_BUFFERS, 1,
EGL_SAMPLES, 4,
EGL_NONE};
EGLint majorVersion;
EGLint minorVersion;
EGLContext context;
EGLSurface surface;
EGLint w, h;

EGLDisplay dpy;

checkEglError("<init>");
dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
checkEglError("eglGetDisplay");
if (dpy == EGL_NO_DISPLAY) {
printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
return 0;
}

returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
checkEglError("eglInitialize", returnValue);
fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
if (returnValue != EGL_TRUE) {
printf("eglInitialize failed\n");
return 0;
}

WindowSurface windowSurface;
EGLNativeWindowType window = windowSurface.getSurface();
returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig);
if (returnValue) {
printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
return 1;
}
}
=================================================
The red word above returns an error -21
Anand told us to push this question here
  • Hi,

    I have forwarded your question to an expert for comment.

    Regards,
    Yordan
  • Hi,

    Could you share information on what TI baseline release is this being run against?

    Thanks,

    Gowtham

  • I have post a picture about system info below

    ===============Another question=================

    Using a new patch(gralloc.so) from Anand, We have successfully set up YV12 texture , just like the code already metioned.

    The main API is "registerBuffer" which can register our physical buffer.

    But when we turn to YUYV format it crashed !

    The "registerBuffer" is to blame.

    =================Here is our code===============================

    #include "VideoTexture.h"
    
    
    
    #define FOURCC(a, b, c, d) ((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24 ))
    #define FOURCC_STR(str)    FOURCC(str[0], str[1], str[2], str[3])
        EGLSyncKHR (*eglCreateSyncKHR)(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
        EGLBoolean (*eglDestroySyncKHR)(EGLDisplay dpy, EGLSyncKHR sync);
        EGLint (*eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
        EGLBoolean (*eglGetSyncAttribKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
    #include "drm_fourcc.h"
    
        PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
        PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
    
        static ANativeWindowBuffer anwb;
        const gralloc_module_t *grModule = NULL;
        const alloc_device_t *allocDevice = NULL;
    
        const int yuvTexUsage = android::GraphicBuffer::USAGE_HW_TEXTURE | android::GraphicBuffer::USAGE_SW_WRITE_RARELY;
        const int yuvTexFormat = HAL_PIXEL_FORMAT_YV12;
    
        int align(int x, int a) {
            return (x + (a-1)) & (~(a-1));
        }
        static int openGraphicsHAL()
        {
            int err = 0;
            gralloc_module_t const *module;
    
            if (grModule)
                return 0;
    
            err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
                                (const hw_module_t **)&module);
            if (err) {
                RUN_INFO("%s: Failed to open Android Graphics HAL (err=%d)\n",
                        __func__, err);
                goto err_out;
            }
    
            err = module->common.methods->open((const hw_module_t *)module,
                                               GRALLOC_HARDWARE_GPU0, (hw_device_t **)&allocDevice);
            if (err) {
                RUN_INFO("%s: Failed to open Android Grapichs HAL device (err=%d)\n",
                        __func__, err);
                goto err_out;
            }
    
            grModule = module;
    
            err_out:
            return err;
        }
    
        static void incRefNop(struct android_native_base_t __unused *base) {}
        static void decRefNop(struct android_native_base_t __unused *base) {}
    
    #define  OMAP_BO_M4_BUFFER_SHIFT	 20
        void * VideoTexture::alloc_bo(int bpp, int width, int height, int *bo_handle, int *pitch, unsigned char nBufidx)
        {
            uint32_t flag = 0;
    
            if(nBufidx >=1 && nBufidx <= 8){
                flag = nBufidx << OMAP_BO_M4_BUFFER_SHIFT;
            }
            else{
                RUN_INFO("bufIdx error!! %d",nBufidx);
                return NULL;
            }
    
            struct omap_bo *bo;
            uint32_t bo_flags =  OMAP_BO_SCANOUT;
    
            if ((bo_flags & OMAP_BO_TILED) == OMAP_BO_TILED)
            {
                bo_flags &= ~OMAP_BO_TILED;
                if (bpp == 8) {
                    bo_flags |= OMAP_BO_TILED_8;
                } else if (bpp == 16) {
                    bo_flags |= OMAP_BO_TILED_16;
                } else if (bpp == 32) {
                    bo_flags |= OMAP_BO_TILED_32;
                }
            }
    
            bo_flags |= OMAP_BO_WC;
    
            if (bo_flags & OMAP_BO_TILED) {
                //bo = omap_bo_new_tiled((omap_device*)m_pGraphic->GetDevice(), width, height, bo_flags);
            } else {
                //bo = omap_bo_new((omap_device*)m_pGraphic->GetDevice(), width * height * bpp / 8, bo_flags);
                RUN_INFO("omap_bo_new nBufidx:%d\r\n", nBufidx);
                RUN_INFO("omap_device:%x\r\n", m_pGraphic->GetDevice());
                RUN_INFO("width:%d  height:%d  bpp:%d\r\n", width, height, bpp);
                bo = omap_bo_new((omap_device*)m_pGraphic->GetDevice(), width * height * bpp / 8,
                                            OMAP_BO_WC | OMAP_BO_SCANOUT | flag);
                RUN_INFO("bo:%x\r\n", bo);
            }
    
            if (bo)
            {
                //*bo_handle = omap_bo_handle(bo);
                *pitch = width * bpp / 8;
                //if (bo_flags & OMAP_BO_TILED)
                //*pitch = ALIGN2(*pitch, PAGE_SHIFT);
                RUN_INFO("pitch:%d\r\n", *pitch);
            }
            return (void*)bo;
        }
    
        int  VideoTexture::SetYV12Buffer(unsigned char* pBuffer, int nWid, int nHgt, unsigned char nBufidx)
        {
            if (nWid <= 0 || nHgt <= 0)
            {
                RUN_INFO("InitVideoBuffer!error");
                return NULL;
            }
    
            map<unsigned char, unsigned int>::iterator iter = m_mapDma2Tex.find(nBufidx);
            if (iter != m_mapDma2Tex.end())
            {
                //RUN_INFO("Not Create YUV BUffer begin %d\r\n", nBufidx);
                m_nTexture = iter->second;
            }
            else
            {
                RUN_INFO("Create YUV BUffer begin %d\r\n", nBufidx);
                PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
                PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
                eglCreateImageKHR =
                        (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
                glEGLImageTargetTexture2DOES =
                        (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
    
                int nPitch = 0;
                int nHandle =  OMAP_BO_SCANOUT;
                int dfd = 0;
                EGLint attr[20];
    
                omap_bo * tempBO = (omap_bo * )alloc_bo(16, nWid, nHgt, &nHandle, &nPitch, nBufidx);
    
                dfd = omap_bo_dmabuf(tempBO);
                RUN_INFO("dfd:%d\r\n", dfd);
    
                /* create a native_handle and wrap it in ANativeWindowBuffer */
                IMG_native_handle_t *imgHandle = (IMG_native_handle_t *)native_handle_create(
                        1, IMG_NATIVE_HANDLE_NUMFDS - 1 + IMG_NATIVE_HANDLE_NUMINTS);
                if (!imgHandle) {
                    RUN_INFO("Failed to create IMG_native_handle_t\n");
                    return false;
                }
                imgHandle->fd[0] = dfd;
                imgHandle->usage = yuvTexUsage;
                imgHandle->iWidth = nWid;
                imgHandle->iHeight = nHgt;
                imgHandle->iFormat = yuvTexFormat;
                imgHandle->uiBpp = 12;
                imgHandle->uiFlags = 0;
                imgHandle->ui64Stamp = 0ULL;
                RUN_INFO("Created buffer_handle\n");
    
                android::status_t err = openGraphicsHAL();
                if (err) {
                    RUN_INFO("%s: Failed to open graphics HAL\n", __func__);
                    return false;
                }
    
                err = grModule->registerBuffer(grModule, (buffer_handle_t)imgHandle);
                if (err) {
                    RUN_INFO("%s: Failed to register buffer with gralloc (%d)\n",
                            __func__, err);
                    return false;
                }
                RUN_INFO("Registerd the buffer with gralloc\n");
    
                anwb.common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
                anwb.common.version = sizeof(ANativeWindowBuffer);
                memset(anwb.common.reserved, 0, sizeof(anwb.common.reserved));
                anwb.common.incRef = incRefNop;
                anwb.common.decRef = decRefNop;
                anwb.width = imgHandle->iWidth;
                anwb.height = imgHandle->iHeight;
                anwb.stride = align(anwb.width, 16);
                anwb.usage = imgHandle->usage;
                anwb.format = imgHandle->iFormat;
                anwb.handle = (buffer_handle_t)imgHandle;
                RUN_INFO("Create ANativeWindowBuffer out of buffer handle\n");
    
                EGLImageKHR img = eglCreateImageKHR(m_pGraphic->GetDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
                                                    (EGLClientBuffer)&anwb, 0);
    
                EGLint error = eglGetError();
    
                if (error != EGL_SUCCESS)
                {
                    RUN_INFO(" CreateImageKHR: error%d\n", error);
                }
                else{
                    RUN_INFO(" eglCreateImageKHR: success!\n");
                }
    
                if (m_pKHRImage == EGL_NO_IMAGE_KHR) {
                    RUN_INFO(" m_pKHRImage iS Null !!!\n");
                }
    
    
                glGenTextures(1, &m_nTexture);
                glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_nTexture);
                glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                //glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
                //glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_LINEAR);
                glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)m_pKHRImage);
                //glGenerateMipmap(GL_TEXTURE_EXTERNAL_OES);
                //m_pAddress = omap_bo_map(tempBO);
                m_mapDma2Tex.insert(pair<unsigned char, unsigned int>(nBufidx, m_nTexture));
            }
    
            m_nVideoWid = nWid;
            m_nVideoHgt = nHgt;
            return SUCCESS_RETURN;
        }
    
    
        int VideoTexture::UpdateToShader()
        {
            unsigned int nProgram =  m_pEffect->GetCurrentProgram();
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_nTexture);
            glGenerateMipmap(GL_TEXTURE_EXTERNAL_OES);
            GLint location = glGetUniformLocation(nProgram, "sam0");
            if (location == -1)
            {
                RUN_INFO("-1 loacation!\r\n");
                return HIK3DERR_WRONG_PARA;
            }
            glUniform1i(location, 0);
    
            return SUCCESS_RETURN;
        }
    
    }

    ====================================================
    We just modified  HAL_PIXEL_FORMAT_YV12 to HAL_PIXEL_FORMAT_YCbCr_422_I

    The api "registerBuffer" crashed!

    And we tried all format in headers,the format which can be successfully created is:

     HAL_PIXEL_FORMAT_YV12,    HAL_PIXEL_FORMAT_TI_NV12

    which failed is:

    HAL_PIXEL_FORMAT_TI_UYVY, HAL_PIXEL_FORMAT_YCbCr_422_888, HAL_PIXEL_FORMAT_YCbCr_444_888

    And we directly use "YUYV" as a fourcc code 0x56595559, it crashed as well

    And we modified the bpp from 12 to 16, crashed again.

    =====================================================================

    So how to create a yuyv image on android?

     

     

  • Hi,

    Let me check with Anand on what are the changes made to the gralloc library.

    For register buffer error, please take the binaries from the below patch. It fixed some of the errors with registerBuffer API usage in the way you are using in your test.

    review.omapzoom.org/

     

    Thanks,

    Gowtham

     

     

  • That did not work. Can you just try video data with "YUYV(YUY2)" format.

    And show how it work(write a simple demo)?  

  • Hi,

    The attached is an example (modified version of Android `gl2_yuvtex` test) that shows the use of registering a NV12 `omap_bo` buffer with gralloc. I do see that your snippet follows along the similar lines, so it should be pretty similiar. With respect to YUV2 format support, gralloc doesn't mandate its support and it is currently not supported in our gralloc  implementation. If you are seeing errors for any non NV12 YUV formats, then the behavior is along expected lines. Does NV12 suffice your needs?

    Thanks,

    Gowthamgl2_yuvtex_import.tar.gz

  • I have successfully create yv12 and nv12 texture.

    But that is not enough, because our camera sensor supply only yuy2 format, which means we must transform it  manually.

    Actually, we have already done this, but that takes too much time with vpe processor.

    But if we transform it with cpu,  though faster, high utilization will be another problem.

    ====================================================================

    Can you make a patch to support yuy2 format?

    That must be the perfect solution!

  • Hi,

    Unfortunately adding support for YUV2 format won't be trivial. We can plan for it's support in our upcoming Oreo release, which will be in 2Q. At this point you can either upgrade to the newer release or backport the patches to your baseline.

    Thanks,
    Gowtham