a328bde13d32c5427b98dfe04337898ce9ac2031
[AGL/meta-agl.git] /
1 From 0db59bf629def81fe9925fa435ec845e2069dd4b Mon Sep 17 00:00:00 2001
2 From: Wataru Mizuno <wmizuno@jp.adit-jv.com>
3 Date: Wed, 11 Apr 2018 12:19:58 +0900
4 Subject: [PATCH] transmitter: introduce waltham-renderer
5
6 The waltham-renderer creates and sends buffer for remote site.
7 This is using gst-recorder APIs.
8
9 Signed-off-by: Wataru Mizuno <wmizuno@jp.adit-jv.com>
10 ---
11  Makefile.am                    |  12 +++
12  transmitter/README             |  86 +++++++++++----------
13  transmitter/input.c            |   2 +-
14  transmitter/output.c           | 104 ++++++++++++++------------
15  transmitter/plugin.c           |  45 ++++++-----
16  transmitter/plugin.h           |   6 +-
17  transmitter/transmitter_api.h  |   9 +++
18  transmitter/waltham-renderer.c | 166 +++++++++++++++++++++++++++++++++++++++++
19  transmitter/waltham-renderer.h |  33 ++++++++
20  9 files changed, 347 insertions(+), 116 deletions(-)
21  create mode 100644 transmitter/waltham-renderer.c
22  create mode 100644 transmitter/waltham-renderer.h
23
24 diff --git a/Makefile.am b/Makefile.am
25 index 2cb1920..0af66d6 100644
26 --- a/Makefile.am
27 +++ b/Makefile.am
28 @@ -526,6 +526,18 @@ transmitter_la_SOURCES =                   \
29         shared/timespec-util.h                  \
30         shared/zalloc.h                         \
31         src/compositor.h
32 +
33 +module_LTLIBRARIES += waltham-renderer.la
34 +waltham_renderer_la_LDFLAGS = -module -avoid-version
35 +waltham_renderer_la_CFLAGS =                           \
36 +       $(COMPOSITOR_CFLAGS)                    \
37 +       $(AM_CFLAGS)                            \
38 +       $(WALTHAM_CFLAGS)
39 +waltham_renderer_la_LIBADD = $(COMPOSITOR_LIBS) \
40 +                            -lwaltham
41 +waltham_renderer_la_SOURCES =                  \
42 +       transmitter/waltham-renderer.c          \
43 +       transmitter/waltham-renderer.h
44  endif
45  
46  noinst_PROGRAMS += spring-tool
47 diff --git a/transmitter/README b/transmitter/README
48 index af80574..345142d 100644
49 --- a/transmitter/README
50 +++ b/transmitter/README
51 @@ -1,4 +1,4 @@
52 -Transmitter plugin 
53 +Transmitter plugin
54  
55  The current implementation of Transmitter is a stub which interfaces to
56  other Weston parts appropriately, but all networking is just a mockup.
57 @@ -15,8 +15,8 @@ plugin.
58  
59  How to write weston.ini
60  =======================
61 -To load transmitter plugin to weston, add 'transmitter.so' to the 'modules' 
62 -key under '[core]', and make sure the 'shell' is 'ivi-shell.so'. 
63 +To load transmitter plugin to weston, add 'transmitter.so' to the 'modules'
64 +key under '[core]', and make sure the 'shell' is 'ivi-shell.so'.
65  
66  The destination of remoting is configured in weston.ini.
67  Add output name, server address, port number, output's width and height key
68 @@ -27,57 +27,66 @@ In details, see 'weston.ini.transmitter'.
69  
70  How to test
71  ===========
72 -You can use server side test application in waltham repository.
73 +You can use server side test application in waltham-server directory.
74  
75  If you set 'WALTHAM_DEBUG=1' to your environment valuable, you can
76  see the log like this:
77  
78 - [06:12:41.238] Loading module '/usr/lib64/weston/ivi-shell.so'
79 - [06:12:41.245] launching '/usr/libexec/weston-keyboard'
80 - [06:12:41.247] Loading module '/usr/lib64/weston/ivi-controller.so'
81 - [06:12:41.252] Loading module '/usr/lib64/weston/ivi-input-controller.so'
82 - [06:12:41.253] ivi-input-controller module loaded successfully!
83 - [06:12:41.255] Loading module '/usr/lib64/weston/transmitter.so'
84 - [06:12:41.260] Registered plugin API 'transmitter_v1' of size 88
85 - [06:12:41.260] Registered plugin API 'transmitter_ivi_v1' of size 16
86 - [06:12:41.260] Transmitter initialized.
87 - [06:12:41.260] ivi-layout: Transmitter enabled.
88 - [06:12:41.260] Transmitter weston_seat 0x14f8010
89 - [06:12:41.260] Transmitter created pointer=0x139a440 for seat 0x14f8010
90 - [06:12:41.261] Transmitter created keyboard=0x14f8160 for seat 0x14f8010
91 - [06:12:41.261] Transmitter created touch=0x1508750 for seat 0x14f8010
92 + [13:24:08.345] Loading module '/usr/lib64/weston/transmitter.so'
93 + [13:24:08.345] Registered plugin API 'transmitter_v1' of size 88
94 + [13:24:08.345] Registered plugin API 'transmitter_ivi_v1' of size 16
95 + [13:24:08.345] Transmitter initialized.
96 + [13:24:08.345] Loading module '/usr/lib64/libweston-2/waltham-renderer.so'
97 + [13:24:08.352] gst-setting are :-->
98 + [13:24:08.352] ip = 192.168.2.52
99 + [13:24:08.352] port = 34400
100 + [13:24:08.352] bitrate = 3000000
101 + [13:24:08.352] crop = 384 x 368
102 + [13:24:08.352] width = 1920
103 + [13:24:08.352] width = 1080
104 + [13:24:08.531] open media device: platform:fe960000.vsp (fe960000.vsp)
105 + [13:24:08.532] input pad setup ('fe960000.vsp rpf.0 input':'/dev/video0')
106 + [13:24:08.533] output pad setup (fe960000.vsp wpf.0 output:/dev/video5)
107 + [13:24:08.533] vsp-device '/dev/media0' created
108 + [13:24:08.533] gst_recorder_create (1920x1080) crop 384x368 at 0,0
109 + [13:24:08.533] gst_pipeline: starting: appsrc name=src ! omxh264enc target-bitrate=3000000 control-rate=2 no-copy=k
110 + [13:24:08.582] goot 1 pools
111 + [13:24:08.583]  pool settings size 211968, min 5, max 5
112 + [13:24:08.583] gst_recorder_create done
113 + [13:24:08.583] [gst recorder] transmitter-192.168.2.52:34400-1: recorder initialized
114 + [13:24:08.583] Transmitter weston_seat 0x15424630
115 + [13:24:08.583] Transmitter created pointer=0x15625df0 for seat 0x15424630
116 + [13:24:08.583] Transmitter created keyboard=0x154247c0 for seat 0x15424630
117 + [13:24:08.583] Transmitter created touch=0x15625f10 for seat 0x15424630
118  
119  The connection is established, you can see following debug messages:
120  
121 - root@gr-mrb-64:~# debug: wth_connection_insert_new_object: new object id: 1
122 + debug: wth_connection_insert_new_object: new object id: 1
123   debug: wth_connection_insert_new_object: new object id: 2
124 - 2017-07-19T06:14:31Z 00001000030000000100000002000000 wth_display_get_registry
125 + 2018-01-09T13:24:22Z 00001000030000000100000002000000 wth_display_get_registry
126   debug: wth_connection_insert_new_object: new object id: 3
127 - 2017-07-19T06:14:31Z 00001000020000000100000003000000 wth_display_sync
128 - debug: Message received on conn 0x1560340: (9) 40 bytes
129 + 2018-01-09T13:24:22Z 00001000020000000100000003000000 wth_display_sync
130 + debug: Message received on conn 0x15572730: (9) 40 bytes
131   debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
132   debug: wth_connection_insert_new_object: new object id: 4
133 - 2017-07-19T06:14:31Z 00002c000800000002000000010000000400000010000000777468705f636f6d706f7369746f720001000000 wthp_registry_bind
134 - debug: Message received on conn 0x1560340: (9) 44 bytes
135 - debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
136 - debug: wth_connection_insert_new_object: new object id: 5
137 - 2017-07-19T06:14:31Z 000030000800000002000000010000000500000012000000777468705f626c6f625f666163746f72790001000000 wthp_registry_bind
138 - debug: Message received on conn 0x1560340: (9) 48 bytes
139 + 2018-01-09T13:24:22Z 00002c000800000002000000010000000400000010000000777468705f636f6d706f7369746f720001000000 wthpd
140 + debug: Message received on conn 0x15572730: (9) 48 bytes
141   debug: wthp_registry_send_global(2, 1, [variable type const char *], 1) (opcode 9) called.
142 + debug: wth_connection_insert_new_object: new object id: 5
143 + 2018-01-09T13:24:22Z 000034000800000002000000010000000500000015000000777468705f6976695f6170706c69636174696f6e00010d
144 + debug: Message received on conn 0x15572730: (9) 44 bytes
145 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
146   debug: wth_connection_insert_new_object: new object id: 6
147 - 2017-07-19T06:14:31Z 000034000800000002000000010000000600000015000000777468705f6976695f6170706c69636174696f6e0001000000 wthp_registry_bind
148 - debug: Message received on conn 0x1560340: (11) 16 bytes
149 - debug: wthp_callback_send_done(3, 0) (opcode 11) called.
150 - sending wth_display.sync...
151 + 2018-01-09T13:24:22Z 000030000800000002000000010000000600000012000000777468705f626c6f625f666163746f72790001000000 d
152 + debug: Message received on conn 0x15572730: (9) 36 bytes
153 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
154   debug: wth_connection_insert_new_object: new object id: 7
155 - 2017-07-19T06:14:31Z 00001000020000000100000007000000 wth_display_sync
156 - debug: Message received on conn 0x1560340: (11) 16 bytes
157 - debug: wthp_callback_send_done(7, 0) (opcode 11) called.
158 - ...sync done.
159 + 2018-01-09T13:24:22Z 00002800080000000200000001000000070000000a000000777468705f736561740001000000 wthp_registry_bid
160 + debug: Message received on conn 0x15572730: (11) 16 bytes
161 + debug: wthp_callback_send_done(3, 0) (opcode 11) called.
162  
163  Start remoting :
164  - Start an IVI application.
165 -- Put surface on backend output
166  - Put surface on transmitter output
167  
168  Weston log will indicate remoting has started:
169 @@ -85,5 +94,4 @@ Weston log will indicate remoting has started:
170  [13:18:24.572] HMI transmitting surface 0x1c3dad0, ivi-id 0x9ff6
171  [13:18:24.572] Transmitter: update surface 0x1c3dad0 (0, 0), 0 cb
172  [13:18:24.572] transmitter_surface_set_ivi_id(0x1c3dad0, 0x9ff6)
173 -[13:18:24.972] Transmitter: surface 0x1c3dad0 entered output transmitter-0.0.0.0:66-1
174 -
175 +[13:18:24.972] Transmitter: surface 0x1c3dad0 entered output transmitter-0.0.0.0:66-1
176 \ No newline at end of file
177 diff --git a/transmitter/input.c b/transmitter/input.c
178 index 6797b6e..e00546b 100644
179 --- a/transmitter/input.c
180 +++ b/transmitter/input.c
181 @@ -964,7 +964,7 @@ keyboard_handle_enter(struct wthp_keyboard *wthp_keyboard,
182         wl_key->size = keys->size;
183         wl_key->alloc = keys->alloc;
184         wl_key->data = keys->data;
185 -       
186 +
187         seat = wl_container_of(seat_list->next, seat, link);
188  
189         wl_list_for_each(txs, &remote->surface_list, link)
190 diff --git a/transmitter/output.c b/transmitter/output.c
191 index 003056f..2cca781 100644
192 --- a/transmitter/output.c
193 +++ b/transmitter/output.c
194 @@ -28,9 +28,12 @@
195  #include <string.h>
196  
197  #include "compositor.h"
198 +#include "compositor-drm.h"
199 +#include "plugin-registry.h"
200  
201  #include "plugin.h"
202  #include "transmitter_api.h"
203 +#include "waltham-renderer.h"
204  
205  /** @file
206   *
207 @@ -59,6 +62,8 @@
208   * exclusive with weston_compositor_add_output().
209   */
210  
211 +static struct waltham_renderer_interface *waltham_renderer;
212 +
213  static char *
214  make_model(struct weston_transmitter_remote *remote, int name)
215  {
216 @@ -146,45 +151,26 @@ transmitter_start_repaint_loop(struct weston_output *base)
217  }
218  
219  static int
220 -transmitter_check_output(struct weston_transmitter_surface *txs,
221 -                        struct weston_compositor *compositor)
222 -{
223 -       struct weston_output *def_output = wl_container_of(compositor->output_list.next,
224 -                                                       def_output, link);
225 -       struct weston_view *view;
226 -
227 -       wl_list_for_each_reverse(view, &compositor->view_list, link) {
228 -               if (view->output == def_output) {
229 -                       if (view->surface == txs->surface)
230 -                               return 1;
231 -               }
232 -       }
233 -
234 -       return 0;
235 -}
236 -
237 -static int
238  transmitter_output_repaint(struct weston_output *base,
239                            pixman_region32_t *damage)
240  {
241         struct weston_transmitter_output* output = wl_container_of(base, output, base);
242         struct weston_transmitter_remote* remote = output->remote;
243         struct weston_transmitter* txr = remote->transmitter;
244 -       struct weston_transmitter_api* transmitter_api = 
245 +       struct weston_transmitter_api* transmitter_api =
246                 weston_get_transmitter_api(txr->compositor);
247         struct weston_transmitter_surface* txs;
248         struct weston_compositor *compositor = base->compositor;
249         struct weston_view *view;
250         bool found_output = false;
251 +       struct timespec ts;
252  
253 -       if (!output->from_frame_signal)
254 -               return 0;
255 -
256 -       output->from_frame_signal = false;
257 +       struct weston_drm_output_api *api =
258 +               weston_plugin_api_get(txr->compositor,  WESTON_DRM_OUTPUT_API_NAME, sizeof(api));
259  
260 -       /* 
261 +       /*
262          * Pick up weston_view in transmitter_output and check weston_view's surface
263 -        * If the surface hasn't been conbined to weston_transmitter_surface, 
264 +        * If the surface hasn't been conbined to weston_transmitter_surface,
265          * then call push_to_remote.
266          * If the surface has already been combined, call gather_state.
267          */
268 @@ -201,24 +187,34 @@ transmitter_output_repaint(struct weston_output *base,
269                         wl_list_for_each(txs, &remote->surface_list, link) {
270                                 if (txs->surface == view->surface) {
271                                         found_surface = true;
272 -                                       if (!transmitter_check_output(txs, compositor))
273 -                                               break;
274 -
275                                         if (!txs->wthp_surf)
276                                                 transmitter_api->surface_push_to_remote
277                                                         (view->surface, remote, NULL);
278 +
279 +                                       output->renderer->dmafd =
280 +                                               api->get_dma_fd_from_view(&output->base, view);
281 +                                       if(!output->renderer->dmafd) {
282 +                                               weston_log("Failed to get dmafd\n");
283 +                                               goto out;
284 +                                       }
285 +                                       output->renderer->repaint_output(output);
286 +                                       output->renderer->dmafd = NULL;
287                                         transmitter_api->surface_gather_state(txs);
288 +                                       weston_buffer_reference(&view->surface->buffer_ref, NULL);
289                                         break;
290                                 }
291                         }
292                         if (!found_surface)
293 -                               transmitter_api->surface_push_to_remote(view->surface, 
294 +                               transmitter_api->surface_push_to_remote(view->surface,
295                                                                         remote, NULL);
296                 }
297         }
298         if (!found_output)
299                 goto out;
300  
301 +       weston_compositor_read_presentation_clock(output->base.compositor, &ts);
302 +       weston_output_finish_frame(&output->base, &ts, 0);
303 +
304         return 0;
305  
306  out:
307 @@ -228,28 +224,38 @@ out:
308  }
309  
310  static void
311 +transmitter_assign_planes(struct weston_output *base) {
312 +       /*
313 +        * This function prevents compositor releasing buffer early.
314 +        */
315 +       struct weston_transmitter_output* output = wl_container_of(base, output, base);
316 +       struct weston_transmitter_remote* remote = output->remote;
317 +       struct weston_transmitter_surface* txs;
318 +       struct weston_compositor *compositor = base->compositor;
319 +       struct weston_view *view;
320 +
321 +       wl_list_for_each_reverse(view, &compositor->view_list, link) {
322 +               if (view->output == &output->base) {
323 +                       wl_list_for_each(txs, &remote->surface_list, link) {
324 +                               if (txs->surface == view->surface)
325 +                                       view->surface->keep_buffer = true;
326 +
327 +                       }
328 +               }
329 +       }
330 +}
331 +
332 +static void
333  transmitter_output_enable(struct weston_output *base)
334  {
335         struct weston_transmitter_output *output = wl_container_of(base, output, base);
336  
337 -       output->base.assign_planes = NULL;
338 +       output->base.assign_planes = transmitter_assign_planes;
339         output->base.set_backlight = NULL;
340         output->base.set_dpms = NULL;
341         output->base.switch_mode = NULL;
342  }
343  
344 -static void
345 -transmitter_output_frame_handler(struct wl_listener *listener, void *data)
346 -{
347 -       struct weston_transmitter_output *output;
348 -       int ret;
349 -
350 -       output = wl_container_of(listener, output, frame_listener);
351 -       output->from_frame_signal = true;
352 -
353 -       ret = transmitter_output_repaint(&output->base, NULL);
354 -}
355 -
356  int
357  transmitter_remote_create_output(struct weston_transmitter_remote *remote,
358                                  const struct weston_transmitter_output_info *info)
359 @@ -312,13 +318,15 @@ transmitter_remote_create_output(struct weston_transmitter_remote *remote,
360         output->remote = remote;
361         wl_list_insert(&remote->output_list, &output->link);
362  
363 -       weston_output_enable(&output->base);
364 +       /* Loading a waltham renderer library */
365 +       waltham_renderer = weston_load_module("waltham-renderer.so","waltham_renderer_interface");
366 +
367 +       if (waltham_renderer->display_create(output) < 0) {
368 +               weston_log("Failed to create waltham renderer display \n");
369 +               return -1;
370 +       }
371  
372 -       output->frame_listener.notify = transmitter_output_frame_handler;
373 -       def_output = wl_container_of(txr->compositor->output_list.next,
374 -                                 def_output, link);
375 -       wl_signal_add(&def_output->frame_signal, &output->frame_listener);
376 -       output->from_frame_signal = false;
377 +       weston_output_enable(&output->base);
378  
379         return 0;
380  
381 diff --git a/transmitter/plugin.c b/transmitter/plugin.c
382 index 1f00f33..faf28b5 100644
383 --- a/transmitter/plugin.c
384 +++ b/transmitter/plugin.c
385 @@ -121,20 +121,20 @@ transmitter_surface_gather_state(struct weston_transmitter_surface *txs)
386         else {
387                 /* TODO: transmit surface state to remote */
388                 /* The buffer must be transmitted to remote side */
389 -               
390 +
391                 /* waltham */
392                 struct weston_surface *surf = txs->surface;
393                 struct weston_compositor *comp = surf->compositor;
394                 int32_t stride, data_sz, width, height;
395                 void *data;
396 -               
397 +
398                 width = 1;
399                 height = 1;
400                 stride = width * (PIXMAN_FORMAT_BPP(comp->read_format) / 8);
401 -               
402 +
403                 data = malloc(stride * height);
404                 data_sz = stride * height;
405 -               
406 +
407                 /* fake sending buffer */
408                 txs->wthp_buf = wthp_blob_factory_create_buffer(remote->display->blob_factory,
409                                                                 data_sz,
410 @@ -143,13 +143,13 @@ transmitter_surface_gather_state(struct weston_transmitter_surface *txs)
411                                                                 surf->height,
412                                                                 stride,
413                                                                 PIXMAN_FORMAT_BPP(comp->read_format));
414 -               
415 +
416                 wthp_buffer_set_listener(txs->wthp_buf, &buffer_listener, txs);
417 -               
418 +
419                 wthp_surface_attach(txs->wthp_surf, txs->wthp_buf, txs->attach_dx, txs->attach_dy);
420                 wthp_surface_damage(txs->wthp_surf, txs->attach_dx, txs->attach_dy, surf->width, surf->height);
421                 wthp_surface_commit(txs->wthp_surf);
422 -               
423 +
424                 wth_connection_flush(remote->display->connection);
425                 txs->attach_dx = 0;
426                 txs->attach_dy = 0;
427 @@ -255,7 +255,7 @@ transmitter_surface_set_ivi_id(struct weston_transmitter_surface *txs)
428                                 weston_log("no content in seat object\n");
429                         if(!dpy->application)
430                                 weston_log("no content in ivi-application object\n");
431 -                       
432 +
433                         txs->wthp_ivi_surface = wthp_ivi_application_surface_create
434                                 (dpy->application, ivi_surf->id_surface,  txs->wthp_surf);
435                         weston_log("surface ID %d\n", ivi_surf->id_surface);
436 @@ -313,7 +313,7 @@ transmitter_surface_push_to_remote(struct weston_surface *ws,
437                 wl_list_init(&txs->frame_callback_list);
438                 wl_list_init(&txs->feedback_list);
439  
440 -               txs->lyt = weston_plugin_api_get(txr->compositor, 
441 +               txs->lyt = weston_plugin_api_get(txr->compositor,
442                                                  IVI_LAYOUT_API_NAME, sizeof(txs->lyt));
443         }
444  
445 @@ -351,15 +351,15 @@ registry_handle_global(struct wthp_registry *registry,
446         struct waltham_display *dpy = wth_object_get_user_data((struct wth_object *)registry);
447  
448         if (strcmp(interface, "wthp_compositor") == 0) {
449 -               assert(!dpy->compositor); 
450 +               assert(!dpy->compositor);
451                 dpy->compositor = (struct wthp_compositor *)wthp_registry_bind(registry, name, interface, 1);
452                 /* has no events to handle */
453         } else if (strcmp(interface, "wthp_blob_factory") == 0) {
454 -               assert(!dpy->blob_factory); 
455 +               assert(!dpy->blob_factory);
456                 dpy->blob_factory = (struct wthp_blob_factory *)wthp_registry_bind(registry, name, interface, 1);
457                 /* has no events to handle */
458         } else if (strcmp(interface, "wthp_seat") == 0) {
459 -               assert(!dpy->seat); 
460 +               assert(!dpy->seat);
461                 dpy->seat = (struct wthp_seat *)wthp_registry_bind(registry, name, interface, 1);
462                 wthp_seat_set_listener(dpy->seat, &seat_listener, dpy);
463         } else if (strcmp(interface, "wthp_ivi_application") == 0) {
464 @@ -486,13 +486,13 @@ waltham_mainloop(int fd, uint32_t mask, void *data)
465         w = &dpy->conn_watch;
466         if (!dpy)
467                 goto not_running;
468 -       
469 +
470         if (!dpy->connection)
471                 dpy->running = false;
472  
473         if (!dpy->running)
474                 goto not_running;
475 -       
476 +
477         running_display++;
478         /* Dispatch queued events. */
479         ret = wth_connection_dispatch(dpy->connection);
480 @@ -505,7 +505,7 @@ waltham_mainloop(int fd, uint32_t mask, void *data)
481  
482         /* Run any application idle tasks at this point. */
483         /* (nothing to run so far) */
484 -       
485 +
486         /* Flush out buffered requests. If the Waltham socket is
487          * full, poll it for writable too, and continue flushing then.
488          */
489 @@ -570,9 +570,6 @@ waltham_client_init(struct waltham_display *dpy)
490                 return -1;
491         }
492  
493 -       /* A one-off asynchronous roundtrip, just for fun. */
494 -       weston_log("sending wth_display.sync...\n");
495 -
496         dpy->running = true;
497  
498         return 0;
499 @@ -586,7 +583,7 @@ establish_timer_handler(void *data)
500  
501         ret = waltham_client_init(remote->display);
502         if(ret == -2) {
503 -               wl_event_source_timer_update(remote->establish_timer, 
504 +               wl_event_source_timer_update(remote->establish_timer,
505                                              ESTABLISH_CONNECTION_PERIOD);
506                 return 0;
507         }
508 @@ -631,13 +628,13 @@ retry_timer_handler(void *data)
509                 registry_handle_global_remove(dpy->registry, 1);
510                 init_globals(dpy);
511                 disconnect_surface(remote);
512 -               wl_event_source_timer_update(remote->establish_timer, 
513 +               wl_event_source_timer_update(remote->establish_timer,
514                                              ESTABLISH_CONNECTION_PERIOD);
515  
516                 return 0;
517         }
518         else
519 -               wl_event_source_timer_update(remote->retry_timer, 
520 +               wl_event_source_timer_update(remote->retry_timer,
521                                              RETRY_CONNECTION_PERIOD);
522         return 0;
523  }
524 @@ -648,7 +645,7 @@ transmitter_connect_to_remote(struct weston_transmitter *txr)
525         struct weston_transmitter_remote *remote;
526         struct wl_event_loop *loop_est, *loop_retry;
527         int ret;
528 -       
529 +
530         wl_list_for_each_reverse(remote, &txr->remote_list, link) {
531                 /* XXX: actually start connecting */
532                 /* waltham */
533 @@ -658,12 +655,12 @@ transmitter_connect_to_remote(struct weston_transmitter *txr)
534                 remote->display->remote = remote;
535                 /* set connection establish timer */
536                 loop_est = wl_display_get_event_loop(txr->compositor->wl_display);
537 -               remote->establish_timer = 
538 +               remote->establish_timer =
539                         wl_event_loop_add_timer(loop_est, establish_timer_handler, remote);
540                 wl_event_source_timer_update(remote->establish_timer, 1);
541                 /* set connection retry timer */
542                 loop_retry = wl_display_get_event_loop(txr->compositor->wl_display);
543 -               remote->retry_timer = 
544 +               remote->retry_timer =
545                         wl_event_loop_add_timer(loop_retry, retry_timer_handler, remote);
546                 if (ret < 0) {
547                         weston_log("Fatal: Transmitter waltham connecting failed.\n");
548 diff --git a/transmitter/plugin.h b/transmitter/plugin.h
549 index 116c1f6..ec776fa 100644
550 --- a/transmitter/plugin.h
551 +++ b/transmitter/plugin.h
552 @@ -59,7 +59,7 @@ enum wthp_seat_capability {
553  };
554  
555  /* epoll structure */
556 -struct watch { 
557 +struct watch {
558         struct waltham_display *display;
559         int fd;
560         void (*cb)(struct watch *w, uint32_t events);
561 @@ -198,9 +198,7 @@ struct weston_transmitter_output {
562         struct frame *frame;
563  
564         struct wl_callback *frame_cb;
565 -       struct wl_listener frame_listener;
566 -
567 -       bool from_frame_signal;
568 +       struct renderer *renderer;
569  };
570  
571  struct weston_transmitter_seat {
572 diff --git a/transmitter/transmitter_api.h b/transmitter/transmitter_api.h
573 index 4a660a0..c473256 100644
574 --- a/transmitter/transmitter_api.h
575 +++ b/transmitter/transmitter_api.h
576 @@ -265,4 +265,13 @@ weston_get_transmitter_ivi_api(struct weston_compositor *compositor)
577  
578  /* Remote compositor/output are identified by model */
579  
580 +
581 +struct renderer {
582 +       void (*repaint_output)(struct weston_output *base);
583 +       struct gst_recorder *recorder;  /* gst-recorder instance */
584 +       int32_t dmafd;    /* dmafd received from compositor-drm */
585 +       int surface_width;
586 +       int surface_height;
587 +};
588 +
589  #endif /* WESTON_TRANSMITTER_API_H */
590 diff --git a/transmitter/waltham-renderer.c b/transmitter/waltham-renderer.c
591 new file mode 100644
592 index 0000000..f9e4e21
593 --- /dev/null
594 +++ b/transmitter/waltham-renderer.c
595 @@ -0,0 +1,166 @@
596 +/*
597 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
598 + *
599 + * Permission is hereby granted, free of charge, to any person obtaining
600 + * a copy of this software and associated documentation files (the
601 + * "Software"), to deal in the Software without restriction, including
602 + * without limitation the rights to use, copy, modify, merge, publish,
603 + * distribute, sublicense, and/or sell copies of the Software, and to
604 + * permit persons to whom the Software is furnished to do so, subject to
605 + * the following conditions:
606 + *
607 + * The above copyright notice and this permission notice (including the
608 + * next paragraph) shall be included in all copies or substantial
609 + * portions of the Software.
610 + *
611 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
612 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
613 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
614 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
615 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
616 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
617 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
618 + * SOFTWARE.
619 + */
620 +
621 +#include <stdlib.h>
622 +#include <assert.h>
623 +#include <string.h>
624 +
625 +#include "compositor.h"
626 +#include "libweston/gst-recorder.h"
627 +
628 +#include "transmitter_api.h"
629 +#include "waltham-renderer.h"
630 +#include "plugin.h"
631 +
632 +struct waltham_renderer {
633 +       struct renderer base;
634 +};
635 +
636 +static void
637 +recorder_frame_notify(struct weston_transmitter_output* output)
638 +{
639 +       gst_recorder_frame_dmafd(output->renderer->recorder, output->renderer->dmafd,
640 +                               output->renderer->surface_width*4);
641 +}
642 +
643 +static int parse_crop_rect(const char *s, struct v4l2_rect* crop)
644 +{
645 +       crop->left = 0;
646 +       crop->top = 0;
647 +       crop->width = 0;
648 +       crop->height = 0;
649 +
650 +       if (sscanf(s, "%dx%d@%dx%d",
651 +                  &crop->width,
652 +                  &crop->height,
653 +                  &crop->top,
654 +                  &crop->left) != 4)
655 +               return -1;
656 +
657 +       return 0;
658 +}
659 +
660 +static int
661 +recorder_enable(struct weston_transmitter_output *output)
662 +{
663 +       int enable_recorder = 0;
664 +       struct gst_recorder_settings *settings;
665 +       struct weston_config_section *section;
666 +
667 +       struct weston_output* base = &output->base;
668 +       struct weston_compositor *compositor = base->compositor;
669 +       struct weston_transmitter_remote* remote = output->remote;
670 +
671 +       /*
672 +        * Limitation:
673 +        * Hard coding bitrate and crop params.
674 +        * In case of gst-recorder case these were taken from weston.ini
675 +        */
676 +       int32_t bitrate = 3000000;
677 +       char *crop_params = "384x368@0x0";
678 +
679 +       struct v4l2_rect crop = { .width = output->base.current_mode->width,
680 +                                 .height = output->base.current_mode->height,
681 +                                 .top = 0,
682 +                                 .left = 0 };
683 +
684 +       if (output->renderer->recorder)
685 +               return -1;
686 +
687 +       settings = malloc(sizeof(* settings));
688 +       settings->ip = remote->addr;
689 +
690 +       settings->port = atoi(remote->port);
691 +
692 +       settings->bitrate = bitrate;
693 +       settings->width = output->base.current_mode->width;
694 +       settings->height = output->base.current_mode->height;
695 +
696 +       settings->crop = crop;
697 +
698 +       if (parse_crop_rect(crop_params, &settings->crop)) {
699 +                       weston_log("[gst recorder] %s:"
700 +                                  " failed to parse crop parameter\n",
701 +                                  output->base.name);
702 +                       goto err;
703 +               }
704 +
705 +       weston_log("gst-setting are :-->\n");
706 +       weston_log("ip = %s \n",settings->ip);
707 +       weston_log("port = %d \n",settings->port);
708 +       weston_log("bitrate = %d \n",settings->bitrate);
709 +       weston_log("crop = %d x %d \n",settings->crop.width,settings->crop.height);
710 +       weston_log("width = %d \n",settings->width);
711 +       weston_log("width = %d \n",settings->height);
712 +
713 +
714 +       gst_recorder_init();
715 +
716 +       output->renderer->recorder =
717 +               gst_recorder_create(settings);
718 +       if (!output->renderer->recorder) {
719 +               weston_log("[gst recorder] %s:"
720 +                       " failed to create gst recorder\n",
721 +                       output->base.name);
722 +               goto err;
723 +       }
724 +
725 +       weston_log("[gst recorder] %s:"
726 +               " recorder initialized\n",
727 +               output->base.name);
728 +
729 +       return 0;
730 +err:
731 +       weston_log("[gst recorder] %s:"
732 +               " invalid settings\n",
733 +               output->base.name);
734 +       free(settings);
735 +       return -1;
736 +}
737 +
738 +static void waltham_renderer_repaint_output(struct weston_transmitter_output *output)
739 +{
740 +       recorder_frame_notify(output);
741 +}
742 +
743 +static int
744 +waltham_renderer_display_create(struct weston_transmitter_output *output)
745 +{
746 +       struct waltham_renderer *wth_renderer;
747 +
748 +       wth_renderer = zalloc(sizeof *wth_renderer);
749 +       if (wth_renderer == NULL)
750 +               return -1;
751 +       wth_renderer->base.repaint_output = waltham_renderer_repaint_output;
752 +
753 +       output->renderer = &wth_renderer->base;
754 +
755 +       recorder_enable(&output->base);
756 +       return 0;
757 +}
758 +
759 +WL_EXPORT struct waltham_renderer_interface waltham_renderer_interface = {
760 +               .display_create = waltham_renderer_display_create
761 +};
762 diff --git a/transmitter/waltham-renderer.h b/transmitter/waltham-renderer.h
763 new file mode 100644
764 index 0000000..458794e
765 --- /dev/null
766 +++ b/transmitter/waltham-renderer.h
767 @@ -0,0 +1,33 @@
768 +/*
769 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
770 + *
771 + * Permission is hereby granted, free of charge, to any person obtaining
772 + * a copy of this software and associated documentation files (the
773 + * "Software"), to deal in the Software without restriction, including
774 + * without limitation the rights to use, copy, modify, merge, publish,
775 + * distribute, sublicense, and/or sell copies of the Software, and to
776 + * permit persons to whom the Software is furnished to do so, subject to
777 + * the following conditions:
778 + *
779 + * The above copyright notice and this permission notice (including the
780 + * next paragraph) shall be included in all copies or substantial
781 + * portions of the Software.
782 + *
783 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
784 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
785 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
786 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
787 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
788 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
789 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
790 + * SOFTWARE.
791 + */
792 +
793 +#ifndef TRANSMITTER_WALTHAM_RENDERER_H_
794 +#define TRANSMITTER_WALTHAM_RENDERER_H_
795 +
796 +struct waltham_renderer_interface {
797 +       int (*display_create)(struct weston_transmitter_output *output);
798 +};
799 +
800 +#endif /* TRANSMITTER_WALTHAM_RENDERER_H_ */
801 -- 
802 2.7.4
803