1 /*
2  * Copyright (C) 2000-2020 the xine project
3  * Copyright (C) 2004 the unichrome project
4  *
5  * This file is part of xine, a free video player.
6  *
7  * xine is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * xine is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20  *
21  * video_out_xxmc.c, X11 decoding accelerated video extension interface for xine
22  *
23  * based on mpeg2dec code from
24  * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
25  *
26  * Xv image support by Gerd Knorr <kraxel@goldbach.in-berlin.de>
27  *
28  * xine-specific code by Guenter Bartsch <bartscgr@studbox.uni-stuttgart.de>
29  *
30  * overlay support by James Courtier-Dutton <James@superbug.demon.co.uk> - July 2001
31  * X11 unscaled overlay support by Miguel Freitas - Nov 2003
32  * XxMC implementation by Thomas Hellström - August 2004
33  */
34 
35 #ifndef _XXMC_H
36 #define _XXMC_H
37 
38 #define XVMC_THREAD_SAFE
39 
40 /*
41  * some implementations are not aware of the display having been locked
42  * already before calling the xvmc function and may therefore deadlock.
43  */
44 /*
45 #define XVMC_LOCKDISPLAY_SAFE
46 */
47 
48 #if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__)
49 #  error config.h not included
50 #endif
51 
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <errno.h>
56 #include <math.h>
57 
58 #if defined (__SVR4) && defined (__sun)
59 # include <sys/int_types.h>
60 #else
61 # include <stdint.h>
62 #endif
63 
64 #include <sys/types.h>
65 #if defined(__FreeBSD__)
66 #include <machine/param.h>
67 #endif
68 #include <sys/ipc.h>
69 #include <sys/shm.h>
70 #include <sys/time.h>
71 
72 #include <X11/Xlib.h>
73 #include <X11/Xutil.h>
74 #include <X11/cursorfont.h>
75 #include <X11/extensions/XShm.h>
76 #include <X11/extensions/Xv.h>
77 #include <X11/extensions/Xvlib.h>
78 #include <X11/extensions/XvMClib.h>
79 #ifdef HAVE_VLDXVMC
80   #include <X11/extensions/vldXvMC.h>
81 #endif
82 
83 #define LOG_MODULE "video_out_xxmc"
84 #define LOG_VERBOSE
85 /*
86 #define LOG
87 */
88 
89 #include "xine.h"
90 #include <xine/video_out.h>
91 #include <xine/xine_internal.h>
92 #include <xine/xineutils.h>
93 #include <xine/vo_scale.h>
94 #include "x11osd.h"
95 #include "accel_xvmc.h"
96 
97 #define FOURCC_IA44 0x34344149
98 #define FOURCC_AI44 0x34344941
99 #define XVMC_MAX_SURFACES 16
100 #define XVMC_MAX_SUBPICTURES 4
101 
102 typedef struct xxmc_driver_s xxmc_driver_t;
103 
104 typedef struct {
105   xine_macroblocks_t   xine_mc;
106   XvMCBlockArray       blocks;            /* pointer to memory for dct block array  */
107   int                  num_blocks;
108   XvMCMacroBlock      *macroblockptr;     /* pointer to current macro block         */
109   XvMCMacroBlock      *macroblockbaseptr; /* pointer to base MacroBlock in MB array */
110   XvMCMacroBlockArray  macro_blocks;      /* pointer to memory for macroblock array */
111   int                  slices;
112 } xvmc_macroblocks_t;
113 
114 
115 typedef struct {
116   int                value;
117   int                min;
118   int                max;
119   Atom               atom;
120 
121   cfg_entry_t       *entry;
122 
123   xxmc_driver_t     *this;
124 } xxmc_property_t;
125 
126 typedef struct {
127   vo_frame_t         vo_frame;
128 
129   int                width, height, format;
130   double             ratio;
131 
132   XvImage           *image;
133   XShmSegmentInfo    shminfo;
134 
135   /* XvMC specific stuff */
136 
137   XvMCSurface       *xvmc_surf;
138   xine_xxmc_t        xxmc_data;
139   int                last_sw_format;
140 } xxmc_frame_t;
141 
142 typedef struct{
143   unsigned int       mpeg_flags;
144   unsigned int       accel_flags;
145   unsigned int       max_width;
146   unsigned int       max_height;
147   unsigned int       sub_max_width;
148   unsigned int       sub_max_height;
149   int                type_id;
150   XvImageFormatValues subPicType;
151   int                flags;
152 } xvmc_capabilities_t;
153 
154 typedef struct xvmc_surface_handler_s {
155   XvMCSurface surfaces[XVMC_MAX_SURFACES];
156   int surfInUse[XVMC_MAX_SURFACES];
157   int surfValid[XVMC_MAX_SURFACES];
158   XvMCSubpicture subpictures[XVMC_MAX_SUBPICTURES];
159   int subInUse[XVMC_MAX_SUBPICTURES];
160   int subValid[XVMC_MAX_SUBPICTURES];
161   pthread_mutex_t mutex;
162 } xvmc_surface_handler_t;
163 
164 typedef struct context_lock_s {
165   pthread_mutex_t mutex;
166   pthread_cond_t cond;
167   int num_readers;
168 } context_lock_t;
169 
170 #define LOCK_AND_SURFACE_VALID(driver, surface)			\
171   xvmc_context_reader_lock( &(driver)->xvmc_lock );		\
172   if (!xxmc_xvmc_surface_valid((driver),(surface))) {		\
173     xvmc_context_reader_unlock( &(driver)->xvmc_lock );		\
174     return;							\
175   }
176 
177 #if defined(XVMC_THREAD_SAFE) && defined(XVMC_LOCKDISPLAY_SAFE)
178 #define XVMCLOCKDISPLAY(display)
179 #define XVMCUNLOCKDISPLAY(display)
180 #else
181 #define XVMCLOCKDISPLAY(display) XLockDisplay(display)
182 #define XVMCUNLOCKDISPLAY(display) XUnlockDisplay(display)
183 #endif
184 
185 struct xxmc_driver_s {
186   vo_driver_t        vo_driver;
187 
188   config_values_t    *config;
189 
190   /* X11 / Xv related stuff */
191   Display            *display;
192   int                screen;
193   Drawable           drawable;
194   unsigned int       xv_format_yv12;
195   unsigned int       xv_format_yuy2;
196   XVisualInfo        vinfo;
197   GC                 gc;
198   XvPortID           xv_port;
199   XColor             black;
200 
201   int                use_shm;
202   int                use_pitch_alignment;
203   xxmc_property_t    props[VO_NUM_PROPERTIES];
204   uint32_t           capabilities;
205   xxmc_frame_t       *recent_frames[VO_NUM_RECENT_FRAMES];
206   xxmc_frame_t       *cur_frame;
207   int                cur_field;
208   int                bob;
209   int                disable_bob_for_progressive_frames;
210   int                disable_bob_for_scaled_osd;
211   int                scaled_osd_active;
212   x11osd             *xoverlay;
213   int                xv_xoverlay_type;
214   int                xoverlay_type;
215   int                ovl_changed;
216 
217   /* all scaling information goes here */
218   vo_scale_t         sc;
219   int                deinterlace_enabled;
220   int                use_colorkey;
221   uint32_t           colorkey;
222   int                (*x11_old_error_handler)  (Display *, XErrorEvent *);
223   xine_t             *xine;
224 
225   /* XvMC related stuff here */
226   xvmc_macroblocks_t   macroblocks;
227   xvmc_capabilities_t  *xvmc_cap;
228   unsigned           xvmc_num_cap;
229   unsigned int       xvmc_max_subpic_x;
230   unsigned int       xvmc_max_subpic_y;
231   int                xvmc_eventbase;
232   int                xvmc_errbase;
233   int                hwSubpictures;
234   XvMCSubpicture     *old_subpic,*new_subpic;
235   xx44_palette_t     palette;
236   int                first_overlay;
237   float              cpu_saver;
238   int                cpu_save_enabled;
239   int                reverse_nvidia_palette;
240   int                context_flags;
241 
242   /*
243    * These variables are protected by the context lock:
244    */
245 
246   unsigned           xvmc_cur_cap;
247   int                xvmc_backend_subpic;
248   XvMCContext        context;
249   int                contextActive;
250   xvmc_surface_handler_t xvmc_surf_handler;
251   unsigned           xvmc_mpeg;
252   unsigned           xvmc_accel;
253   unsigned           last_accel_request;
254   unsigned           xvmc_width;
255   unsigned           xvmc_height;
256   int                have_xvmc_autopaint;
257   int                xvmc_xoverlay_type;
258   int                unsigned_intra;
259 
260   /*
261    * Only creation and destruction of the below.
262    */
263 
264   char               *xvmc_palette;
265   XvImage            *subImage;
266   XShmSegmentInfo    subShmInfo;
267 
268   /*
269    * The mutex below is needed since XlockDisplay wasn't really enough
270    * to protect the XvMC Calls.
271    */
272   context_lock_t     xvmc_lock;
273 
274   alphablend_t       alphablend_extra_data;
275 };
276 
277 typedef struct {
278   video_driver_class_t driver_class;
279 
280   xine_t              *xine;
281 } xxmc_class_t;
282 
283 extern void xvmc_context_reader_unlock(context_lock_t *c);
284 extern void xvmc_context_reader_lock(context_lock_t *c);
285 extern int xxmc_xvmc_surface_valid(xxmc_driver_t *this, XvMCSurface *surf);
286 
287 extern void xvmc_vld_slice(vo_frame_t *this_gen);
288 extern void xvmc_vld_frame(struct vo_frame_s *this_gen);
289 
290 extern void xxmc_xvmc_proc_macro_block(int x, int y, int mb_type, int motion_type,
291 				       int (*mv_field_sel)[2], int *dmvector,
292 				       int cbp,
293 				       int dct_type, vo_frame_t *current_frame,
294 				       vo_frame_t *forward_ref_frame,
295 				       vo_frame_t *backward_ref_frame,
296 				       int picture_structure,
297 				       int second_field, int (*f_mot_pmv)[2],
298 				       int (*b_mot_pmv)[2]);
299 
300 #endif
301