1 /*****************************************************************************
2 * evas.c: EFL Evas video output
3 *****************************************************************************
4 * Copyright (C) 2015 VLC authors, VideoLAN, and VideoLabs
6 * Authors: Thomas Guillem <thomas@gllm.fr>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
29 #include <vlc_common.h>
30 #include <vlc_plugin.h>
31 #include <vlc_vout_display.h>
32 #include <vlc_picture_pool.h>
33 #include <vlc_filter.h>
38 /* Deactivate TBM surface for now: it's impossible to specify a crop (visible
39 * lines/pitch) and to avoid green borders. */
43 # include <tbm_surface.h>
46 #if defined(EVAS_VERSION_MAJOR) && defined(EVAS_VERSION_MINOR)
47 # if EVAS_VERSION_MAJOR > 1 || ( EVAS_VERSION_MAJOR == 1 && EVAS_VERSION_MINOR >= 10 )
48 # define HAVE_EVAS_CALLBACK_KEY_UP
52 /*****************************************************************************
54 *****************************************************************************/
55 #define CHROMA_TEXT "Chroma used"
56 #define CHROMA_LONGTEXT "Force use of a specific chroma for evas image"
58 static int Open ( vlc_object_t
* );
59 static void Close( vlc_object_t
* );
62 set_category( CAT_VIDEO
)
63 set_subcategory( SUBCAT_VIDEO_VOUT
)
64 set_shortname( "evas" )
65 set_description( "evas video output" )
66 set_capability( "vout display", 220 )
67 add_shortcut( "evas" )
68 add_string( "evas-image-chroma", NULL
, CHROMA_TEXT
, CHROMA_LONGTEXT
, true )
69 set_callbacks( Open
, Close
)
72 /*****************************************************************************
74 *****************************************************************************/
76 static int EvasImageSetup( vout_display_t
* );
78 static bool EvasIsOpenGLSupported( vout_display_t
* );
79 static int TbmSurfaceSetup( vout_display_t
* );
82 /* Buffer and Event Fifo */
86 struct fifo_item
*p_next
;
92 struct fifo_item
*p_first
;
93 struct fifo_item
*p_last
;
98 struct fifo_item fifo_item
;
99 uint8_t *p
[PICTURE_PLANE_MAX
];
101 #ifdef HAVE_TIZEN_SDK
102 tbm_surface_h p_tbm_surface
;
108 struct fifo_item fifo_item
;
119 struct vout_display_sys_t
121 picture_pool_t
*p_pool
;
123 int i_width
, i_height
;
126 plane_t p_planes
[PICTURE_PLANE_MAX
];
127 int i_planes_order
[PICTURE_PLANE_MAX
];
128 unsigned int i_nb_planes
;
130 /* Array of video buffers */
131 struct buffer
*p_buffers
;
132 unsigned int i_nb_buffers
;
134 /* FIFO of unlocked video buffers */
135 struct fifo buffer_fifo
;
137 /* New buffer to display */
138 struct buffer
*p_new_buffer
;
139 /* Buffer being displayed */
140 struct buffer
*p_current_buffer
;
144 Ecore_Animator
*p_anim
;
146 /* If true: this module doesn't own the Evas_Object anymore */
148 /* If true: apply rotation to vd->fmt */
149 bool b_apply_rotation
;
152 struct fifo event_fifo
;
154 /* lock and cond used by EcoreMainLoopCallSync */
161 Evas_Colorspace i_colorspace
;
164 #ifdef HAVE_TIZEN_SDK
172 /* Specific callbacks for EvasImage or TBMSurface */
173 int (*pf_set_data
)( vout_display_t
* );
174 int (*pf_buffers_alloc
)( vout_display_t
*, video_format_t
* );
175 void (*pf_buffers_free
)( vout_display_t
* );
180 vout_display_sys_t
*p_vd_sys
;
181 struct buffer
*p_buffer
;
185 fifo_push( struct fifo
*p_fifo
, struct fifo_item
*p_new
)
187 struct fifo_item
*p_last
;
189 vlc_mutex_lock( &p_fifo
->lock
);
191 p_new
->p_next
= NULL
;
192 p_last
= p_fifo
->p_last
;
195 p_last
->p_next
= p_new
;
197 p_fifo
->p_first
= p_new
;
198 p_fifo
->p_last
= p_new
;
200 vlc_mutex_unlock( &p_fifo
->lock
);
203 static struct fifo_item
*
204 fifo_pop( struct fifo
*p_fifo
)
206 struct fifo_item
*p_new
;
208 vlc_mutex_lock( &p_fifo
->lock
);
210 p_new
= p_fifo
->p_first
;
214 if( p_fifo
->p_last
== p_fifo
->p_first
)
215 p_fifo
->p_first
= p_fifo
->p_last
= NULL
;
217 p_fifo
->p_first
= p_new
->p_next
;
220 vlc_mutex_unlock( &p_fifo
->lock
);
225 fifo_init( struct fifo
*p_fifo
)
227 vlc_mutex_init( &p_fifo
->lock
);
228 p_fifo
->p_first
= p_fifo
->p_last
= NULL
;
232 fifo_deinit( struct fifo
*p_fifo
)
234 vlc_mutex_destroy( &p_fifo
->lock
);
237 #define BUFFER_FIFO_PUSH( buffer ) fifo_push( &sys->buffer_fifo, (struct fifo_item *)(buffer) )
238 #define BUFFER_FIFO_POP() (struct buffer *) fifo_pop( &sys->buffer_fifo )
239 #define EVENT_FIFO_PUSH( event ) fifo_push( &sys->event_fifo, (struct fifo_item *)(event) )
240 #define EVENT_FIFO_POP() (struct event *) fifo_pop( &sys->event_fifo )
242 typedef int (*mainloop_cb
)( vout_display_t
*vd
);
244 struct mainloop_cb_args
253 EcoreMainLoopCb( void *p_opaque
)
255 struct mainloop_cb_args
*p_args
= p_opaque
;
256 vout_display_sys_t
*sys
= p_args
->vd
->sys
;
258 p_args
->i_ret
= p_args
->p_cb( p_args
->vd
);
260 vlc_mutex_lock( &sys
->cb_lock
);
261 p_args
->b_signal
= true;
262 vlc_cond_signal( &sys
->cb_wait
);
263 vlc_mutex_unlock( &sys
->cb_lock
);
267 EcoreMainLoopCallSync( vout_display_t
*vd
, mainloop_cb p_cb
)
269 vout_display_sys_t
*sys
= vd
->sys
;
270 struct mainloop_cb_args args
= { .vd
= vd
, .p_cb
= p_cb
, .b_signal
= false };
271 ecore_main_loop_thread_safe_call_async( EcoreMainLoopCb
, &args
);
273 vlc_mutex_lock( &sys
->cb_lock
);
274 while( !args
.b_signal
)
275 vlc_cond_wait( &sys
->cb_wait
, &sys
->cb_lock
);
276 vlc_mutex_unlock( &sys
->cb_lock
);
281 #ifdef HAVE_EVAS_CALLBACK_KEY_UP
283 EventSendKey( vout_display_t
*vd
, int i_key
)
285 vout_display_sys_t
*sys
= vd
->sys
;
286 struct event
*p_event
= malloc( sizeof(struct event
) );
290 p_event
->i_type
= VOUT_DISPLAY_EVENT_KEY
;
291 p_event
->u
.i_key
= i_key
;
292 EVENT_FIFO_PUSH( p_event
);
296 EvasKeyUpCb( void *data
, Evas
*e
, Evas_Object
*obj
, void *event
)
298 (void) e
; (void) obj
;
299 Evas_Event_Key_Up
*p_key_up
= (Evas_Event_Key_Up
*) event
;
301 EventSendKey( data
, p_key_up
->keycode
);
306 EventSendMouseMoved( vout_display_t
*vd
, int i_x
, int i_y
)
308 vout_display_sys_t
*sys
= vd
->sys
;
309 Evas_Coord i_ox
, i_oy
, i_ow
, i_oh
;
310 struct event
*p_event
= malloc( sizeof(struct event
) );
314 evas_object_geometry_get( sys
->p_evas
, &i_ox
, &i_oy
, &i_ow
, &i_oh
);
315 p_event
->i_type
= VOUT_DISPLAY_EVENT_MOUSE_MOVED
;
316 p_event
->u
.point
.i_x
= ( ( i_x
- i_ox
) * sys
->i_width
) / i_ow
;
317 p_event
->u
.point
.i_y
= ( ( i_y
- i_oy
) * sys
->i_height
) / i_oh
;
318 EVENT_FIFO_PUSH( p_event
);
322 EventSendMouseButton( vout_display_t
*vd
, int i_type
, int i_button
)
324 vout_display_sys_t
*sys
= vd
->sys
;
325 struct event
*p_event
= malloc( sizeof(struct event
) );
329 p_event
->i_type
= i_type
;
330 p_event
->u
.i_button
= i_button
;
331 EVENT_FIFO_PUSH( p_event
);
335 EventMouseDownCb( void *data
, Evas
*e
, Evas_Object
*obj
, void *event
)
337 (void) e
; (void) obj
;
338 Evas_Event_Mouse_Down
*p_mouse_down
= (Evas_Event_Mouse_Down
*) event
;
340 EventSendMouseButton( data
, VOUT_DISPLAY_EVENT_MOUSE_PRESSED
,
341 p_mouse_down
->button
- 1 );
345 EvasMouseUpCb( void *data
, Evas
*e
, Evas_Object
*obj
, void *event
)
347 (void) e
; (void) obj
;
348 Evas_Event_Mouse_Up
*p_mouse_up
= (Evas_Event_Mouse_Up
*) event
;
350 EventSendMouseButton( data
, VOUT_DISPLAY_EVENT_MOUSE_RELEASED
,
351 p_mouse_up
->button
- 1 );
355 EvasMouseMoveCb( void *data
, Evas
*e
, Evas_Object
*obj
, void *event
)
357 (void) e
; (void) obj
;
358 Evas_Event_Mouse_Move
*p_mouse_move
= (Evas_Event_Mouse_Move
*) event
;
359 EventSendMouseMoved( data
, p_mouse_move
->cur
.canvas
.x
,
360 p_mouse_move
->cur
.canvas
.y
);
364 EvasMultiDownCb( void *data
, Evas
*e
, Evas_Object
*obj
, void *event
)
366 (void) e
; (void) obj
; (void) event
;
367 EventSendMouseButton( data
, VOUT_DISPLAY_EVENT_MOUSE_PRESSED
, 1 );
371 EvasMultiUpCb( void *data
, Evas
*e
, Evas_Object
*obj
, void *event
)
373 (void) e
; (void) obj
; (void) event
;
374 EventSendMouseButton( data
, VOUT_DISPLAY_EVENT_MOUSE_RELEASED
, 1 );
378 EvasMultiMoveCb( void *data
, Evas
*e
, Evas_Object
*obj
, void *event
)
380 (void) e
; (void) obj
;
381 Evas_Event_Multi_Move
*p_multi_move
= (Evas_Event_Multi_Move
*) event
;
383 EventSendMouseMoved( data
, p_multi_move
->cur
.canvas
.x
,
384 p_multi_move
->cur
.canvas
.y
);
388 FmtUpdate( vout_display_t
*vd
)
390 vout_display_sys_t
*sys
= vd
->sys
;
391 vout_display_place_t place
;
394 vout_display_PlacePicture( &place
, &vd
->source
, vd
->cfg
, false );
396 if( sys
->b_apply_rotation
)
398 video_format_ApplyRotation( &src
, &vd
->source
);
399 vd
->fmt
.orientation
= 0;
404 vd
->fmt
.i_width
= src
.i_width
* place
.width
/ src
.i_visible_width
;
405 vd
->fmt
.i_height
= src
.i_height
* place
.height
/ src
.i_visible_height
;
407 vd
->fmt
.i_visible_width
= place
.width
;
408 vd
->fmt
.i_visible_height
= place
.height
;
409 vd
->fmt
.i_x_offset
= src
.i_x_offset
* place
.width
/ src
.i_visible_width
;
410 vd
->fmt
.i_y_offset
= src
.i_y_offset
* place
.height
/ src
.i_visible_height
;
412 sys
->i_width
= vd
->fmt
.i_visible_width
;
413 sys
->i_height
= vd
->fmt
.i_visible_height
;
417 mainloop_evas_anim_cb( void *p_opaque
)
419 vout_display_t
*vd
= p_opaque
;
420 vout_display_sys_t
*sys
= vd
->sys
;
421 evas_object_image_pixels_dirty_set( sys
->p_evas
, 1 );
428 EvasResizeCb( void *data
, Evas
*e
, Evas_Object
*obj
, void *event
)
430 (void) e
; (void) obj
; (void) event
;
431 vout_display_t
*vd
= data
;
432 vout_display_sys_t
*sys
= vd
->sys
;
434 sys
->b_evas_changed
= true;
438 EvasDisplayMainloopCb( vout_display_t
*vd
)
440 vout_display_sys_t
*sys
= vd
->sys
;
442 if( sys
->b_evas_changed
|| sys
->pf_set_data( vd
) )
445 evas_object_image_data_update_add( sys
->p_evas
, 0, 0,
446 sys
->i_width
, sys
->i_height
);
447 evas_object_image_pixels_dirty_set( sys
->p_evas
, 0 );
450 sys
->p_anim
= ecore_animator_add( mainloop_evas_anim_cb
, vd
);
452 if( sys
->p_current_buffer
)
453 BUFFER_FIFO_PUSH( sys
->p_current_buffer
);
455 sys
->p_current_buffer
= sys
->p_new_buffer
;
456 sys
->p_new_buffer
= NULL
;
461 EvasInitMainloopCb( vout_display_t
*vd
)
463 vout_display_sys_t
*sys
= vd
->sys
;
465 #ifdef HAVE_TIZEN_SDK
466 if( !EvasIsOpenGLSupported( vd
) || TbmSurfaceSetup( vd
) )
468 if( EvasImageSetup( vd
) )
471 evas_object_image_alpha_set( sys
->p_evas
, 0 );
472 evas_object_image_size_set( sys
->p_evas
, sys
->i_width
, sys
->i_height
);
474 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_MOUSE_DOWN
,
475 EventMouseDownCb
, vd
);
476 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_MOUSE_UP
,
478 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_MOUSE_MOVE
,
479 EvasMouseMoveCb
, vd
);
480 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_MULTI_DOWN
,
481 EvasMultiDownCb
, vd
);
482 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_MULTI_UP
,
484 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_MULTI_MOVE
,
485 EvasMultiMoveCb
, vd
);
486 #ifdef HAVE_EVAS_CALLBACK_KEY_UP
487 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_KEY_UP
,
491 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_IMAGE_RESIZE
,
498 EvasDeinitMainloopCb( vout_display_t
*vd
)
500 vout_display_sys_t
*sys
= vd
->sys
;
504 ecore_animator_del( sys
->p_anim
);
508 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_IMAGE_RESIZE
,
511 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_MOUSE_DOWN
,
512 EventMouseDownCb
, vd
);
513 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_MOUSE_UP
,
515 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_MOUSE_MOVE
,
516 EvasMouseMoveCb
, vd
);
517 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_MULTI_DOWN
,
518 EvasMultiDownCb
, vd
);
519 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_MULTI_UP
,
521 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_MULTI_MOVE
,
522 EvasMultiMoveCb
, vd
);
523 #ifdef HAVE_EVAS_CALLBACK_KEY_UP
524 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_KEY_UP
,
528 if( !sys
->b_evas_changed
)
530 evas_object_image_data_set( sys
->p_evas
, NULL
);
531 evas_object_image_pixels_dirty_set( sys
->p_evas
, 0 );
538 EvasResetMainloopCb( vout_display_t
*vd
)
540 vout_display_sys_t
*sys
= vd
->sys
;
542 if( sys
->b_evas_changed
)
547 ecore_animator_del( sys
->p_anim
);
551 evas_object_event_callback_del_full( sys
->p_evas
, EVAS_CALLBACK_IMAGE_RESIZE
,
556 evas_object_image_data_set( sys
->p_evas
, NULL
);
557 evas_object_image_size_set( sys
->p_evas
, sys
->i_width
, sys
->i_height
);
559 evas_object_event_callback_add( sys
->p_evas
, EVAS_CALLBACK_IMAGE_RESIZE
,
565 BuffersSetup( vout_display_t
*vd
, video_format_t
*p_fmt
,
566 unsigned int *p_requested_count
)
568 vout_display_sys_t
*sys
= vd
->sys
;
570 sys
->i_nb_buffers
= *p_requested_count
;
571 if( sys
->pf_buffers_alloc( vd
, p_fmt
) )
573 sys
->i_nb_planes
= 0;
576 *p_requested_count
= sys
->i_nb_buffers
;
578 for( unsigned int i
= 0; i
< sys
->i_nb_buffers
; ++i
)
579 BUFFER_FIFO_PUSH( &sys
->p_buffers
[i
] );
584 BuffersClean( vout_display_t
*vd
)
586 vout_display_sys_t
*sys
= vd
->sys
;
589 sys
->pf_buffers_free( vd
);
590 sys
->buffer_fifo
.p_first
= sys
->buffer_fifo
.p_last
= NULL
;
594 PictureAlloc( vout_display_t
*vd
)
596 vout_display_sys_t
*sys
= vd
->sys
;
597 picture_resource_t rsc
;
598 picture_t
*p_pic
= NULL
;
599 picture_sys_t
*p_picsys
= calloc(1, sizeof(*p_picsys
));
604 p_picsys
->p_vd_sys
= vd
->sys
;
605 memset(&rsc
, 0, sizeof(picture_resource_t
));
606 rsc
.p_sys
= p_picsys
;
607 for( unsigned int i
= 0; i
< sys
->i_nb_planes
; ++i
)
609 rsc
.p
[i
].i_lines
= sys
->p_planes
[i
].i_lines
;
610 rsc
.p
[i
].i_pitch
= sys
->p_planes
[i
].i_pitch
;
613 p_pic
= picture_NewFromResource( &vd
->fmt
, &rsc
);
624 PoolLockPicture(picture_t
*p_pic
)
626 picture_sys_t
*p_picsys
= p_pic
->p_sys
;
627 vout_display_sys_t
*sys
= p_picsys
->p_vd_sys
;
629 struct buffer
*p_buffer
= BUFFER_FIFO_POP();
630 if( !p_buffer
|| !p_buffer
->p
[0] )
633 p_picsys
->p_buffer
= p_buffer
;
634 for( unsigned int i
= 0; i
< sys
->i_nb_planes
; ++i
)
635 p_pic
->p
[i
].p_pixels
= p_buffer
->p
[i
];
640 PoolUnlockPicture(picture_t
*p_pic
)
642 picture_sys_t
*p_picsys
= p_pic
->p_sys
;
643 vout_display_sys_t
*sys
= p_picsys
->p_vd_sys
;
645 if( p_picsys
->p_buffer
)
647 BUFFER_FIFO_PUSH( p_picsys
->p_buffer
);
648 p_picsys
->p_buffer
= NULL
;
652 static picture_pool_t
*
653 PoolAlloc( vout_display_t
*vd
, unsigned i_requested_count
)
655 picture_t
**pp_pics
= NULL
;
656 picture_pool_t
*p_pool
;
657 picture_pool_configuration_t pool_cfg
;
659 msg_Dbg(vd
, "PoolAlloc, requested_count: %d", i_requested_count
);
661 i_requested_count
++; /* picture owned by evas */
663 if( BuffersSetup( vd
, &vd
->fmt
, &i_requested_count
) )
665 msg_Err( vd
, "BuffersSetup failed" );
668 if( i_requested_count
<= 1 )
670 msg_Err( vd
, "not enough buffers allocated" );
675 msg_Dbg( vd
, "PoolAlloc, got: %d", i_requested_count
);
677 if( !( pp_pics
= calloc( i_requested_count
, sizeof(picture_t
) ) ) )
680 for( unsigned int i
= 0; i
< i_requested_count
; ++i
)
682 if( !( pp_pics
[i
] = PictureAlloc( vd
) ) )
684 i_requested_count
= i
;
685 msg_Err( vd
, "PictureAlloc failed" );
690 memset( &pool_cfg
, 0, sizeof(pool_cfg
) );
691 pool_cfg
.picture_count
= i_requested_count
;
692 pool_cfg
.picture
= pp_pics
;
693 pool_cfg
.lock
= PoolLockPicture
;
694 pool_cfg
.unlock
= PoolUnlockPicture
;
696 p_pool
= picture_pool_NewExtended( &pool_cfg
);
703 for( unsigned int i
= 0; i
< i_requested_count
; ++i
)
704 picture_Release( pp_pics
[i
] );
711 static picture_pool_t
*
712 Pool( vout_display_t
*vd
, unsigned i_requested_count
)
714 vout_display_sys_t
*sys
= vd
->sys
;
716 if( sys
->p_pool
== NULL
)
717 sys
->p_pool
= PoolAlloc( vd
, i_requested_count
);
722 Display( vout_display_t
*vd
, picture_t
*p_pic
, subpicture_t
*p_subpic
)
725 vout_display_sys_t
*sys
= vd
->sys
;
726 picture_sys_t
*p_picsys
= p_pic
->p_sys
;
728 if( p_picsys
->p_buffer
)
730 sys
->p_new_buffer
= p_picsys
->p_buffer
;
731 p_picsys
->p_buffer
= NULL
;
733 EcoreMainLoopCallSync( vd
, EvasDisplayMainloopCb
);
735 picture_Release( p_pic
);
739 Control( vout_display_t
*vd
, int i_query
, va_list ap
)
741 vout_display_sys_t
*sys
= vd
->sys
;
745 case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT
:
747 vout_display_place_t place
;
750 msg_Dbg( vd
, "VOUT_DISPLAY_CHANGE_SOURCE_ASPECT" );
752 video_format_ApplyRotation( &fmt
, &vd
->source
);
753 vout_display_PlacePicture( &place
, &fmt
, vd
->cfg
, false );
755 if( place
.width
!= (unsigned) sys
->i_width
756 && place
.height
!= (unsigned) sys
->i_height
)
758 if( vd
->info
.has_pictures_invalid
)
760 msg_Warn( vd
, "ratio changed: invalidate pictures" );
761 vout_display_SendEventPicturesInvalid( vd
);
768 case VOUT_DISPLAY_RESET_PICTURES
:
769 msg_Dbg( vd
, "VOUT_DISPLAY_RESET_PICTURES" );
771 EcoreMainLoopCallSync( vd
, EvasResetMainloopCb
);
777 picture_pool_Release( sys
->p_pool
);
781 case VOUT_DISPLAY_CHANGE_ZOOM
:
782 case VOUT_DISPLAY_CHANGE_SOURCE_CROP
:
783 case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE
:
784 case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED
:
787 msg_Warn( vd
, "Unknown request in evas_output" );
793 Manage( vout_display_t
*vd
)
795 vout_display_sys_t
*sys
= vd
->sys
;
796 struct event
*p_event
;
798 while( ( p_event
= EVENT_FIFO_POP() ) )
800 switch( p_event
->i_type
)
802 case VOUT_DISPLAY_EVENT_MOUSE_MOVED
:
803 vout_display_SendEventMouseMoved( vd
, p_event
->u
.point
.i_x
,
804 p_event
->u
.point
.i_y
);
806 case VOUT_DISPLAY_EVENT_MOUSE_PRESSED
:
807 case VOUT_DISPLAY_EVENT_MOUSE_RELEASED
:
808 vout_display_SendEvent( vd
, p_event
->i_type
,
809 p_event
->u
.i_button
);
811 case VOUT_DISPLAY_EVENT_KEY
:
812 vout_display_SendEventKey( vd
, p_event
->u
.i_key
);
820 Close( vlc_object_t
*p_this
)
822 vout_display_t
*vd
= (vout_display_t
*)p_this
;
823 vout_display_sys_t
*sys
= vd
->sys
;
824 struct event
*p_event
;
829 EcoreMainLoopCallSync( vd
, EvasDeinitMainloopCb
);
832 fifo_deinit( &sys
->buffer_fifo
);
835 picture_pool_Release(sys
->p_pool
);
837 while( ( p_event
= EVENT_FIFO_POP() ) )
840 vlc_mutex_destroy( &sys
->cb_lock
);
841 vlc_cond_destroy( &sys
->cb_wait
);
847 Open( vlc_object_t
*p_this
)
849 vout_display_t
*vd
= (vout_display_t
*)p_this
;
850 vout_display_sys_t
*sys
;
853 if( vout_display_IsWindowed( vd
) )
856 p_evas
= var_InheritAddress( p_this
, "drawable-evasobject" );
860 vd
->sys
= sys
= (struct vout_display_sys_t
*) calloc( 1, sizeof(*sys
) );
864 vlc_mutex_init( &sys
->cb_lock
);
865 vlc_cond_init( &sys
->cb_wait
);
866 fifo_init( &sys
->buffer_fifo
);
867 fifo_init( &sys
->event_fifo
);
869 sys
->p_evas
= p_evas
;
871 msg_Dbg( vd
, "request video format: %4.4s",
872 (const char *)&vd
->fmt
.i_chroma
);
874 /* Evas Initialisation must be done from the Mainloop */
875 if( EcoreMainLoopCallSync( vd
, EvasInitMainloopCb
) )
877 msg_Err( vd
, "EvasInitMainloopCb failed" );
882 for( unsigned int i
= 0; i
< PICTURE_PLANE_MAX
; ++i
)
883 sys
->i_planes_order
[i
] = i
;
885 switch( vd
->fmt
.i_chroma
)
887 case VLC_CODEC_RGB32
:
888 case VLC_CODEC_RGB16
:
889 video_format_FixRgb(&vd
->fmt
);
892 sys
->i_planes_order
[1] = 2;
893 sys
->i_planes_order
[2] = 1;
898 msg_Dbg( vd
, "got video format: %4.4s, size: %dx%d",
899 (const char *)&vd
->fmt
.i_chroma
,
900 sys
->i_width
, sys
->i_height
);
902 /* Setup vout_display */
905 vd
->display
= Display
;
906 vd
->control
= Control
;
913 EvasImageSetData( vout_display_t
*vd
)
915 vout_display_sys_t
*sys
= vd
->sys
;
916 struct buffer
*p_buffer
= sys
->p_new_buffer
;
918 if( sys
->u
.evas
.b_yuv
)
920 void *p_data
= evas_object_image_data_get( sys
->p_evas
, 1 );
921 const uint8_t **pp_rows
= (const uint8_t **) p_data
;
926 for( unsigned int i
= 0; i
< sys
->i_nb_planes
; ++i
)
928 plane_t
*p_plane
= &sys
->p_planes
[sys
->i_planes_order
[i
]];
930 for( int j
= 0; j
< p_plane
->i_visible_lines
; ++j
)
931 *(pp_rows
++) = &p_buffer
->p
[i
][j
* p_plane
->i_pitch
];
934 evas_object_image_data_set( sys
->p_evas
, p_data
);
937 evas_object_image_data_set( sys
->p_evas
, p_buffer
->p
[0] );
943 EvasImageBuffersFree( vout_display_t
*vd
)
945 vout_display_sys_t
*sys
= vd
->sys
;
947 for( unsigned int i
= 0; i
< sys
->i_nb_buffers
; i
++ )
948 aligned_free( sys
->p_buffers
[i
].p
[0] );
949 free( sys
->p_buffers
);
950 sys
->p_buffers
= NULL
;
951 sys
->i_nb_buffers
= 0;
952 sys
->i_nb_planes
= 0;
956 EvasImageBuffersAlloc( vout_display_t
*vd
, video_format_t
*p_fmt
)
958 vout_display_sys_t
*sys
= vd
->sys
;
959 picture_t
*p_pic
= NULL
;
960 picture_resource_t rsc
;
963 memset(&rsc
, 0, sizeof(picture_resource_t
));
964 if( !( p_pic
= picture_NewFromResource( p_fmt
, &rsc
) ) )
967 if( picture_Setup( p_pic
, p_fmt
) )
969 picture_Release( p_pic
);
973 for( int i
= 0; i
< p_pic
->i_planes
; ++i
)
974 memcpy( &sys
->p_planes
[i
], &p_pic
->p
[i
], sizeof(plane_t
));
975 sys
->i_nb_planes
= p_pic
->i_planes
;
976 picture_Release( p_pic
);
978 if( !( sys
->p_buffers
= calloc( sys
->i_nb_buffers
, sizeof(struct buffer
) ) ) )
981 /* Calculate how big the new image should be */
982 for( unsigned int i
= 0; i
< sys
->i_nb_planes
; i
++ )
984 const plane_t
*p
= &sys
->p_planes
[i
];
986 if( p
->i_pitch
< 0 || p
->i_lines
<= 0 ||
987 (size_t)p
->i_pitch
> (SIZE_MAX
- i_bytes
)/p
->i_lines
)
989 i_bytes
+= p
->i_pitch
* p
->i_lines
;
995 for( unsigned int i
= 0; i
< sys
->i_nb_buffers
; ++i
)
997 struct buffer
*p_buffer
= &sys
->p_buffers
[i
];
999 p_buffer
->p
[0] = aligned_alloc( 16, i_bytes
);
1001 if( !p_buffer
->p
[0] )
1003 sys
->i_nb_buffers
= i
;
1007 for( unsigned int j
= 1; j
< sys
->i_nb_planes
; j
++ )
1008 p_buffer
->p
[j
] = &p_buffer
->p
[j
-1][ sys
->p_planes
[j
-1].i_lines
*
1009 sys
->p_planes
[j
-1].i_pitch
];
1015 if( sys
->p_buffers
)
1016 EvasImageBuffersFree( vd
);
1021 EvasImageSetup( vout_display_t
*vd
)
1023 vout_display_sys_t
*sys
= vd
->sys
;
1024 char *psz_fcc
= var_InheritString( vd
, "evas-image-chroma" );
1028 vd
->fmt
.i_chroma
= vlc_fourcc_GetCodecFromString( VIDEO_ES
, psz_fcc
);
1032 switch( vd
->fmt
.i_chroma
)
1034 case VLC_CODEC_RGB32
:
1035 sys
->u
.evas
.i_colorspace
= EVAS_COLORSPACE_ARGB8888
;
1037 /* Not implemented yet */
1039 case VLC_CODEC_RGB16
:
1040 sys
->u
.evas
.i_colorspace
= EVAS_COLORSPACE_RGB565_A5P
;
1043 case VLC_CODEC_YUYV
:
1044 sys
->u
.evas
.i_colorspace
= EVAS_COLORSPACE_YCBCR422601_PL
;
1045 sys
->u
.evas
.b_yuv
= true;
1047 /* FIXME: SIGSEGV in evas_gl_common_texture_nv12_update */
1049 case VLC_CODEC_NV12
:
1050 sys
->u
.evas
.i_colorspace
= EVAS_COLORSPACE_YCBCR420NV12601_PL
;
1051 sys
->u
.evas
.b_yuv
= true;
1054 case VLC_CODEC_YV12
:
1055 sys
->u
.evas
.i_colorspace
= EVAS_COLORSPACE_YCBCR422P601_PL
;
1056 sys
->u
.evas
.b_yuv
= true;
1059 case VLC_CODEC_I420
:
1060 sys
->u
.evas
.i_colorspace
= EVAS_COLORSPACE_YCBCR422P601_PL
;
1061 vd
->fmt
.i_chroma
= VLC_CODEC_I420
;
1062 sys
->u
.evas
.b_yuv
= true;
1066 evas_object_image_colorspace_set( sys
->p_evas
, sys
->u
.evas
.i_colorspace
);
1067 evas_object_image_data_set( sys
->p_evas
, NULL
);
1069 /* No rotation support with EvasImage */
1070 sys
->b_apply_rotation
= true;
1073 /* No aspect ratio support with EvasImage */
1074 vd
->info
.has_pictures_invalid
= true;
1076 sys
->pf_set_data
= EvasImageSetData
;
1077 sys
->pf_buffers_alloc
= EvasImageBuffersAlloc
;
1078 sys
->pf_buffers_free
= EvasImageBuffersFree
;
1080 msg_Dbg( vd
, "using evas_image" );
1084 #ifdef HAVE_TIZEN_SDK
1086 struct tbm_format_to_vlc
1088 tbm_format i_tbm_format
;
1089 vlc_fourcc_t i_vlc_chroma
;
1092 struct tbm_format_to_vlc tbm_format_to_vlc_list
[] = {
1093 { TBM_FORMAT_NV12
, VLC_CODEC_NV12
},
1094 { TBM_FORMAT_YUV420
, VLC_CODEC_I420
},
1095 { TBM_FORMAT_BGRA8888
, VLC_CODEC_RGB32
},
1097 #define TBM_FORMAT_TO_VLC_LIST_COUNT \
1098 ( sizeof(tbm_format_to_vlc_list) / sizeof(struct tbm_format_to_vlc) )
1101 EvasIsOpenGLSupported( vout_display_t
*vd
)
1103 vout_display_sys_t
*sys
= vd
->sys
;
1104 Evas
*p_canvas
= evas_object_evas_get(sys
->p_evas
);
1105 Eina_List
*p_engine_list
, *p_l
;
1107 char *psz_render_name
;
1108 bool b_is_gl
= false;
1112 i_render_id
= evas_output_method_get( p_canvas
);
1114 p_engine_list
= evas_render_method_list();
1115 if( !p_engine_list
)
1118 EINA_LIST_FOREACH( p_engine_list
, p_l
, psz_render_name
)
1120 if( evas_render_method_lookup( psz_render_name
) == i_render_id
)
1122 b_is_gl
= strncmp( psz_render_name
, "gl", 2 ) == 0;
1127 evas_render_method_list_free( p_engine_list
);
1132 TbmSurfaceBufferLock( struct buffer
*p_buffer
)
1134 tbm_surface_info_s tbm_surface_info
;
1135 if( tbm_surface_map( p_buffer
->p_tbm_surface
, TBM_SURF_OPTION_WRITE
,
1136 &tbm_surface_info
) )
1139 for( unsigned i
= 0; i
< tbm_surface_info
.num_planes
; ++i
)
1140 p_buffer
->p
[i
] = tbm_surface_info
.planes
[i
].ptr
;
1145 TbmSurfaceBufferUnlock( struct buffer
*p_buffer
)
1147 tbm_surface_unmap( p_buffer
->p_tbm_surface
);
1148 p_buffer
->p
[0] = NULL
;
1153 TbmSurfaceSetData( vout_display_t
*vd
)
1155 vout_display_sys_t
*sys
= vd
->sys
;
1156 Evas_Native_Surface surf
;
1158 TbmSurfaceBufferUnlock( sys
->p_new_buffer
);
1160 surf
.version
= EVAS_NATIVE_SURFACE_VERSION
;
1161 surf
.type
= EVAS_NATIVE_SURFACE_TBM
;
1162 surf
.data
.tizen
.buffer
= sys
->p_new_buffer
->p_tbm_surface
;
1163 surf
.data
.tizen
.rot
= sys
->u
.tbm
.i_angle
;
1164 surf
.data
.tizen
.ratio
= 0;
1165 surf
.data
.tizen
.flip
= 0;
1166 evas_object_image_native_surface_set( sys
->p_evas
, &surf
);
1168 if( sys
->p_current_buffer
)
1169 TbmSurfaceBufferLock( sys
->p_current_buffer
);
1174 TbmSurfaceBuffersFree( vout_display_t
*vd
)
1176 vout_display_sys_t
*sys
= vd
->sys
;
1178 for( unsigned int i
= 0; i
< sys
->i_nb_buffers
; i
++ )
1180 if( sys
->p_buffers
[i
].p
[0] )
1181 tbm_surface_unmap( sys
->p_buffers
[i
].p_tbm_surface
);
1182 tbm_surface_destroy( sys
->p_buffers
[i
].p_tbm_surface
);
1184 free( sys
->p_buffers
);
1185 sys
->p_buffers
= NULL
;
1186 sys
->i_nb_buffers
= 0;
1187 sys
->i_nb_planes
= 0;
1191 TbmSurfaceBuffersAllocMainloopCb( vout_display_t
*vd
)
1193 vout_display_sys_t
*sys
= vd
->sys
;
1194 tbm_surface_info_s tbm_surface_info
;
1196 sys
->i_nb_buffers
= 2;
1198 if( !( sys
->p_buffers
= calloc( sys
->i_nb_buffers
, sizeof(struct buffer
) ) ) )
1201 for( unsigned i
= 0; i
< sys
->i_nb_buffers
; ++i
)
1203 struct buffer
*p_buffer
= &sys
->p_buffers
[i
];
1204 tbm_surface_h p_tbm_surface
= tbm_surface_create( sys
->i_width
,
1206 sys
->u
.tbm
.i_format
);
1208 || tbm_surface_get_info( p_tbm_surface
, &tbm_surface_info
) )
1210 tbm_surface_destroy( p_tbm_surface
);
1211 p_tbm_surface
= NULL
;
1214 if( !p_tbm_surface
)
1216 sys
->i_nb_buffers
= i
;
1219 p_buffer
->p_tbm_surface
= p_tbm_surface
;
1220 TbmSurfaceBufferLock( p_buffer
);
1223 sys
->i_nb_planes
= tbm_surface_info
.num_planes
;
1224 for( unsigned i
= 0; i
< tbm_surface_info
.num_planes
; ++i
)
1226 sys
->p_planes
[i
].i_lines
= tbm_surface_info
.planes
[i
].size
1227 / tbm_surface_info
.planes
[i
].stride
;
1228 sys
->p_planes
[i
].i_visible_lines
= sys
->p_planes
[i
].i_lines
;
1229 sys
->p_planes
[i
].i_pitch
= tbm_surface_info
.planes
[i
].stride
;
1230 sys
->p_planes
[i
].i_visible_pitch
= sys
->p_planes
[i
].i_pitch
;
1237 TbmSurfaceBuffersAlloc( vout_display_t
*vd
, video_format_t
*p_fmt
)
1240 return EcoreMainLoopCallSync( vd
, TbmSurfaceBuffersAllocMainloopCb
);
1244 TbmSurfaceSetup( vout_display_t
*vd
)
1246 vout_display_sys_t
*sys
= vd
->sys
;
1247 tbm_format i_tbm_format
= 0;
1248 bool b_found
= false;
1249 uint32_t *p_formats
;
1250 uint32_t i_format_num
;
1252 for( unsigned int i
= 0; i
< TBM_FORMAT_TO_VLC_LIST_COUNT
; ++i
)
1254 if( tbm_format_to_vlc_list
[i
].i_vlc_chroma
== vd
->fmt
.i_chroma
)
1256 i_tbm_format
= tbm_format_to_vlc_list
[i
].i_tbm_format
;
1262 msg_Err( vd
, "no tbm format found" );
1266 if( tbm_surface_query_formats( &p_formats
, &i_format_num
) )
1268 msg_Warn( vd
, "tbm_surface_query_formats failed" );
1272 for( unsigned int i
= 0; i
< i_format_num
; i
++ )
1274 if( p_formats
[i
] == i_tbm_format
)
1282 if( i_tbm_format
!= TBM_FORMAT_YUV420
)
1284 msg_Warn( vd
, "vlc format not matching any tbm format: trying with I420");
1285 i_tbm_format
= TBM_FORMAT_YUV420
;
1286 for( uint32_t i
= 0; i
< i_format_num
; i
++ )
1288 if( p_formats
[i
] == i_tbm_format
)
1290 vd
->fmt
.i_chroma
= VLC_CODEC_I420
;
1301 msg_Warn( vd
, "can't find any compatible tbm format" );
1304 sys
->u
.tbm
.i_format
= i_tbm_format
;
1306 switch( vd
->fmt
.orientation
)
1308 case ORIENT_ROTATED_90
:
1309 sys
->u
.tbm
.i_angle
= 270;
1311 case ORIENT_ROTATED_180
:
1312 sys
->u
.tbm
.i_angle
= 180;
1314 case ORIENT_ROTATED_270
:
1315 sys
->u
.tbm
.i_angle
= 90;
1318 sys
->u
.tbm
.i_angle
= 0;
1321 sys
->b_apply_rotation
= false;
1325 vd
->info
.has_pictures_invalid
= true;
1327 sys
->pf_set_data
= TbmSurfaceSetData
;
1328 sys
->pf_buffers_alloc
= TbmSurfaceBuffersAlloc
;
1329 sys
->pf_buffers_free
= TbmSurfaceBuffersFree
;
1331 msg_Dbg( vd
, "using tbm_surface" );