mirror of
https://github.com/raspberrypi/userland.git
synced 2025-12-06 04:49:12 +00:00
Fix for missing cleanup step for hello_videocube and hello_teapot
Fixed missing cleanup step in hello_videocube and hello_teapot, and fixed lockup when cleaning up egl_render component
This commit is contained in:
@@ -46,6 +46,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "triangle.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
#define PATH "./"
|
||||
|
||||
@@ -95,6 +97,8 @@ static CUBE_STATE_T _state, *state=&_state;
|
||||
static void* eglImage = 0;
|
||||
static pthread_t thread1;
|
||||
|
||||
extern int thread_run;
|
||||
|
||||
|
||||
/***********************************************************
|
||||
* Name: init_ogl
|
||||
@@ -416,6 +420,10 @@ static void init_textures(CUBE_STATE_T *state)
|
||||
static void exit_func(void)
|
||||
// Function to be passed to atexit().
|
||||
{
|
||||
|
||||
thread_run = 0;
|
||||
pthread_join(thread1, NULL);
|
||||
|
||||
if (eglImage != 0)
|
||||
{
|
||||
if (!eglDestroyImageKHR(state->display, (EGLImageKHR) eglImage))
|
||||
@@ -435,12 +443,20 @@ static void exit_func(void)
|
||||
printf("\ncube closed\n");
|
||||
} // exit_func()
|
||||
|
||||
void sig_handler(int signo) {
|
||||
|
||||
terminate = 1;
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
int main ()
|
||||
{
|
||||
bcm_host_init();
|
||||
printf("Note: ensure you have sufficient gpu_mem configured\n");
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
// Clear application state
|
||||
memset( state, 0, sizeof( *state ) );
|
||||
|
||||
@@ -40,13 +40,23 @@ static COMPONENT_T* egl_render = NULL;
|
||||
|
||||
static void* eglImage = 0;
|
||||
|
||||
int thread_run = 0;
|
||||
|
||||
void my_fill_buffer_done(void* data, COMPONENT_T* comp)
|
||||
{
|
||||
if (OMX_FillThisBuffer(ilclient_get_handle(egl_render), eglBuffer) != OMX_ErrorNone)
|
||||
{
|
||||
printf("OMX_FillThisBuffer failed in callback\n");
|
||||
exit(1);
|
||||
|
||||
OMX_STATETYPE state;
|
||||
|
||||
if (OMX_GetState(ILC_GET_HANDLE(egl_render), &state) != OMX_ErrorNone) {
|
||||
printf("OMX_FillThisBuffer failed while getting egl_render component state\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (state != OMX_StateExecuting)
|
||||
return;
|
||||
|
||||
if (OMX_FillThisBuffer(ilclient_get_handle(egl_render), eglBuffer) != OMX_ErrorNone)
|
||||
printf("OMX_FillThisBuffer failed in callback\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +74,7 @@ void *video_decode_test(void* arg)
|
||||
|
||||
OMX_VIDEO_PARAM_PORTFORMATTYPE format;
|
||||
OMX_TIME_CONFIG_CLOCKSTATETYPE cstate;
|
||||
OMX_ERRORTYPE omx_err;
|
||||
COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *clock = NULL;
|
||||
COMPONENT_T *list[5];
|
||||
TUNNEL_T tunnel[4];
|
||||
@@ -72,6 +83,8 @@ void *video_decode_test(void* arg)
|
||||
int status = 0;
|
||||
unsigned int data_len = 0;
|
||||
|
||||
thread_run = 1;
|
||||
|
||||
memset(list, 0, sizeof(list));
|
||||
memset(tunnel, 0, sizeof(tunnel));
|
||||
|
||||
@@ -215,6 +228,9 @@ void *video_decode_test(void* arg)
|
||||
if(!data_len)
|
||||
break;
|
||||
|
||||
if(!thread_run)
|
||||
break;
|
||||
|
||||
buf->nFilledLen = data_len;
|
||||
data_len = 0;
|
||||
|
||||
@@ -254,8 +270,22 @@ void *video_decode_test(void* arg)
|
||||
ilclient_teardown_tunnels(tunnel);
|
||||
|
||||
ilclient_state_transition(list, OMX_StateIdle);
|
||||
ilclient_state_transition(list, OMX_StateLoaded);
|
||||
|
||||
/*
|
||||
* To cleanup egl_render, we need to first disable its output port, then
|
||||
* free the output eglBuffer, and finally request the state transition
|
||||
* from to Loaded.
|
||||
*/
|
||||
omx_err = OMX_SendCommand(ILC_GET_HANDLE(egl_render), OMX_CommandPortDisable, 221, NULL);
|
||||
if (omx_err != OMX_ErrorNone)
|
||||
printf("Failed OMX_SendCommand\n");
|
||||
|
||||
omx_err = OMX_FreeBuffer(ILC_GET_HANDLE(egl_render), 221, eglBuffer);
|
||||
if(omx_err != OMX_ErrorNone)
|
||||
printf("OMX_FreeBuffer failed\n");
|
||||
|
||||
ilclient_state_transition(list, OMX_StateLoaded);
|
||||
|
||||
ilclient_cleanup_components(list);
|
||||
|
||||
OMX_Deinit();
|
||||
|
||||
@@ -46,6 +46,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "triangle.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
#define PATH "./"
|
||||
|
||||
@@ -55,7 +57,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.141592654
|
||||
#endif
|
||||
|
||||
|
||||
extern int thread_run;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -432,6 +435,10 @@ static void init_textures(CUBE_STATE_T *state)
|
||||
static void exit_func(void)
|
||||
// Function to be passed to atexit().
|
||||
{
|
||||
|
||||
thread_run = 0;
|
||||
pthread_join(thread1, NULL);
|
||||
|
||||
if (eglImage != 0)
|
||||
{
|
||||
if (!eglDestroyImageKHR(state->display, (EGLImageKHR) eglImage))
|
||||
@@ -451,6 +458,12 @@ static void exit_func(void)
|
||||
printf("\ncube closed\n");
|
||||
} // exit_func()
|
||||
|
||||
void sig_handler(int signo) {
|
||||
|
||||
terminate = 1;
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
int main ()
|
||||
@@ -460,6 +473,8 @@ int main ()
|
||||
|
||||
// Clear application state
|
||||
memset( state, 0, sizeof( *state ) );
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
// Start OGLES
|
||||
init_ogl(state);
|
||||
|
||||
@@ -40,13 +40,23 @@ static COMPONENT_T* egl_render = NULL;
|
||||
|
||||
static void* eglImage = 0;
|
||||
|
||||
int thread_run = 0;
|
||||
|
||||
void my_fill_buffer_done(void* data, COMPONENT_T* comp)
|
||||
{
|
||||
if (OMX_FillThisBuffer(ilclient_get_handle(egl_render), eglBuffer) != OMX_ErrorNone)
|
||||
{
|
||||
printf("OMX_FillThisBuffer failed in callback\n");
|
||||
exit(1);
|
||||
|
||||
OMX_STATETYPE state;
|
||||
|
||||
if (OMX_GetState(ILC_GET_HANDLE(egl_render), &state) != OMX_ErrorNone) {
|
||||
printf("OMX_FillThisBuffer failed while getting egl_render component state\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (state != OMX_StateExecuting)
|
||||
return;
|
||||
|
||||
if (OMX_FillThisBuffer(ilclient_get_handle(egl_render), eglBuffer) != OMX_ErrorNone)
|
||||
printf("OMX_FillThisBuffer failed in callback\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +74,7 @@ void *video_decode_test(void* arg)
|
||||
|
||||
OMX_VIDEO_PARAM_PORTFORMATTYPE format;
|
||||
OMX_TIME_CONFIG_CLOCKSTATETYPE cstate;
|
||||
OMX_ERRORTYPE omx_err;
|
||||
COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *clock = NULL;
|
||||
COMPONENT_T *list[5];
|
||||
TUNNEL_T tunnel[4];
|
||||
@@ -72,6 +83,8 @@ void *video_decode_test(void* arg)
|
||||
int status = 0;
|
||||
unsigned int data_len = 0;
|
||||
|
||||
thread_run = 1;
|
||||
|
||||
memset(list, 0, sizeof(list));
|
||||
memset(tunnel, 0, sizeof(tunnel));
|
||||
|
||||
@@ -215,6 +228,9 @@ void *video_decode_test(void* arg)
|
||||
if(!data_len)
|
||||
break;
|
||||
|
||||
if(!thread_run)
|
||||
break;
|
||||
|
||||
buf->nFilledLen = data_len;
|
||||
data_len = 0;
|
||||
|
||||
@@ -254,8 +270,22 @@ void *video_decode_test(void* arg)
|
||||
ilclient_teardown_tunnels(tunnel);
|
||||
|
||||
ilclient_state_transition(list, OMX_StateIdle);
|
||||
ilclient_state_transition(list, OMX_StateLoaded);
|
||||
|
||||
/*
|
||||
* To cleanup egl_render, we need to first disable its output port, then
|
||||
* free the output eglBuffer, and finally request the state transition
|
||||
* from to Loaded.
|
||||
*/
|
||||
omx_err = OMX_SendCommand(ILC_GET_HANDLE(egl_render), OMX_CommandPortDisable, 221, NULL);
|
||||
if (omx_err != OMX_ErrorNone)
|
||||
printf("Failed OMX_SendCommand\n");
|
||||
|
||||
omx_err = OMX_FreeBuffer(ILC_GET_HANDLE(egl_render), 221, eglBuffer);
|
||||
if(omx_err != OMX_ErrorNone)
|
||||
printf("OMX_FreeBuffer failed\n");
|
||||
|
||||
ilclient_state_transition(list, OMX_StateLoaded);
|
||||
|
||||
ilclient_cleanup_components(list);
|
||||
|
||||
OMX_Deinit();
|
||||
|
||||
Reference in New Issue
Block a user