5 #include "colormodels.h"
7 #include "playbackconfig.h"
8 #include "preferences.h"
9 #include "recordconfig.h"
10 #include "strategies.inc"
11 #include "vdevicex11.h"
13 #include "videodevice.h"
14 #include "videowindow.h"
15 #include "videowindowgui.h"
20 VDeviceX11::VDeviceX11(VideoDevice *device, Canvas *output)
24 this->output = output;
27 VDeviceX11::~VDeviceX11()
32 int VDeviceX11::reset_parameters()
48 color_model_selected = 0;
52 int VDeviceX11::open_input()
54 //printf("VDeviceX11::open_input 1\n");
55 capture_bitmap = new BC_Capture(device->in_config->w,
57 device->in_config->screencapture_display);
58 //printf("VDeviceX11::open_input 2\n");
63 int VDeviceX11::open_output()
67 output->canvas->lock_window("VDeviceX11::open_output");
68 if(!device->single_frame)
69 output->start_video();
71 output->start_single();
72 output->canvas->unlock_window();
78 int VDeviceX11::output_visible()
80 if(!output || output->canvas->get_hidden())
87 int VDeviceX11::close_all()
91 output->canvas->lock_window("VDeviceX11::close_all");
94 if(output && output_frame)
96 // We need to copy when the memory is shared, which is when bimap_type is primary
97 if (bitmap && bitmap_type == BITMAP_PRIMARY)
99 if(output->refresh_frame &&
100 (output->refresh_frame->get_w() != device->out_w ||
101 output->refresh_frame->get_h() != device->out_h ||
102 output->refresh_frame->get_color_model() != output_frame->get_color_model()))
104 delete output->refresh_frame;
105 output->refresh_frame = 0;
108 if(!output->refresh_frame)
110 output->refresh_frame = new VFrame(0,
113 output_frame->get_color_model());
116 output->refresh_frame->copy_from(output_frame);
120 if(output->refresh_frame)
121 delete output->refresh_frame;
123 output->refresh_frame = output_frame;
127 if(!device->single_frame)
128 output->stop_video();
130 output->stop_single();
131 output->draw_refresh();
145 if(capture_bitmap) delete capture_bitmap;
149 output->canvas->unlock_window();
157 int VDeviceX11::read_buffer(VFrame *frame)
159 capture_bitmap->capture_frame(frame, device->input_x, device->input_y);
164 int VDeviceX11::get_best_colormodel(Asset *asset)
170 int VDeviceX11::get_best_colormodel(int colormodel)
173 if(!device->single_frame)
192 case BC_RGBA16161616:
196 case BC_YUVA16161616:
201 result = output->canvas->get_color_model();
206 //printf("VDeviceX11::get_best_colormodel %d %d %d\n", device->single_frame, colormodel, result);
211 void VDeviceX11::new_output_buffer(VFrame **output_channels, int colormodel)
213 for(int i = 0; i < MAX_CHANNELS; i++)
214 output_channels[i] = 0;
215 //printf("VDeviceX11::new_output_buffer 1\n");
217 // Get the best colormodel the display can handle.
218 int best_colormodel = get_best_colormodel(colormodel);
219 //printf("VDeviceX11::new_output_buffer 2 %d\n", best_colormodel);
221 // Conform existing bitmap to new colormodel and output size
224 // Restart if output size changed or output colormodel changed
225 if(!color_model_selected ||
226 (!bitmap->hardware_scaling() &&
227 (bitmap->get_w() != output->canvas->get_w() ||
228 bitmap->get_h() != output->canvas->get_h())) ||
229 colormodel != output_frame->get_color_model())
231 int size_change = (bitmap->get_w() != output->canvas->get_w() ||
232 bitmap->get_h() != output->canvas->get_h());
238 // Blank only if size changed
241 output->canvas->set_color(BLACK);
242 output->canvas->draw_box(0, 0, output->w, output->h);
243 output->canvas->flash();
247 // Update the ring buffer
248 if(bitmap_type == BITMAP_PRIMARY)
251 //printf("VDeviceX11::new_output_buffer\n");
252 output_frame->set_memory((unsigned char*)bitmap->get_data() /* + bitmap->get_shm_offset() */,
253 bitmap->get_y_offset(),
254 bitmap->get_u_offset(),
255 bitmap->get_v_offset());
262 //printf("VDeviceX11::new_output_buffer 1 %d\n", best_colormodel);
263 // Try hardware accelerated
264 switch(best_colormodel)
267 if(device->out_config->driver == PLAYBACK_X11_XV &&
268 output->canvas->accel_available(best_colormodel))
270 bitmap = new BC_Bitmap(output->canvas,
275 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
276 bitmap->get_y_offset(),
277 bitmap->get_u_offset(),
278 bitmap->get_v_offset(),
282 bitmap_type = BITMAP_PRIMARY;
287 if(device->out_config->driver == PLAYBACK_X11_XV &&
288 output->canvas->accel_available(best_colormodel))
290 bitmap = new BC_Bitmap(output->canvas,
295 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
296 bitmap->get_y_offset(),
297 bitmap->get_u_offset(),
298 bitmap->get_v_offset(),
302 bitmap_type = BITMAP_PRIMARY;
305 if(device->out_config->driver == PLAYBACK_X11_XV &&
306 output->canvas->accel_available(BC_YUV422))
308 bitmap = new BC_Bitmap(output->canvas,
313 bitmap_type = BITMAP_TEMP;
318 //printf("VDeviceX11::new_output_buffer 3\n");
319 if(device->out_config->driver == PLAYBACK_X11_XV &&
320 output->canvas->accel_available(best_colormodel))
322 //printf("VDeviceX11::new_output_buffer 4\n");
323 bitmap = new BC_Bitmap(output->canvas,
328 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
329 bitmap->get_y_offset(),
330 bitmap->get_u_offset(),
331 bitmap->get_v_offset(),
335 bitmap_type = BITMAP_PRIMARY;
338 if(device->out_config->driver == PLAYBACK_X11_XV &&
339 output->canvas->accel_available(BC_YUV422P))
341 //printf("VDeviceX11::new_output_buffer 5\n");
342 bitmap = new BC_Bitmap(output->canvas,
347 //printf("VDeviceX11::new_output_buffer 6\n");
348 bitmap_type = BITMAP_TEMP;
349 //printf("VDeviceX11::new_output_buffer 7\n");
353 //printf("VDeviceX11::new_output_buffer 8\n");
355 // Not accelerated --- use specified Format/Video/Color model instead
358 best_colormodel = output->canvas->get_color_model();
359 bitmap = new BC_Bitmap(output->canvas,
360 output->canvas->get_w(),
361 output->canvas->get_h(),
364 bitmap_type = BITMAP_TEMP;
365 //printf("VDeviceX11::new_output_buffer 9\n");
368 if(bitmap_type == BITMAP_TEMP)
370 // Intermediate frame
371 output_frame = new VFrame(0,
375 bitmap_type = BITMAP_TEMP;
376 //printf("VDeviceX11::new_output_buffer 10\n");
378 color_model_selected = 1;
380 //printf("VDeviceX11::new_output_buffer 11\n");
383 if(bitmap_type == BITMAP_PRIMARY)
385 // Only useful if the primary is RGB888 which XFree86 never uses.
386 output_frame->set_shm_offset(bitmap->get_shm_offset());
389 if(bitmap_type == BITMAP_TEMP)
391 output_frame->set_shm_offset(0);
393 //printf("VDeviceX11::new_output_buffer 12\n");
395 // Temporary until multichannel X
396 output_channels[0] = output_frame;
400 int VDeviceX11::start_playback()
402 // Record window is initialized when its monitor starts.
403 if(!device->single_frame)
404 output->start_video();
408 int VDeviceX11::stop_playback()
410 if(!device->single_frame)
411 output->stop_video();
412 // Record window goes back to monitoring
413 // get the last frame played and store it in the video_out
417 int VDeviceX11::write_buffer(VFrame **output_channels, EDL *edl)
421 // The reason for not drawing single frame is that it is _always_ drawn
422 // when drawing draw_refresh in cwindowgui and vwindowgui
423 if (device->single_frame)
426 //printf("VDeviceX11::write_buffer 1\n");
427 output->canvas->lock_window("VDeviceX11::write_buffer");
428 //printf("VDeviceX11::write_buffer 2\n");
429 output->get_transfers(edl,
438 (bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) ? bitmap->get_w() : -1,
439 (bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) ? bitmap->get_h() : -1);
441 //output->canvas->unlock_window();
443 // printf("VDeviceX11::write_buffer 2 %d\n", bitmap_type);
444 // for(int j = 0; j < output_channels[0]->get_w() * 3 * 5; j++)
445 // output_channels[0]->get_rows()[0][j] = 255;
447 // Convert colormodel
448 if(bitmap_type == BITMAP_TEMP)
450 // printf("VDeviceX11::write_buffer 1 %d %d, %d %d %d %d -> %d %d %d %d\n",
460 // out_h );fflush(stdout);
462 //printf("VDeviceX11::write_buffer 2\n");
464 //printf("VDeviceX11::write_buffer 3 %p %p\n", bitmap->get_row_pointers(), output_channels[0]->get_rows());
466 if(bitmap->hardware_scaling())
468 cmodel_transfer(bitmap->get_row_pointers(),
469 output_channels[0]->get_rows(),
473 output_channels[0]->get_y(),
474 output_channels[0]->get_u(),
475 output_channels[0]->get_v(),
478 output_channels[0]->get_w(),
479 output_channels[0]->get_h(),
484 output_channels[0]->get_color_model(),
485 bitmap->get_color_model(),
487 output_channels[0]->get_w(),
492 cmodel_transfer(bitmap->get_row_pointers(),
493 output_channels[0]->get_rows(),
497 output_channels[0]->get_y(),
498 output_channels[0]->get_u(),
499 output_channels[0]->get_v(),
508 output_channels[0]->get_color_model(),
509 bitmap->get_color_model(),
511 output_channels[0]->get_w(),
516 //printf("VDeviceX11::write_buffer 4 %p\n", bitmap);
517 //for(i = 0; i < 1000; i += 4) bitmap->get_data()[i] = 128;
518 //printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type,
519 // bitmap->get_color_model(),
520 // output->get_color_model());fflush(stdout);
521 // printf("VDeviceX11::write_buffer 2 %d %d, %d %d %d %d -> %d %d %d %d\n",
534 // Select field if using field mode. This may be a useful feature later on
535 // but currently it's being superceded by the heroine 60 encoding.
536 // Doing time base conversion in the display routine produces
537 // pretty big compression artifacts. It also requires implementing a
538 // different transform for each X visual.
539 if(device->out_config->x11_use_fields)
545 // Cause X server to display it
546 if(bitmap->hardware_scaling())
548 output->canvas->draw_bitmap(bitmap,
549 !device->single_frame,
562 output->canvas->draw_bitmap(bitmap,
563 !device->single_frame,
576 output->canvas->unlock_window();