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>
30 #include <X11/extensions/Xvlib.h>
32 #include "bcwindowbase.inc"
33 #include "bcbitmap.inc"
34 #include "bccmodels.h"
36 #include "condition.h"
42 #define MIN_BITMAP_BUFFERS 4
43 #define MAX_BITMAP_BUFFERS 32
47 class BC_BitmapImage : public ListItem<BC_BitmapImage> {
50 union { XImage *ximage; XvImage *xv_image; };
51 BC_WindowBase *top_level;
54 unsigned char **row_data;
58 friend class BC_Bitmap;
59 friend class BC_XImage;
60 friend class BC_XShmImage;
61 friend class BC_XvImage;
62 friend class BC_XvShmImage;
63 friend class BC_ActiveBitmaps;
65 int read_frame_rgb(VFrame* frame);
67 BC_BitmapImage(BC_Bitmap *bitmap, int index);
68 virtual ~BC_BitmapImage();
69 unsigned char *get_data() { return data; }
70 unsigned char **get_row_data() { return row_data; }
71 virtual long get_data_size() { return dataSize; }
72 int bits_per_pixel() { return bitsPerPixel; }
73 long bytes_per_line() { return bytesPerLine; }
74 virtual long xv_offset(int i) { return 0; }
75 virtual unsigned char* xv_plane(int i) { return 0; }
76 virtual int get_shmid() { return 0; }
77 virtual ShmSeg get_shmseg() { return 0; }
78 long get_y_offset() { return xv_offset(0); }
79 long get_u_offset() { return xv_offset(2); }
80 long get_v_offset() { return xv_offset(1); }
81 unsigned char *get_y_data() { return xv_plane(0); }
82 unsigned char *get_u_data() { return xv_plane(2); }
83 unsigned char *get_v_data() { return xv_plane(1); }
84 virtual int write_drawable(Drawable &pixmap, GC &gc,
85 int source_x, int source_y, int source_w, int source_h,
86 int dest_x, int dest_y, int dest_w, int dest_h) {
89 virtual int read_drawable(Drawable &pixmap, int source_x, int source_y) {
93 bool is_zombie() { return index < 0; }
97 class BC_XImage : public BC_BitmapImage {
99 BC_XImage(BC_Bitmap *bitmap, int idx, int w,int h, int color_model);
101 int write_drawable(Drawable &pixmap, GC &gc,
102 int source_x, int source_y, int source_w, int source_h,
103 int dest_x, int dest_y, int dest_w, int dest_h);
104 int read_drawable(Drawable &pixmap, int source_x, int source_y);
107 class BC_XShmImage : public BC_BitmapImage {
108 XShmSegmentInfo shm_info;
109 long shm_offset(int i) { return 0; }
110 //long shm_offset(int i) {
111 // return (h*ximage->bytes_per_line) * BC_BitmapImage::index;
114 BC_XShmImage(BC_Bitmap *bitmap, int idx, int w,int h, int color_model);
116 int get_shmid() { return shm_info.shmid; }
117 ShmSeg get_shmseg() { return shm_info.shmseg; }
119 int write_drawable(Drawable &pixmap, GC &gc,
120 int source_x, int source_y, int source_w, int source_h,
121 int dest_x, int dest_y, int dest_w, int dest_h);
122 int read_drawable(Drawable &pixmap, int source_x, int source_y);
125 class BC_XvImage : public BC_BitmapImage {
126 long xv_offset(int i) { return xv_image->offsets[i]; }
127 unsigned char* xv_plane(int i) { return get_data() + xv_offset(i); }
129 BC_XvImage(BC_Bitmap *bitmap, int idx, int w,int h, int color_model);
131 int write_drawable(Drawable &pixmap, GC &gc,
132 int source_x, int source_y, int source_w, int source_h,
133 int dest_x, int dest_y, int dest_w, int dest_h);
136 class BC_XvShmImage : public BC_BitmapImage {
137 XShmSegmentInfo shm_info;
138 long shm_offset(int i) { return 0; }
139 //long shm_offset(int i) {
140 // return xv_image->data_size*BC_BitmapImage::index;
142 long xv_offset(int i) { return shm_offset(i) + xv_image->offsets[i]; }
143 unsigned char* xv_plane(int i) { return data + xv_offset(i); }
145 BC_XvShmImage(BC_Bitmap *bitmap, int idx, int w,int h, int color_model);
147 int get_shmid() { return shm_info.shmid; }
148 ShmSeg get_shmseg() { return shm_info.shmseg; }
149 int get_shm_size() { return xv_image->data_size; }
150 int write_drawable(Drawable &pixmap, GC &gc,
151 int source_x, int source_y, int source_w, int source_h,
152 int dest_x, int dest_y, int dest_w, int dest_h);
159 friend class BC_XImage;
160 friend class BC_XShmImage;
161 friend class BC_XvImage;
162 friend class BC_XvShmImage;
163 friend class BC_BitmapImage;
164 friend class BC_ActiveBitmaps;
165 int buffer_count, max_buffer_count;
167 static int max_active_buffers;
172 int initialize(BC_WindowBase *parent_window, int w, int h, int color_model, int use_shm);
173 BC_BitmapImage *new_buffer(int type, int idx);
174 void update_buffers(int count, int lock_avail=1);
177 int get_default_depth();
178 long best_buffer_size();
181 // Background color for using pngs
183 // Override top_level for small bitmaps
185 BC_WindowBase *top_level;
186 BC_WindowBase *parent_window;
188 // For resetting XVideo
189 int last_pixmap_used;
191 // Need last pixmap to stop XVideo
192 Drawable last_pixmap;
194 static uint8_t bitswap[256];
195 void transparency_bitswap(uint8_t *buf, int w, int h);
197 enum { bmXNone, bmXImage, bmXShmImage, bmXvImage, bmXvShmImage };
199 BC_Bitmap(BC_WindowBase *parent_window, unsigned char *png_data, double scale=1);
200 BC_Bitmap(BC_WindowBase *parent_window, VFrame *frame);
202 // Shared memory is a problem in X because it's asynchronous and there's
203 // no easy way to join with the blitting process.
204 BC_Bitmap(BC_WindowBase *parent_window, int w, int h,
205 int color_model, int use_shm = 1);
206 virtual ~BC_Bitmap();
209 int read_frame(VFrame *frame,
210 int in_x, int in_y, int in_w, int in_h,
211 int out_x, int out_y, int out_w, int out_h);
212 // x1, y1, x2, y2 dimensions of output area
213 int read_frame(VFrame *frame,
214 int x1, int y1, int x2, int y2);
215 // Reset bitmap to match the new parameters
216 int match_params(int w, int h, int color_model, int use_shm);
217 // Test if bitmap already matches parameters
218 int params_match(int w, int h, int color_model, int use_shm);
220 // If dont_wait is true, the XSync comes before the flash.
221 // For YUV bitmaps, the image is scaled to fill dest_x ... w * dest_y ... h
222 int write_drawable(Drawable &pixmap, GC &gc,
223 int source_x, int source_y, int source_w, int source_h,
224 int dest_x, int dest_y, int dest_w, int dest_h,
226 int write_drawable(Drawable &pixmap, GC &gc,
227 int dest_x, int dest_y, int source_x, int source_y,
228 int dest_w, int dest_h, int dont_wait);
229 // the bitmap must be wholly contained in the source during a GetImage
230 int read_drawable(Drawable &pixmap, int source_x, int source_y, VFrame *frame=0);
232 int rotate_90(int side);
233 // Data pointers for current ring buffer
234 BC_BitmapImage **buffers;
236 List<BC_BitmapImage> avail;
237 void reque(BC_BitmapImage *bfr);
238 BC_BitmapImage *cur_bfr(), *active_bfr;
239 unsigned char* get_data() { return cur_bfr()->get_data(); }
240 unsigned char** get_row_pointers() { return cur_bfr()->get_row_data(); }
241 long get_data_size() { return cur_bfr()->get_data_size(); }
242 int get_shmid() { return cur_bfr()->get_shmid(); }
243 unsigned char *get_y_plane() { return cur_bfr()->get_y_data(); }
244 unsigned char *get_u_plane() { return cur_bfr()->get_u_data(); }
245 unsigned char *get_v_plane() { return cur_bfr()->get_v_data(); }
246 long get_y_offset() { return cur_bfr()->get_y_offset(); }
247 long get_u_offset() { return cur_bfr()->get_u_offset(); }
248 long get_v_offset() { return cur_bfr()->get_v_offset(); }
249 int get_color_model() { return color_model; }
250 int hardware_scaling() {
251 return xv_portid < 0 ? 0 :
252 (get_color_model() == BC_YUV420P ||
253 get_color_model() == BC_YUV422P ||
254 get_color_model() == BC_YUV422) ? 1 : 0;
256 int get_w() { return w; }
257 int get_h() { return h; }
259 int get_image_type() { return type; }
260 int is_xvideo() { return type==bmXvShmImage || type==bmXvImage; }
261 int is_xwindow() { return type==bmXShmImage || type==bmXImage; }
262 int is_shared() { return type==bmXvShmImage || type==bmXShmImage; }
263 int is_unshared() { return type==bmXvImage || type==bmXImage; }
265 int set_bg_color(int color);