4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program 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.
11 * This program 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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #ifndef __BCBITMAP_H__
23 #define __BCBITMAP_H__
29 #include <X11/extensions/XShm.h>
31 #include <X11/extensions/Xvlib.h>
33 typedef struct _XvImage XvImage;
36 #include "bcwindowbase.inc"
37 #include "bcbitmap.inc"
38 #include "bccmodels.h"
40 #include "condition.h"
46 #define MIN_BITMAP_BUFFERS 4
47 #define MAX_BITMAP_BUFFERS 32
51 class BC_BitmapImage : public ListItem<BC_BitmapImage> {
54 union { XImage *ximage; XvImage *xv_image; };
55 BC_WindowBase *top_level;
58 unsigned char **row_data;
62 friend class BC_Bitmap;
63 friend class BC_XImage;
64 friend class BC_XShmImage;
66 friend class BC_XvImage;
67 friend class BC_XvShmImage;
69 friend class BC_ActiveBitmaps;
71 int read_frame_rgb(VFrame* frame);
73 BC_BitmapImage(BC_Bitmap *bitmap, int index);
74 virtual ~BC_BitmapImage();
75 unsigned char *get_data() { return data; }
76 unsigned char **get_row_data() { return row_data; }
77 virtual long get_data_size() { return dataSize; }
78 int bits_per_pixel() { return bitsPerPixel; }
79 long bytes_per_line() { return bytesPerLine; }
80 virtual long xv_offset(int i) { return 0; }
81 virtual unsigned char* xv_plane(int i) { return 0; }
82 virtual int get_shmid() { return 0; }
83 virtual ShmSeg get_shmseg() { return 0; }
84 long get_y_offset() { return xv_offset(0); }
85 long get_u_offset() { return xv_offset(2); }
86 long get_v_offset() { return xv_offset(1); }
87 unsigned char *get_y_data() { return xv_plane(0); }
88 unsigned char *get_u_data() { return xv_plane(2); }
89 unsigned char *get_v_data() { return xv_plane(1); }
90 virtual int write_drawable(Drawable &pixmap, GC &gc,
91 int source_x, int source_y, int source_w, int source_h,
92 int dest_x, int dest_y, int dest_w, int dest_h) {
95 virtual int read_drawable(Drawable &pixmap, int source_x, int source_y) {
99 bool is_zombie() { return index < 0; }
103 class BC_XImage : public BC_BitmapImage {
105 BC_XImage(BC_Bitmap *bitmap, int idx, int w,int h, int color_model);
107 int write_drawable(Drawable &pixmap, GC &gc,
108 int source_x, int source_y, int source_w, int source_h,
109 int dest_x, int dest_y, int dest_w, int dest_h);
110 int read_drawable(Drawable &pixmap, int source_x, int source_y);
113 class BC_XShmImage : public BC_BitmapImage {
114 XShmSegmentInfo shm_info;
115 long shm_offset(int i) { return 0; }
116 //long shm_offset(int i) {
117 // return (h*ximage->bytes_per_line) * BC_BitmapImage::index;
120 BC_XShmImage(BC_Bitmap *bitmap, int idx, int w,int h, int color_model);
122 int get_shmid() { return shm_info.shmid; }
123 ShmSeg get_shmseg() { return shm_info.shmseg; }
125 int write_drawable(Drawable &pixmap, GC &gc,
126 int source_x, int source_y, int source_w, int source_h,
127 int dest_x, int dest_y, int dest_w, int dest_h);
128 int read_drawable(Drawable &pixmap, int source_x, int source_y);
132 class BC_XvImage : public BC_BitmapImage {
133 long xv_offset(int i) { return xv_image->offsets[i]; }
134 unsigned char* xv_plane(int i) { return get_data() + xv_offset(i); }
136 BC_XvImage(BC_Bitmap *bitmap, int idx, int w,int h, int color_model);
138 int write_drawable(Drawable &pixmap, GC &gc,
139 int source_x, int source_y, int source_w, int source_h,
140 int dest_x, int dest_y, int dest_w, int dest_h);
143 class BC_XvShmImage : public BC_BitmapImage {
144 XShmSegmentInfo shm_info;
145 long shm_offset(int i) { return 0; }
146 //long shm_offset(int i) {
147 // return xv_image->data_size*BC_BitmapImage::index;
149 long xv_offset(int i) { return shm_offset(i) + xv_image->offsets[i]; }
150 unsigned char* xv_plane(int i) { return data + xv_offset(i); }
152 BC_XvShmImage(BC_Bitmap *bitmap, int idx, int w,int h, int color_model);
154 int get_shmid() { return shm_info.shmid; }
155 ShmSeg get_shmseg() { return shm_info.shmseg; }
156 int get_shm_size() { return xv_image->data_size; }
157 int write_drawable(Drawable &pixmap, GC &gc,
158 int source_x, int source_y, int source_w, int source_h,
159 int dest_x, int dest_y, int dest_w, int dest_h);
166 friend class BC_XImage;
167 friend class BC_XShmImage;
169 friend class BC_XvImage;
170 friend class BC_XvShmImage;
172 friend class BC_BitmapImage;
173 friend class BC_ActiveBitmaps;
174 int buffer_count, max_buffer_count;
176 static int max_active_buffers;
181 int initialize(BC_WindowBase *parent_window, int w, int h, int color_model, int use_shm);
182 BC_BitmapImage *new_buffer(int type, int idx);
183 void update_buffers(int count, int lock_avail=1);
186 int get_default_depth();
187 long best_buffer_size();
190 // Override top_level for small bitmaps
192 BC_WindowBase *top_level;
193 BC_WindowBase *parent_window;
196 static uint8_t bitswap[256];
197 void transparency_bitswap(uint8_t *buf, int w, int h);
199 enum { bmXNone, bmXImage, bmXShmImage, bmXvImage, bmXvShmImage };
201 BC_Bitmap(BC_WindowBase *parent_window, unsigned char *png_data, double scale=1);
202 BC_Bitmap(BC_WindowBase *parent_window, VFrame *frame);
204 // Shared memory is a problem in X because it's asynchronous and there's
205 // no easy way to join with the blitting process.
206 BC_Bitmap(BC_WindowBase *parent_window, int w, int h,
207 int color_model, int use_shm = 1);
208 virtual ~BC_Bitmap();
211 int read_frame(VFrame *frame,
212 int in_x, int in_y, int in_w, int in_h,
213 int out_x, int out_y, int out_w, int out_h,
215 // x1, y1, x2, y2 dimensions of output area
216 int read_frame(VFrame *frame,
217 int x1, int y1, int x2, int y2);
218 int read_frame(VFrame *frame,
219 int x1, int y1, int x2, int y2, int bg_color);
220 // Reset bitmap to match the new parameters
221 int match_params(int w, int h, int color_model, int use_shm);
222 // Test if bitmap already matches parameters
223 int params_match(int w, int h, int color_model, int use_shm);
225 // If dont_wait is true, the XSync comes before the flash.
226 // For YUV bitmaps, the image is scaled to fill dest_x ... w * dest_y ... h
227 int write_drawable(Drawable &pixmap, GC &gc,
228 int source_x, int source_y, int source_w, int source_h,
229 int dest_x, int dest_y, int dest_w, int dest_h,
231 int write_drawable(Drawable &pixmap, GC &gc,
232 int dest_x, int dest_y, int source_x, int source_y,
233 int dest_w, int dest_h, int dont_wait);
234 // the bitmap must be wholly contained in the source during a GetImage
235 int read_drawable(Drawable &pixmap, int source_x, int source_y, VFrame *frame=0);
237 int rotate_90(int side);
238 // Data pointers for current ring buffer
239 BC_BitmapImage **buffers;
241 List<BC_BitmapImage> avail;
242 void reque(BC_BitmapImage *bfr);
243 BC_BitmapImage *cur_bfr(), *active_bfr;
244 unsigned char* get_data() { return cur_bfr()->get_data(); }
245 unsigned char** get_row_pointers() { return cur_bfr()->get_row_data(); }
246 long get_data_size() { return cur_bfr()->get_data_size(); }
247 int get_shmid() { return cur_bfr()->get_shmid(); }
248 unsigned char *get_y_plane() { return cur_bfr()->get_y_data(); }
249 unsigned char *get_u_plane() { return cur_bfr()->get_u_data(); }
250 unsigned char *get_v_plane() { return cur_bfr()->get_v_data(); }
251 long get_y_offset() { return cur_bfr()->get_y_offset(); }
252 long get_u_offset() { return cur_bfr()->get_u_offset(); }
253 long get_v_offset() { return cur_bfr()->get_v_offset(); }
254 int get_color_model() { return color_model; }
255 int hardware_scaling() {
256 return xv_portid < 0 ? 0 :
257 (get_color_model() == BC_YUV420P ||
258 // get_color_model() == BC_YUV422P || not in bc_to_x
259 get_color_model() == BC_YUV422) ? 1 : 0;
261 int get_w() { return w; }
262 int get_h() { return h; }
264 int get_image_type() { return type; }
265 int is_xvideo() { return type==bmXvShmImage || type==bmXvImage; }
266 int is_xwindow() { return type==bmXShmImage || type==bmXImage; }
267 int is_shared() { return type==bmXvShmImage || type==bmXShmImage; }
268 int is_unshared() { return type==bmXvImage || type==bmXImage; }
269 int is_zombie() { return cur_bfr()->is_zombie(); }