Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Rok
Contributor
Rok
Posts: 11
Registered: ‎01-25-2013
My Device: Developer
My Carrier: Developer

OpenGL windows and video playback

[ Edited ]

I'm having difficulty displaying a (mp4) video.  In my game the main window is initialised with OpenGL.  I'm basing my video playback on the VideoPlayback sample code.

 

I'm using bbutil_init_egl function for game initialisation purposes.  The only ammendment I've made to it is to add the following line after screen_create_window -

 

screen_create_window_group(screen_win, window_group_name);

 

My initial thought was to create a child window to display the video but, from what I can gather, the renderer creates its own child window when attached.

 

So I'm initialising the video playback using -

 

mmr_connection = mmr_connect(NULL);
mmr_context = mmr_context_create(mmr_connection, video_context_name, 0, S_IRWXU | S_IRWXG | S_IRWXO);

 

 

And, later, commencing the playback using -

 

video_device_output_id = mmr_output_attach(mmr_context, video_device_url, "video");
audio_device_output_id = mmr_output_attach(mmr_context, audio_device_url, "audio");
mmr_input_attach(mmr_context, media_file, "track");
mmr_play(mmr_context);

 

 

(I've removed all error checking code, etc, for the purposes of clarity)

 

I can hear the video's audio but just see what's already rendered in OpenGL.  If I change the screen format from SCREEN_FORMAT_RGBX8888 to SCREEN_FORMAT_RGBA8888 I still hear the audio but see a black screen.

 

Can anyone shed some light on what I need to do to actually see the video?

Please use plain text.
Developer
step_jac
Posts: 89
Registered: ‎05-31-2012
My Device: BlackBerry Playbook
My Carrier: Bell

Re: OpenGL windows and video playback

Hi Rok,

 

Dealth with exactly this in previous games we ported to BB10/PBOS.

The sample for video doesn't really show how to use the component other than standalone.

 

One key this you need to do is have the window window join the global windowgroup that you created initially in bbutil_initegl:

 

rc = screen_join_window_group(video_window, window_group_name);

 

As well as a few other gimmicks.

 

I've include full trimmed down source below that depicts movie playback as a busy look with OpenGL overlay rendering (optionally).

 

Best,

 

Stephane

 

    // I/O devices
    static const char *video_device_url    = "screen:?winid=bardtalevideowindow&wingrp=jbewindowgrp";
    static const char *audio_device_url    = "audio:default";

    // Name of video context
    static const char *video_context_name = "bardtalevideocontextname";

    // Window group name
    static const char *window_group_name = "jbewindowgrp";
    const char* winid = "bardtalevideowindow";
    int rc;

    // Screen variables
    screen_context_t    screen_context = getGlobalScreenContext(); //HOWEVER THIS IS EXPOSED
    screen_window_t        screen_window = 0;
    int size[2]    = {0,0};

    // Renderer variables
    mmr_connection_t*     mmr_connection = 0;
    mmr_context_t*        mmr_context = 0;

    // I/O variables
    int                    video_device_output_id = -1;
    int                    audio_device_output_id = -1;

    /*
     * Create the window used for video output.
     */

    rc = screen_create_window_type(&screen_window, screen_context, SCREEN_CHILD_WINDOW);
    assert(rc == 0);

    int format = SCREEN_FORMAT_RGBX8888;
    rc = screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_FORMAT, &format);
    assert(rc == 0);

    int usage = SCREEN_USAGE_NATIVE;
    rc = screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_USAGE, &usage);
    assert(rc == 0);

    int z = -1;
    rc = screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_ZORDER, &z);
    assert(rc == 0);

    screen_set_window_property_cv(screen_window, SCREEN_PROPERTY_ID_STRING, strlen(winid), winid);
    assert(rc == 0);

    rc = screen_create_window_buffers(screen_window, 1);
    assert(rc == 0);

    rc = screen_join_window_group(screen_window, window_group_name);
    assert(rc == 0);

   /*
     * Configure mm-renderer.
     */
    mmr_connection = mmr_connect(NULL);
    assert(mmr_connection);

    mmr_context = mmr_context_create(mmr_connection, video_context_name, 0, S_IRWXU|S_IRWXG|S_IRWXO);
    assert(mmr_context);

    // Make the window visible
    rc = screen_get_window_property_iv(screen_window, SCREEN_PROPERTY_SIZE, size);
    assert(rc == 0);

    /*
     * Configure video and audio output.
     */
    video_device_output_id = mmr_output_attach(mmr_context, video_device_url, "video");
    assert(video_device_output_id != -1);

    audio_device_output_id = mmr_output_attach(mmr_context, audio_device_url, "audio");
    assert(audio_device_output_id != -1);

    // Get the render buffer
    screen_buffer_t temp_buffer[1];
    rc = screen_get_window_property_pv( screen_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)temp_buffer);
    assert(rc == 0);

    // Fill the buffer with a solid color (black)
    int fill_attributes[3] = {SCREEN_BLIT_COLOR, 0x0, SCREEN_BLIT_END};
    rc = screen_fill(screen_context, temp_buffer[0], fill_attributes);
    assert(rc == 0);

    int temp_rectangle[4] = {0,0,size[0],size[1]};
    rc = screen_post_window(screen_window, temp_buffer[0], 1, temp_rectangle, 0);
    assert(rc == 0);

    // Build up the path where our bundled resource is.
    char media_file[PATH_MAX];
    char media_url[PATH_MAX];

    snprintf( media_file, sizeof(media_file), "%s/movies/%s.mp4", JBE::File::GetAppDir(), baseFileName );
    rc = snprintf(media_url, PATH_MAX, "file://%s", media_file);
    assert( ((rc != -1) && (rc < PATH_MAX)) );

    /*
     * Start the playback.
     */
    rc = mmr_input_attach(mmr_context, media_url, "track");
    assert( rc == 0);

    rc = mmr_play(mmr_context);
    assert( rc == 0);

    mmrenderer_monitor_t *mon = mmrenderer_request_events(video_context_name, 0, NULL);

    movieDone = false;
    movieFrame = 0;
    /*
     * Handle keyboard events and stop playback upon user request.
     */

    while( !movieDone )
    {
#ifdef BLACKBERRY10
        {
            // now, get the actual event
            const mmr_event_t * event = mmr_event_get(mmr_context);
            if( event  )
            {
                movieDone = ( event->type == MMR_EVENT_ERROR );
            }
        }
#endif
        beginGLFrame(clear);
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        if( frameCallback( movieFrame ) ) // Do OpenGL rendering.
        {
            movieDone = true;
        }
        endGLFrame();
    }

    mmrenderer_stop_events(mon);

    rc = mmr_stop(mmr_context);
    assert(rc == 0);

    rc= mmr_output_detach(mmr_context, video_device_output_id);
    //const mmr_error_info_t *err2 = mmr_error_info( mmr_context );
    //assert(rc == 0);

    rc = mmr_output_detach(mmr_context, audio_device_output_id);
    //const mmr_error_info_t *err1 = mmr_error_info( mmr_context );
    //assert(rc == 0);


    rc = mmr_context_destroy(mmr_context);
    assert(rc == 0);

    mmr_context = 0;
    video_device_output_id = -1;
    audio_device_output_id = -1;

    mmr_disconnect(mmr_connection);
    mmr_connection = 0;


    rc = screen_destroy_window(screen_window);
    assert(rc == 0);
    screen_window = 0;

Please use plain text.
Rok
Contributor
Rok
Posts: 11
Registered: ‎01-25-2013
My Device: Developer
My Carrier: Developer

Re: OpenGL windows and video playback

Thanks for the detailed reply.  Unfortunately, using that code I was getting the same result as before.

 

What I found is that if I make the format of the main window SCREEN_FORMAT_RGBA8888 and clear the GL buffers using

 

glClear(GL_COLOR_BUFFER_BIT);
bbutil_swap();

in the renderer monitoring loop, I can now see the video without the need for creating a child window which indicates that the renderer does indeed create its own child window when attached.

 

If the main screen format is SCREEN_FORMAT_RGBA8888 then I don't see the video.  This suggests to me that the video window is being concealed byt the main window.  But surely the video window should appear on top of the main window that has been initialised with OpenGL?

Please use plain text.
Developer
step_jac
Posts: 89
Registered: ‎05-31-2012
My Device: BlackBerry Playbook
My Carrier: Bell

Re: OpenGL windows and video playback

In our case it appears below the OpenGL view due to the Z setting. This was desired as we render overlays on the video. You would indeed need to clear the Alpha component of the OpenGL front buffer for the video to appear.

 

Best regards,

 

Stephane

Please use plain text.