gst-vaapi and opengl again

Jorge jorgefm at cirsa.com
Wed Mar 13 07:44:10 PDT 2013


Hi Nicolas!

Thanks to your clarifications I've been able to implement a little SDL
application to display a GStreamer video in a texture!
Now I'm trying to optimize it because the CPU utilization is bigger in my
application than in the next test pipeline:

$ gst-launch-0.10 filesrc
location=/tmp/simpsons_movie_trailer/TheSimpsonsMovie-Trailer.mp4 ! qtdemux
! vaapidecode ! vaapisink

With gst-launch, top shows the CPU around 8%, adding process gst-launch-0.10
and Xorg, and my application is around 30%
In my SDL application I'm using OpenGL to painting the texture content
upload from the converter. Basically I have the code to handle the new
buffer and upload it to a texture:

/* The appsink has received a buffer */
static void on_new_buffer( GstElement *sink, void *data )
{
  GstBuffer *buffer;
  GstSurfaceBuffer *surface;
  DecodingPrivateData *priv = (DecodingPrivateData *)data;

  // Retrieve the buffer.
  g_signal_emit_by_name( sink, "pull-buffer", &buffer );
  if( !buffer )
    return;

  // Cast to surface.
  if( !GST_IS_SURFACE_BUFFER( buffer ) ) {
    goto on_new_buffer_exit;
  }
  surface = GST_SURFACE_BUFFER( buffer );

  //printf( "%s - surface %p, buffer %p\n", __FUNCTION__, surface, buffer );

  // Set OpenGL context.
  if( glXMakeCurrent( priv->x11_display, priv->x11_window, priv->gl_context
) == 0 )
    goto on_new_buffer_exit;

  // Create the converter if not yet ready.
  if( G_UNLIKELY( priv->converter == NULL ) ) {
    GValue value = {0};

    g_value_init( &value, G_TYPE_UINT );
    g_value_set_uint( &value, priv->texture );
    priv->converter = gst_surface_buffer_create_converter( surface,
"opengl", &value );
    //printf( "%s - Converter %p for tex_id %d\n", __FUNCTION__,
priv->converter, priv->texture );
  }

  // Upload surface to the OpenGL texture.
  if( priv->converter != NULL ) {
    gst_surface_converter_upload( priv->converter, surface );
    priv->repaint = 1;
  }

on_new_buffer_exit:
  gst_buffer_unref( buffer );
}

and the painting code in the SDL main loop and a helper to render a quad:

  while (run) {

    // Handle events.
    SDL_Event event;
    while (SDL_PollEvent (&event)) {
      switch (event.type) {
      case SDL_QUIT:
        run = 0;
        break;

      case SDL_KEYDOWN:
        switch (event.key.keysym.sym) {
        case SDLK_q:
        case SDLK_ESCAPE:
          run = 0;
          break;
        default:
          break;
        }
        break;

      default:
        break;
      }
    }

    // Render frame.
    if( decoding_data.repaint == 1 ) {
      render_frame(0, 0, decoding_data.width, decoding_data.height);
      decoding_data.repaint = 0;
      ++frames;
    } else
      SDL_Delay(10);
  }

where

void render_frame( int x, int y, int w, int h )
{
    glBindTexture( GL_TEXTURE_2D, decoding_data.texture );
	glBegin(GL_TRIANGLE_STRIP);
	glTexCoord2f(0.0f, 0.0f); glVertex2i(x,   y  );
	glTexCoord2f(1.0f, 0.0f); glVertex2i(x+w, y  );
	glTexCoord2f(0.0f, 1.0f); glVertex2i(x,   y+h);
	glTexCoord2f(1.0f, 1.0f); glVertex2i(x+w, y+h);
	glEnd();

    SDL_GL_SwapBuffers( );
}

What do you recommend in order to debug the application to locate where the
CPU is wasted? Is there any additional memory copy that I missed?

Thanks!



--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/gst-vaapi-and-opengl-again-tp4658892p4659107.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list