20 #ifdef ENABLE_BREAKPAD
21 #include "client/linux/handler/exception_handler.h"
30 #include "wayland-client.h"
32 #define UNUSED( x ) ((void)(x))
36 struct wl_display *display;
37 struct wl_registry *registry;
38 struct wl_output *output;
41 GstElement *westerossink;
45 #ifdef ENABLE_BREAKPAD
46 static bool breakpadDumpCallback(
const google_breakpad::MinidumpDescriptor& descriptor,
50 printf(
"\nbreakpadDumpCallback: application crashed ---- Dump path: %s\n",descriptor.path());
57 static void showUsage()
60 printf(
" rne_player [options] <uri>\n" );
61 printf(
" uri - URI of video asset to play\n" );
62 printf(
"where [options] are:\n" );
63 printf(
" -? : show usage\n" );
67 static void outputHandleGeometry(
void *data,
68 struct wl_output *output,
90 static void outputHandleMode(
void *data,
91 struct wl_output *output,
100 if ( flags & WL_OUTPUT_MODE_CURRENT )
102 printf(
"outputMode: %dx%d flags %X\n", width, height, flags);
104 if ( ctx->westerossink )
106 sprintf( work,
"%d,%d,%d,%d", 0, 0, width, height );
107 g_object_set(G_OBJECT(ctx->westerossink),
"window-set", work, NULL );
112 static void outputHandleDone(
void *data,
113 struct wl_output *output )
119 static void outputHandleScale(
void *data,
120 struct wl_output *output,
128 static const struct wl_output_listener outputListener = {
129 outputHandleGeometry,
135 static void registryHandleGlobal(
void *data,
136 struct wl_registry *registry, uint32_t
id,
137 const char *interface, uint32_t version)
142 len= strlen(interface);
143 if ( (len==9) && !strncmp(interface,
"wl_output", len) ) {
144 ctx->output= (
struct wl_output*)wl_registry_bind(registry,
id, &wl_output_interface, 2);
145 wl_output_add_listener(ctx->output, &outputListener, ctx);
146 wl_display_roundtrip( ctx->display );
150 static void registryHandleGlobalRemove(
void *data,
151 struct wl_registry *registry,
159 static const struct wl_registry_listener registryListener =
161 registryHandleGlobal,
162 registryHandleGlobalRemove
165 static gboolean busCallback(GstBus *bus, GstMessage *message, gpointer data)
169 switch ( GST_MESSAGE_TYPE(message) )
171 case GST_MESSAGE_ERROR:
176 gst_message_parse_error(message, &error, &debug);
177 g_print(
"Error: %s\n", error->message);
180 g_print(
"Debug info: %s\n", debug);
184 g_main_loop_quit( ctx->loop );
187 case GST_MESSAGE_EOS:
188 g_print(
"EOS ctx %p\n", ctx );
189 g_main_loop_quit( ctx->loop );
191 case GST_MESSAGE_BUFFERING:
194 static bool triggerPlay =
false;
195 gst_message_parse_buffering (message, &percent);
196 if(percent >= 50 && !triggerPlay)
199 printf(
"50 percent buffered, going to play!\n");
200 gst_element_set_state(ctx->pipeline, GST_STATE_PLAYING);
211 static void cb_playbin_source_setup( GObject *obj )
213 const char* rne_proxy = getenv(
"RNE_PROXY");
214 GObject *source_element;
216 if( g_object_class_find_property( G_OBJECT_GET_CLASS( obj ),
"source" ) )
219 g_object_get(obj,
"source", &source_element, NULL);
221 if( NULL != rne_proxy )
223 printf(
"The proxy is %s\n", rne_proxy );
224 if( g_object_class_find_property ( G_OBJECT_GET_CLASS( source_element ),
"proxy" ) )
226 g_object_set( G_OBJECT( source_element ),
"proxy", rne_proxy, NULL );
230 if( g_object_class_find_property ( G_OBJECT_GET_CLASS( source_element ),
"ssl-strict" ) )
232 g_object_set( G_OBJECT( source_element ),
"ssl-strict", FALSE , NULL );
234 g_object_unref( source_element );
238 bool createPipeline(
AppCtx *ctx )
243 gint64 bufferDuration = 10 * GST_SECOND;
245 gst_init( &argc, &argv );
247 ctx->pipeline= gst_pipeline_new(
"pipeline");
248 if ( !ctx->pipeline )
250 printf(
"Error: unable to create pipeline instance\n" );
254 ctx->bus= gst_pipeline_get_bus( GST_PIPELINE(ctx->pipeline) );
257 printf(
"Error: unable to get pipeline bus\n");
260 gst_bus_add_watch( ctx->bus, busCallback, ctx );
262 ctx->player= gst_element_factory_make(
"playbin",
"player" );
263 g_object_set(G_OBJECT(ctx->player),
"buffer-duration",bufferDuration,NULL);
267 printf(
"Error: unable to create playbin instance\n" );
270 gst_object_ref( ctx->player );
272 ctx->westerossink= gst_element_factory_make(
"westerossink",
"vsink" );
273 if ( !ctx->westerossink )
275 printf(
"Error: unable to create westerossink instance\n" );
278 gst_object_ref( ctx->westerossink );
280 g_object_set(G_OBJECT(ctx->player),
"video-sink", ctx->westerossink, NULL );
283 if( g_object_class_find_property( G_OBJECT_GET_CLASS( ctx->westerossink ),
"secure-video" ) )
285 g_object_set( G_OBJECT( ctx->westerossink ),
"secure-video",
true, NULL );
288 if ( !gst_bin_add( GST_BIN(ctx->pipeline), ctx->player) )
290 printf(
"Error: unable to add playbin to pipeline\n");
294 g_signal_connect( G_OBJECT( ctx->player ),
"source-setup", G_CALLBACK( cb_playbin_source_setup ), NULL );
303 void destroyPipeline(
AppCtx *ctx )
307 gst_element_set_state(ctx->pipeline, GST_STATE_NULL);
309 if ( ctx->westerossink )
311 gst_object_unref( ctx->westerossink );
312 ctx->westerossink= 0;
316 gst_object_unref( ctx->player );
321 gst_object_unref( ctx->bus );
326 gst_object_unref( GST_OBJECT(ctx->pipeline) );
333 static void signalHandler(
int signum)
335 printf(
"signalHandler: signum %d\n", signum);
338 g_main_loop_quit( g_ctx->loop );
343 int main(
int argc,
char **argv )
347 const char *uri=
"http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_h264.mov";
349 struct sigaction sigint;
350 #ifdef ENABLE_BREAKPAD
351 google_breakpad::MinidumpDescriptor descriptor(
"/tmp");
352 google_breakpad::ExceptionHandler eh(descriptor, NULL, breakpadDumpCallback, NULL,
true, -1);
354 printf(
"rne_player: v1.0\n\n" );
363 while ( argidx < argc )
365 if ( argv[argidx][0] ==
'-' )
367 switch( argv[argidx][1] )
373 printf(
"unknown option %s\n\n", argv[argidx] );
398 printf(
"missing uri argument\n" );
402 printf(
"playing asset: %s\n", uri );
407 printf(
"Error: unable to allocate application context\n");
411 ctx->display= wl_display_connect( NULL );
414 printf(
"Error: unable to open default wayland display\n");
417 ctx->registry= wl_display_get_registry(ctx->display);
418 if ( !ctx->registry )
420 printf(
"Error: unable to get wayland registry\n");
423 wl_registry_add_listener(ctx->registry, ®istryListener, ctx);
424 wl_display_roundtrip(ctx->display);
426 if ( createPipeline( ctx ) )
428 printf(
"pipeline created\n");
429 ctx->loop= g_main_loop_new(NULL,FALSE);
433 g_object_set(G_OBJECT(ctx->player),
"uri", uri, NULL );
435 if ( GST_STATE_CHANGE_FAILURE != gst_element_set_state(ctx->pipeline, GST_STATE_PAUSED) )
437 sigint.sa_handler = signalHandler;
438 sigemptyset(&sigint.sa_mask);
439 sigint.sa_flags = SA_RESETHAND;
440 sigaction(SIGINT, &sigint, NULL);
444 g_main_loop_run( ctx->loop );
449 printf(
"Error: unable to create main loop\n");
454 printf(
"Error: unable to create player pipeline\n" );
466 wl_output_destroy( ctx->output );
472 wl_registry_destroy(ctx->registry);
478 wl_display_disconnect(ctx->display);
482 destroyPipeline( ctx );
486 g_main_loop_unref(ctx->loop);