예제 #1
0
/*------------------------------------------------------------------------------
|    OMX_TextureData::freeData
+-----------------------------------------------------------------------------*/
void OMX_TextureData::freeData()
{
   if (!m_textureData || !m_textureId || !m_eglImage)
      log_warn("Double free of OMX texture data requested.");

   EGLDisplay eglDisplay = get_egl_display();

   // Destroy texture, EGL image and free the buffer.
   log_debug("Freeing KHR image...");
   if (m_eglImage && eglDestroyImageKHR(eglDisplay, m_eglImage) == EGL_SUCCESS) {
      EGLint err = eglGetError();
      LOG_ERROR(LOG_TAG, "Failed to destroy EGLImageKHR: %d.", err);
   }
   m_eglImage = NULL;

   if (m_textureId) {
      log_debug("Freeing texture...");
      glDeleteTextures(1, &m_textureId);
      m_textureId = 0;
   }

   if (m_textureData) {
      log_debug("Freeing texture data...");
      delete m_textureData;
      m_textureData = NULL;
   }
}
예제 #2
0
/*------------------------------------------------------------------------------
|    OpenMAXILTextureLoader::instantiateTexture
+-----------------------------------------------------------------------------*/
OMX_TextureData* OMX_TextureProviderQQuickItem::instantiateTexture(QSize size)
{
   EGLDisplay eglDisplay = get_egl_display();
   EGLContext eglContext = get_egl_context();

   EGLint attr[] = {EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE};

   GLuint textureId;
   glGenTextures(1, &textureId);
   glBindTexture(GL_TEXTURE_2D, textureId);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

   // It seems that only 4byte pixels is supported here.
   GLubyte* pixel = new GLubyte[size.width()*size.height()*4];
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);

   EGLImageKHR eglImage = eglCreateImageKHR(
            eglDisplay,
            eglContext,
            EGL_GL_TEXTURE_2D_KHR,
            (EGLClientBuffer)textureId,
            attr
            );

   EGLint eglErr = eglGetError();
   if (eglErr != EGL_SUCCESS) {
      LOG_ERROR(LOG_TAG, "Failed to create KHR image: %d.", eglErr);
      return 0;
   }

   OMX_TextureData* textureData = new OMX_TextureData;
   textureData->m_textureId   = textureId;
   textureData->m_textureData = pixel;
   textureData->m_eglImage    = eglImage;
   textureData->m_textureSize = size;
   return textureData;
}
예제 #3
0
OMX_VideoGraph::OMX_VideoGraph(
        OMX_TextureProvider* provider,
        QObject* parent
        ) :
    m_eglDisplay(get_egl_display()),
    m_eglContext(get_egl_context()),
    m_provider(provider),
    m_eglBuffer(NULL),
    m_texture(m_eglDisplay),
    port_settings_changed(0),
    first_packet(1),
    fillCalled(false)
{
    // Get core.
    // TODO: Init of core must be changed.
    m_core = OMX_Core::instance();
    if (!m_core)
        throw OMX_Exception("Failed to init core.");

    // Create the components.
    LOG_VERBOSE(LOG_TAG, "Instantiating components...");
    compEGLRender = OMXComponentFactory<MyEGLRenderer>::getInstance(
                "OMX.broadcom.egl_render"
                );
    compDecoder = OMXComponentFactory<OMXComponent>::getInstance(
                "OMX.broadcom.video_decode"
                );
    compClock = OMXComponentFactory<OMXComponent>::getInstance(
                "OMX.broadcom.clock"
                );
    compScheduler = OMXComponentFactory<OMXComponent>::getInstance(
                "OMX.broadcom.video_scheduler"
                );

    if (!(compEGLRender && compDecoder && compClock && compScheduler))
        throw OMX_Exception("Failed to create component.");

    // Disable all ports. It is necessary to do it here because otherwise
    // I'll not be able to make the components switch to IDLE state.
    LOG_VERBOSE(LOG_TAG, "Disabling all the ports...");
    compEGLRender->sendCommand(OMX_CommandPortDisable, 220, NULL);
    compEGLRender->waitForEvent(OMX_EventCmdComplete, OMX_CommandPortDisable, 220, TIMEOUT_MS);
    compEGLRender->sendCommand(OMX_CommandPortDisable, 221, NULL);
    compEGLRender->waitForEvent(OMX_EventCmdComplete, OMX_CommandPortDisable, 221, TIMEOUT_MS);
    compDecoder->sendCommand(OMX_CommandPortDisable, 130, NULL);
    compDecoder->waitForEvent(OMX_EventCmdComplete, OMX_CommandPortDisable, 130, TIMEOUT_MS);
    compDecoder->sendCommand(OMX_CommandPortDisable, 131, NULL);
    compDecoder->waitForEvent(OMX_EventCmdComplete, OMX_CommandPortDisable, 131, TIMEOUT_MS);
    for (int i = 80; i <= 85; i++) {
        compClock->sendCommand(OMX_CommandPortDisable, i, NULL);
        compClock->waitForEvent(OMX_EventCmdComplete, OMX_CommandPortDisable, i, TIMEOUT_MS);
    }
    for (int i = 10; i <= 12; i++) {
        compScheduler->sendCommand(OMX_CommandPortDisable, i, NULL);
        compScheduler->waitForEvent(OMX_EventCmdComplete, OMX_CommandPortDisable, i, TIMEOUT_MS);
    }
    LOG_VERBOSE(LOG_TAG, "All the ports were disabled.");

    // Setup clock.
    LOG_VERBOSE(LOG_TAG, "Setting params.");
    OMX_TIME_CONFIG_CLOCKSTATETYPE cstate;
    memset(&cstate, 0, sizeof(cstate));
    cstate.nSize = sizeof(cstate);
    cstate.nVersion.nVersion = OMX_VERSION;
    cstate.eState = OMX_TIME_ClockStateWaitingForStartTime;
    cstate.nWaitMask = 1;
    compClock->SetParameter(OMX_IndexConfigTimeClockState, &cstate);

    // Setup the tunnels.
    tunnelDecSched = new OMXTunnel(
                compDecoder.get(),
                OMXCompVideoDecoder::outputPort,
                compScheduler.get(),
                OMXCompVideoScheduler::inputVideoPort
                );
    tunnelSchedRender = new OMXTunnel(
                compScheduler.get(),
                OMXCompVideoScheduler::outputPort,
                compEGLRender.get(),
                220
                );
    tunnelClockSched = new OMXTunnel(
                compClock.get(),
                80,
                compScheduler.get(),
                OMXCompVideoScheduler::inputClockPort
                );

    LOG_VERBOSE(LOG_TAG, "Setting up tunnel clock/scheduler.");
    tunnelClockSched->setupTunnel(0, 0);
    compClock->sendCommand(OMX_CommandStateSet, OMX_StateExecuting, NULL);
    compDecoder->sendCommand(OMX_CommandStateSet, OMX_StateIdle, NULL);

    LOG_VERBOSE(LOG_TAG, "Setting input parameters.");
    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
    memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
    format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
    format.nVersion.nVersion = OMX_VERSION;
    format.nPortIndex = 130;
    format.eCompressionFormat = OMX_VIDEO_CodingAVC;
    compDecoder->SetParameter(OMX_IndexParamVideoPortFormat, &format);

    OMX_NALSTREAMFORMATTYPE nalFormat;
    OMX_INIT_STRUCTURE(nalFormat);
    nalFormat.nPortIndex = 130;
    //assert(OMX_GetParameter(compDecoder->GetHandle(), , &nalFormat) == OMX_ErrorNone);
    //compDecoder->GetParameter(OMX_IndexParamNalStreamFormatSupported, &nalFormat);
    nalFormat.eNaluFormat = OMX_NaluFormatOneNaluPerBuffer;
    compDecoder->SetParameter((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSelect, &nalFormat);

    //assert(false);

    // Provide buffers and enabled the port.
    compDecoder->enablePortBuffers(130);

    LOG_VERBOSE(LOG_TAG, "Changing decoder state to executing.");
    compDecoder->sendCommand(OMX_CommandStateSet, OMX_StateExecuting, NULL);
}