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 //TRACE("VDeviceX11::new_output_buffer 1");
215 output->canvas->lock_window("VDeviceX11::new_output_buffer");
217 for(int i = 0; i < MAX_CHANNELS; i++)
218 output_channels[i] = 0;
220 // Get the best colormodel the display can handle.
221 int best_colormodel = get_best_colormodel(colormodel);
223 // Conform existing bitmap to new colormodel and output size
226 // Restart if output size changed or output colormodel changed
227 if(!color_model_selected ||
228 (!bitmap->hardware_scaling() &&
229 (bitmap->get_w() != output->canvas->get_w() ||
230 bitmap->get_h() != output->canvas->get_h())) ||
231 colormodel != output_frame->get_color_model())
233 int size_change = (bitmap->get_w() != output->canvas->get_w() ||
234 bitmap->get_h() != output->canvas->get_h());
240 // Blank only if size changed
243 output->canvas->set_color(BLACK);
244 output->canvas->draw_box(0, 0, output->w, output->h);
245 output->canvas->flash();
249 // Update the ring buffer
250 if(bitmap_type == BITMAP_PRIMARY)
253 //printf("VDeviceX11::new_output_buffer\n");
254 output_frame->set_memory((unsigned char*)bitmap->get_data() /* + bitmap->get_shm_offset() */,
255 bitmap->get_y_offset(),
256 bitmap->get_u_offset(),
257 bitmap->get_v_offset());
260 //TRACE("VDeviceX11::new_output_buffer 10");
265 // Try hardware accelerated
266 switch(best_colormodel)
269 //TRACE("VDeviceX11::new_output_buffer 10");
270 if(device->out_config->driver == PLAYBACK_X11_XV &&
271 output->canvas->accel_available(best_colormodel, 0))
273 //TRACE("VDeviceX11::new_output_buffer 20");
274 bitmap = new BC_Bitmap(output->canvas,
279 //TRACE("VDeviceX11::new_output_buffer 30");
280 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
281 bitmap->get_y_offset(),
282 bitmap->get_u_offset(),
283 bitmap->get_v_offset(),
287 bitmap_type = BITMAP_PRIMARY;
292 if(device->out_config->driver == PLAYBACK_X11_XV &&
293 output->canvas->accel_available(best_colormodel, 0))
295 bitmap = new BC_Bitmap(output->canvas,
300 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
301 bitmap->get_y_offset(),
302 bitmap->get_u_offset(),
303 bitmap->get_v_offset(),
307 bitmap_type = BITMAP_PRIMARY;
310 if(device->out_config->driver == PLAYBACK_X11_XV &&
311 output->canvas->accel_available(BC_YUV422, 0))
313 bitmap = new BC_Bitmap(output->canvas,
318 bitmap_type = BITMAP_TEMP;
323 if(device->out_config->driver == PLAYBACK_X11_XV &&
324 output->canvas->accel_available(best_colormodel, 0))
326 bitmap = new BC_Bitmap(output->canvas,
331 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
332 bitmap->get_y_offset(),
333 bitmap->get_u_offset(),
334 bitmap->get_v_offset(),
338 bitmap_type = BITMAP_PRIMARY;
341 if(device->out_config->driver == PLAYBACK_X11_XV &&
342 output->canvas->accel_available(BC_YUV422P, 0))
344 bitmap = new BC_Bitmap(output->canvas,
349 bitmap_type = BITMAP_TEMP;
354 // Not accelerated --- use specified Format/Video/Color model instead
357 best_colormodel = output->canvas->get_color_model();
358 bitmap = new BC_Bitmap(output->canvas,
359 output->canvas->get_w(),
360 output->canvas->get_h(),
363 bitmap_type = BITMAP_TEMP;
366 if(bitmap_type == BITMAP_TEMP)
368 // Intermediate frame
369 output_frame = new VFrame(0,
373 bitmap_type = BITMAP_TEMP;
375 color_model_selected = 1;
378 //TRACE("VDeviceX11::new_output_buffer 100");
381 if(bitmap_type == BITMAP_PRIMARY)
383 // Only useful if the primary is RGB888 which XFree86 never uses.
384 output_frame->set_shm_offset(bitmap->get_shm_offset());
387 if(bitmap_type == BITMAP_TEMP)
389 output_frame->set_shm_offset(0);
392 //printf("VDeviceX11::new_output_buffer 200\n");
394 // Temporary until multichannel X
395 output_channels[0] = output_frame;
397 output->canvas->unlock_window();
402 int VDeviceX11::start_playback()
404 // Record window is initialized when its monitor starts.
405 if(!device->single_frame)
406 output->start_video();
410 int VDeviceX11::stop_playback()
412 if(!device->single_frame)
413 output->stop_video();
414 // Record window goes back to monitoring
415 // get the last frame played and store it in the video_out
419 int VDeviceX11::write_buffer(VFrame **output_channels, EDL *edl)
423 // The reason for not drawing single frame is that it is _always_ drawn
424 // when drawing draw_refresh in cwindowgui and vwindowgui
425 if (device->single_frame)
428 output->canvas->lock_window("VDeviceX11::write_buffer");
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();