1 /*
2  * Copyright (C) 2000-2018 the xine project
3  *
4  * This file is part of xine, a free video player.
5  *
6  * xine is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * xine is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  *
21  * xine version of video_out.h
22  *
23  * vo_frame    : frame containing yuv data and timing info,
24  *               transferred between video_decoder and video_output
25  *
26  * vo_driver   : lowlevel, platform-specific video output code
27  *
28  * vo_port     : generic frame_handling code, uses
29  *               a vo_driver for output
30  */
31 
32 #ifndef HAVE_VIDEO_OUT_H
33 #define HAVE_VIDEO_OUT_H
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 #include <pthread.h>
40 
41 #include <xine.h>
42 #include <xine/attributes.h>
43 #include <xine/buffer.h>
44 
45 struct plugin_node_s;
46 
47 typedef struct vo_frame_s vo_frame_t;
48 typedef struct vo_driver_s vo_driver_t;
49 typedef struct video_driver_class_s video_driver_class_t;
50 typedef struct vo_overlay_s vo_overlay_t;
51 typedef struct video_overlay_manager_s video_overlay_manager_t;
52 
53 /* public part, video drivers may add private fields
54  *
55  * Remember that adding new functions to this structure requires
56  * adaption of the post plugin decoration layer. Be sure to look into
57  * src/xine-engine/post.[ch].
58  */
59 struct vo_frame_s {
60   /*
61    * member functions
62    */
63 
64   /* Provide a copy of the frame's image in an image format already known to xine. data's member */
65   /* have already been intialized to frame's content on entry, so it's usually only necessary to */
66   /* change format and img_size. In case img is set, it will point to a memory block of suitable */
67   /* size (size has been determined by a previous call with img == NULL). img content and img_size */
68   /* must adhere to the specification of _x_get_current_frame_data(). */
69   /* Currently this is needed for all image formats except XINE_IMGFMT_YV12 and XINE_IMGFMT_YUY2. */
70   void (*proc_provide_standard_frame_data) (vo_frame_t *vo_img, xine_current_frame_data_t *data);
71 
72   /* Duplicate picture data and acceleration specific data of a frame. */
73   /* if the image format isn't already known by Xine. Currently this is needed */
74   /* For all image formats except XINE_IMGFMT_YV12 and XINE_IMGFMT_YUY2 */
75   void (*proc_duplicate_frame_data) (vo_frame_t *vo_img, vo_frame_t *src);
76 
77   /* tell video driver to copy/convert the whole of this frame, may be NULL */
78   /* at least one of proc_frame() and proc_slice() MUST set the variable proc_called to 1 */
79   void (*proc_frame) (vo_frame_t *vo_img);
80 
81   /* tell video driver to copy/convert a slice of this frame, may be NULL */
82   /* at least one of proc_frame() and proc_slice() MUST set the variable proc_called to 1 */
83   void (*proc_slice) (vo_frame_t *vo_img, uint8_t **src);
84 
85   /* tell video driver that the decoder starts a new field */
86   void (*field) (vo_frame_t *vo_img, int which_field);
87 
88   /* append this frame to the display queue,
89      returns number of frames to skip if decoder is late */
90   /* when the frame does not originate from a stream, it is legal to pass an anonymous stream */
91   int (*draw) (vo_frame_t *vo_img, xine_stream_t *stream);
92 
93   /* lock frame as reference, must be paired with free.
94    * most decoders/drivers do not need to call this function since
95    * newly allocated frames are already locked once.
96    */
97   void (*lock) (vo_frame_t *vo_img);
98 
99   /* this frame is no longer used by the decoder, video driver, etc */
100   void (*free) (vo_frame_t *vo_img);
101 
102   /* free memory/resources for this frame */
103   void (*dispose) (vo_frame_t *vo_img);
104 
105   /*
106    * public variables to decoders and vo drivers
107    * changing anything here will require recompiling them both
108    */
109   int64_t                    pts;           /* presentation time stamp (1/90000 sec)        */
110   int64_t                    vpts;          /* virtual pts, generated by metronom           */
111   int                        bad_frame;     /* e.g. frame skipped or based on skipped frame */
112   int                        duration;      /* frame length in time, in 1/90000 sec         */
113 
114   /* yv12 (planar)       base[0]: y,       base[1]: u,  base[2]: v  */
115   /* yuy2 (interleaved)  base[0]: yuyv..., base[1]: --, base[2]: -- */
116   uint8_t                   *base[3];
117   int                        pitches[3];
118 
119   /* info that can be used for interlaced output (e.g. tv-out)      */
120   int                        top_field_first;
121   int                        repeat_first_field;
122   /* note: progressive_frame is set wrong on many mpeg2 streams. for
123    * that reason, this flag should be interpreted as a "hint".
124    */
125   int                        progressive_frame;
126   int                        picture_coding_type;
127 
128   /* cropping to be done */
129   int                        crop_left, crop_right, crop_top, crop_bottom;
130 
131   int                        lock_counter;
132   pthread_mutex_t            mutex; /* protect access to lock_count */
133 
134   /* extra info coming from input or demuxers */
135   extra_info_t              *extra_info;
136 
137   /* additional information to be able to duplicate frames:         */
138   int                        width, height;
139   double                     ratio;         /* aspect ratio  */
140   int                        format;        /* IMGFMT_YV12 or IMGFMT_YUY2                     */
141 
142   int                        drawn;         /* used by decoder, frame has already been drawn */
143   int                        flags;         /* remember the frame flags */
144   int                        proc_called;   /* track use of proc_*() methods */
145 
146   /* Used to carry private data for accelerated plugins.*/
147   void                      *accel_data;
148 
149   /* "backward" references to where this frame originates from */
150   xine_video_port_t         *port;
151   vo_driver_t               *driver;
152   xine_stream_t             *stream;
153 
154   /* displacement for overlays */
155   int                       overlay_offset_x, overlay_offset_y;
156 
157   /* pointer to the next frame in display order, used by some vo deint */
158   struct vo_frame_s         *future_frame;
159 
160   /*
161    * that part is used only by video_out.c for frame management
162    * obs: changing anything here will require recompiling vo drivers
163    */
164   struct vo_frame_s         *next;
165 
166   int                        id; /* debugging - track this frame */
167   int                        is_first;
168 };
169 
170 
171 /*
172  * Remember that adding new functions to this structure requires
173  * adaption of the post plugin decoration layer. Be sure to look into
174  * src/xine-engine/post.[ch].
175  */
176 struct xine_video_port_s {
177 
178   uint32_t (*get_capabilities) (xine_video_port_t *self); /* for constants see below */
179 
180   /* open display driver for video output */
181   /* when you are not a full-blown stream, but still need to open the port
182    * (e.g. you are a post plugin) it is legal to pass an anonymous stream */
183   void (*open) (xine_video_port_t *self, xine_stream_t *stream);
184 
185   /*
186    * get_frame - allocate an image buffer from display driver
187    *
188    * params : width      == width of video to display.
189    *          height     == height of video to display.
190    *          ratio      == aspect ration information
191    *          format     == FOURCC descriptor of image format
192    *          flags      == field/prediction flags
193    */
194   vo_frame_t* (*get_frame) (xine_video_port_t *self, uint32_t width,
195 			    uint32_t height, double ratio,
196 			    int format, int flags);
197 
198   /* create a new grab video frame */
199   xine_grab_video_frame_t* (*new_grab_video_frame) (xine_video_port_t *self);
200 
201   /* retrieves the last displayed frame (useful for taking snapshots) */
202   vo_frame_t* (*get_last_frame) (xine_video_port_t *self);
203 
204   /* overlay stuff */
205   void (*enable_ovl) (xine_video_port_t *self, int ovl_enable);
206 
207   /* get overlay manager */
208   video_overlay_manager_t* (*get_overlay_manager) (xine_video_port_t *self);
209 
210   /* flush video_out fifo */
211   void (*flush) (xine_video_port_t *self);
212 
213   /* trigger immediate drawing */
214   void (*trigger_drawing) (xine_video_port_t *self);
215 
216   /* Get/Set video property
217    *
218    * See VO_PROP_* bellow
219    */
220   int (*get_property) (xine_video_port_t *self, int property);
221   int (*set_property) (xine_video_port_t *self, int property, int value);
222 
223   /* return true if port is opened for this stream, stream can be anonymous */
224   int (*status) (xine_video_port_t *self, xine_stream_t *stream,
225                  int *width, int *height, int64_t *img_duration);
226 
227   /* video driver is no longer used by decoder => close */
228   /* when you are not a full-blown stream, but still need to close the port
229    * (e.g. you are a post plugin) it is legal to pass an anonymous stream */
230   void (*close) (xine_video_port_t *self, xine_stream_t *stream);
231 
232   /* called on xine exit */
233   void (*exit) (xine_video_port_t *self);
234 
235   /* the driver in use */
236   vo_driver_t *driver;
237 
238 };
239 
240 /* constants for the get/set property functions */
241 #define VO_PROP_INTERLACED            0
242 #define VO_PROP_ASPECT_RATIO          1
243 #define VO_PROP_HUE                   2
244 #define VO_PROP_SATURATION            3
245 #define VO_PROP_CONTRAST              4
246 #define VO_PROP_BRIGHTNESS            5
247 #define VO_PROP_COLORKEY              6
248 #define VO_PROP_AUTOPAINT_COLORKEY    7
249 #define VO_PROP_ZOOM_X                8
250 #define VO_PROP_PAN_SCAN              9
251 #define VO_PROP_TVMODE		      10
252 #define VO_PROP_MAX_NUM_FRAMES        11
253 #define VO_PROP_GAMMA		      12
254 #define VO_PROP_ZOOM_Y                13
255 /* while this is set, vo shall drop all incoming and queued frames.
256  * when receiving a value of -1 for this, driver shall unref any held frames,
257  * and return their count. drivers not needing this will silently return
258  * -1 or 0.
259  */
260 #define VO_PROP_DISCARD_FRAMES        14
261 #define VO_PROP_WINDOW_WIDTH          15 /* read-only */
262 #define VO_PROP_WINDOW_HEIGHT         16 /* read-only */
263 #define VO_PROP_BUFS_IN_FIFO          17 /* read-only */
264 #define VO_PROP_NUM_STREAMS           18 /* read-only */
265 #define VO_PROP_OUTPUT_WIDTH          19 /* read-only */
266 #define VO_PROP_OUTPUT_HEIGHT         20 /* read-only */
267 #define VO_PROP_OUTPUT_XOFFSET        21 /* read-only */
268 #define VO_PROP_OUTPUT_YOFFSET        22 /* read-only */
269 #define VO_PROP_SHARPNESS             24
270 #define VO_PROP_NOISE_REDUCTION       25
271 #define VO_PROP_BUFS_TOTAL            26 /* read-only */
272 #define VO_PROP_BUFS_FREE             27 /* read-only */
273 #define VO_PROP_MAX_VIDEO_WIDTH       28 /* read-only */
274 #define VO_PROP_MAX_VIDEO_HEIGHT      29 /* read-only */
275 #define VO_NUM_PROPERTIES             30
276 
277 /* number of colors in the overlay palette. Currently limited to 256
278    at most, because some alphablend functions use an 8-bit index into
279    the palette. This should probably be classified as a bug. */
280 #define OVL_PALETTE_SIZE 256
281 
282 #define OVL_MAX_OPACITY  0x0f
283 
284 /* number of recent frames to keep in memory
285    these frames are needed by some deinterlace algorithms
286    FIXME: we need a method to flush the recent frames (new stream)
287 */
288 #define VO_NUM_RECENT_FRAMES     2
289 
290 /* get_frame flags */
291 #define VO_TOP_FIELD           0x0001
292 #define VO_BOTTOM_FIELD        0x0002
293 #define VO_BOTH_FIELDS         (VO_TOP_FIELD | VO_BOTTOM_FIELD)
294 #define VO_PAN_SCAN_FLAG       0x0004
295 #define VO_INTERLACED_FLAG     0x0008
296 #define VO_NEW_SEQUENCE_FLAG   0x0010 /* set after MPEG2 Sequence Header Code (used by XvMC) */
297 #define VO_CHROMA_422          0x0020 /* used by VDPAU, default is chroma_420 */
298 #define VO_STILL_IMAGE         0x0040
299 #define VO_GET_FRAME_MAY_FAIL  0x0080 /* video out may return NULL if frame allocation failed */
300 
301 /* ((mpeg_color_matrix << 1) | color_range) inside frame.flags bits 12-8 */
302 #define VO_FULLRANGE 0x100
303 #define VO_GET_FLAGS_CM(flags) ((flags >> 8) & 31)
304 #define VO_SET_FLAGS_CM(cm,flags) flags = ((flags) & ~0x1f00) | (((cm) & 31) << 8)
305 
306 /* video driver capabilities */
307 #define VO_CAP_YV12                   0x00000001 /* driver can handle YUV 4:2:0 pictures */
308 #define VO_CAP_YUY2                   0x00000002 /* driver can handle YUY2 pictures */
309 #define VO_CAP_XVMC_MOCOMP            0x00000004 /* driver can use XvMC motion compensation */
310 #define VO_CAP_XVMC_IDCT              0x00000008 /* driver can use XvMC idct acceleration   */
311 #define VO_CAP_UNSCALED_OVERLAY       0x00000010 /* driver can blend overlay at output resolution */
312 #define VO_CAP_CROP                   0x00000020 /* driver can crop */
313 #define VO_CAP_XXMC                   0x00000040 /* driver can use extended XvMC */
314 #define VO_CAP_VDPAU_H264             0x00000080 /* driver can use VDPAU for H264 */
315 #define VO_CAP_VDPAU_MPEG12           0x00000100 /* driver can use VDPAU for mpeg1/2 */
316 #define VO_CAP_VDPAU_VC1              0x00000200 /* driver can use VDPAU for VC1 */
317 #define VO_CAP_VDPAU_MPEG4            0x00000400 /* driver can use VDPAU for mpeg4-part2 */
318 #define VO_CAP_VAAPI                  0x00000800 /* driver can use VAAPI */
319 #define VO_CAP_COLOR_MATRIX           0x00004000 /* driver can use alternative yuv->rgb matrices */
320 #define VO_CAP_FULLRANGE              0x00008000 /* driver handles fullrange yuv */
321 #define VO_CAP_HUE                    0x00010000
322 #define VO_CAP_SATURATION             0x00020000
323 #define VO_CAP_CONTRAST               0x00040000
324 #define VO_CAP_BRIGHTNESS             0x00080000
325 #define VO_CAP_COLORKEY               0x00100000
326 #define VO_CAP_AUTOPAINT_COLORKEY     0x00200000
327 #define VO_CAP_ZOOM_X                 0x00400000
328 #define VO_CAP_ZOOM_Y                 0x00800000
329 #define VO_CAP_CUSTOM_EXTENT_OVERLAY  0x01000000 /* driver can blend custom extent overlay to output extent */
330 #define VO_CAP_ARGB_LAYER_OVERLAY     0x02000000 /* driver supports true color overlay */
331 #define VO_CAP_VIDEO_WINDOW_OVERLAY   0x04000000 /* driver can scale video to an area within overlay */
332 #define VO_CAP_GAMMA                  0x08000000
333 #define VO_CAP_SHARPNESS              0x10000000
334 #define VO_CAP_NOISE_REDUCTION        0x20000000
335 
336 
337 /*
338  * vo_driver_s contains the functions every display driver
339  * has to implement. The vo_new_port function (see below)
340  * should then be used to construct a vo_port using this
341  * driver. Some of the function pointers will be copied
342  * directly into xine_video_port_s, others will be called
343  * from generic vo functions.
344  */
345 
346 #define VIDEO_OUT_DRIVER_IFACE_VERSION  22
347 
348 struct vo_driver_s {
349 
350   uint32_t (*get_capabilities) (vo_driver_t *self); /* for constants see above */
351 
352   /*
353    * allocate an vo_frame_t struct,
354    * the driver must supply the copy, field and dispose functions
355    */
356   vo_frame_t* (*alloc_frame) (vo_driver_t *self);
357 
358   /*
359    * check if the given image fullfills the format specified
360    * (re-)allocate memory if necessary
361    */
362   void (*update_frame_format) (vo_driver_t *self, vo_frame_t *img,
363 			       uint32_t width, uint32_t height,
364 			       double ratio, int format, int flags);
365 
366   /* display a given frame */
367   void (*display_frame) (vo_driver_t *self, vo_frame_t *vo_img);
368 
369   /* overlay_begin and overlay_end are used by drivers suporting
370    * persistent overlays. they can be optimized to update only when
371    * overlay image has changed.
372    *
373    * sequence of operation (pseudo-code):
374    *   overlay_begin(this,img,true_if_something_changed_since_last_blend );
375    *   while(visible_overlays)
376    *     overlay_blend(this,img,overlay[i]);
377    *   overlay_end(this,img);
378    *
379    * any function pointer from this group may be set to NULL.
380    */
381   void (*overlay_begin) (vo_driver_t *self, vo_frame_t *vo_img, int changed);
382   void (*overlay_blend) (vo_driver_t *self, vo_frame_t *vo_img, vo_overlay_t *overlay);
383   void (*overlay_end)   (vo_driver_t *self, vo_frame_t *vo_img);
384 
385   /*
386    * these can be used by the gui directly:
387    */
388   int (*get_property) (vo_driver_t *self, int property);
389   int (*set_property) (vo_driver_t *self,
390 		       int property, int value);
391   void (*get_property_min_max) (vo_driver_t *self,
392 				int property, int *min, int *max);
393 
394   /*
395    * general purpose communication channel between gui and driver
396    *
397    * this should be used to propagate events, display data, window sizes
398    * etc. to the driver
399    */
400   int (*gui_data_exchange) (vo_driver_t *self, int data_type,
401 			    void *data);
402 
403   /* check if a redraw is needed (due to resize)
404    * this is only used for still frames, normal video playback
405    * must call that inside display_frame() function.
406    */
407   int (*redraw_needed) (vo_driver_t *self);
408 
409   /* Create a new grab video frame */
410   xine_grab_video_frame_t* (*new_grab_video_frame)(vo_driver_t *self);
411 
412   /*
413    * free all resources, close driver
414    */
415   void (*dispose) (vo_driver_t *self);
416 
417   /**
418    * @brief Pointer to the loaded plugin node.
419    *
420    * Used by the plugins loader. It's an opaque type when using the
421    * structure outside of xine's build.
422    */
423   struct plugin_node_s *node XINE_PRIVATE_FIELD;
424 };
425 
426 struct video_driver_class_s {
427 
428   /*
429    * open a new instance of this plugin class
430    */
431   vo_driver_t* (*open_plugin) (video_driver_class_t *self, const void *visual);
432 
433   /**
434    * @brief short human readable identifier for this plugin class
435    */
436   const char *identifier;
437 
438   /**
439    * @brief human readable (verbose = 1 line) description for this plugin class
440    *
441    * The description is passed to gettext() to internationalise.
442    */
443   const char *description;
444 
445   /**
446    * @brief Optional non-standard catalog to use with dgettext() for description.
447    */
448   const char *text_domain;
449 
450   /*
451    * free all class-related resources
452    */
453   void (*dispose) (video_driver_class_t *self);
454 };
455 
456 #define default_video_driver_class_dispose (void (*) (video_driver_class_t *this_gen))free
457 
458 typedef struct rle_elem_s {
459   uint16_t len;
460   uint16_t color;
461 } rle_elem_t;
462 
463 typedef struct argb_layer_s {
464   pthread_mutex_t  mutex;
465   uint32_t        *buffer;
466   /* dirty area */
467   int x1, y1;
468   int x2, y2;
469   int ref_count;
470 } argb_layer_t;
471 
472 struct vo_overlay_s {
473 
474   rle_elem_t       *rle;           /* rle code buffer                  */
475   int               data_size;     /* useful for deciding realloc      */
476   int               num_rle;       /* number of active rle codes       */
477   int               x;             /* x start of subpicture area       */
478   int               y;             /* y start of subpicture area       */
479   int               width;         /* width of subpicture area         */
480   int               height;        /* height of subpicture area        */
481 
482   /* area within osd extent to scale video to */
483   int               video_window_x;
484   int               video_window_y;
485   int               video_window_width;
486   int               video_window_height;
487 
488   /* extent of reference coordinate system */
489   int               extent_width;
490   int               extent_height;
491 
492   uint32_t          color[OVL_PALETTE_SIZE];  /* color lookup table     */
493   uint8_t           trans[OVL_PALETTE_SIZE];  /* mixer key table        */
494   int               rgb_clut;      /* true if clut was converted to rgb */
495 
496   /* define a highlight area with different colors */
497   int               hili_top;
498   int               hili_bottom;
499   int               hili_left;
500   int               hili_right;
501   uint32_t          hili_color[OVL_PALETTE_SIZE];
502   uint8_t           hili_trans[OVL_PALETTE_SIZE];
503   int               hili_rgb_clut; /* true if clut was converted to rgb */
504 
505   int               unscaled;      /* true if it should be blended unscaled */
506 
507   argb_layer_t     *argb_layer;
508 };
509 
510 void set_argb_layer_ptr(argb_layer_t **dst, argb_layer_t *src);
511 
512 /* API to video_overlay manager
513  *
514  * Remember that adding new functions to this structure requires
515  * adaption of the post plugin decoration layer. Be sure to look into
516  * src/xine-engine/post.[ch].
517  */
518 struct video_overlay_manager_s {
519   void (*init) (video_overlay_manager_t *this_gen);
520 
521   void (*dispose) (video_overlay_manager_t *this_gen);
522 
523   int32_t (*get_handle) (video_overlay_manager_t *this_gen, int object_type );
524 
525   void (*free_handle) (video_overlay_manager_t *this_gen, int32_t handle);
526 
527   int32_t (*add_event) (video_overlay_manager_t *this_gen, void *event);
528 
529   void (*flush_events) (video_overlay_manager_t *this_gen );
530 
531   int (*redraw_needed) (video_overlay_manager_t *this_gen, int64_t vpts );
532 
533   void (*multiple_overlay_blend) (video_overlay_manager_t *this_gen, int64_t vpts,
534                                   vo_driver_t *output, vo_frame_t *vo_img, int enabled);
535 };
536 
537 /**
538  * @brief Build a video output port from a given video driver.
539  *
540  * @internal
541  */
542 xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly);
543 
544 #ifdef __cplusplus
545 }
546 #endif
547 
548 #endif
549 
550