4 #include "colormodels.h"
6 #include "playbackconfig.h"
7 #include "preferences.h"
8 #include "recordconfig.h"
9 #include "strategies.inc"
10 #include "vdevicex11.h"
12 #include "videodevice.h"
13 #include "videowindow.h"
14 #include "videowindowgui.h"
19 VDeviceX11::VDeviceX11(VideoDevice *device, Canvas *output)
23 this->output = output;
26 VDeviceX11::~VDeviceX11()
31 int VDeviceX11::reset_parameters()
47 color_model_selected = 0;
51 int VDeviceX11::open_input()
53 //printf("VDeviceX11::open_input 1\n");
54 capture_bitmap = new BC_Capture(device->in_config->w,
56 device->in_config->screencapture_display);
57 //printf("VDeviceX11::open_input 2\n");
62 int VDeviceX11::open_output()
64 if(output && !device->single_frame)
65 output->canvas->start_video();
70 int VDeviceX11::output_visible()
72 if(!output || output->canvas->get_hidden())
79 int VDeviceX11::close_all()
83 output->canvas->lock_window("VDeviceX11::close_all");
86 if(output && output_frame)
88 // Copy picture to persistent frame buffer with conversion to flat colormodel
89 if(output->refresh_frame &&
90 (output->refresh_frame->get_w() != device->out_w ||
91 output->refresh_frame->get_h() != device->out_h ||
92 output->refresh_frame->get_color_model() != output_frame->get_color_model()))
94 delete output->refresh_frame;
95 output->refresh_frame = 0;
98 if(!output->refresh_frame)
100 output->refresh_frame = new VFrame(0,
103 output_frame->get_color_model());
106 if(!device->single_frame)
108 output->canvas->stop_video();
111 output->refresh_frame->copy_from(output_frame);
113 output->draw_refresh();
123 if(capture_bitmap) delete capture_bitmap;
127 output->canvas->unlock_window();
135 int VDeviceX11::read_buffer(VFrame *frame)
137 capture_bitmap->capture_frame(frame, device->input_x, device->input_y);
142 int VDeviceX11::get_best_colormodel(Asset *asset)
148 int VDeviceX11::get_best_colormodel(int colormodel)
151 if(!device->single_frame)
170 case BC_RGBA16161616:
174 case BC_YUVA16161616:
179 result = output->canvas->get_color_model();
184 //printf("VDeviceX11::get_best_colormodel %d %d %d\n", device->single_frame, colormodel, result);
189 void VDeviceX11::new_output_buffer(VFrame **output_channels, int colormodel)
191 for(int i = 0; i < MAX_CHANNELS; i++)
192 output_channels[i] = 0;
193 //printf("VDeviceX11::new_output_buffer 1\n");
195 // Get the best colormodel the display can handle.
196 int best_colormodel = get_best_colormodel(colormodel);
197 //printf("VDeviceX11::new_output_buffer 2 %d\n", best_colormodel);
199 // Conform existing bitmap to new colormodel and output size
202 // Restart if output size changed or output colormodel changed
203 if(!color_model_selected ||
204 (!bitmap->hardware_scaling() &&
205 (bitmap->get_w() != output->canvas->get_w() ||
206 bitmap->get_h() != output->canvas->get_h())) ||
207 colormodel != output_frame->get_color_model())
209 int size_change = (bitmap->get_w() != output->canvas->get_w() ||
210 bitmap->get_h() != output->canvas->get_h());
216 // Blank only if size changed
219 output->canvas->set_color(BLACK);
220 output->canvas->draw_box(0, 0, output->w, output->h);
221 output->canvas->flash();
225 // Update the ring buffer
226 if(bitmap_type == BITMAP_PRIMARY)
229 //printf("VDeviceX11::new_output_buffer\n");
230 output_frame->set_memory((unsigned char*)bitmap->get_data() /* + bitmap->get_shm_offset() */,
231 bitmap->get_y_offset(),
232 bitmap->get_u_offset(),
233 bitmap->get_v_offset());
240 //printf("VDeviceX11::new_output_buffer 1 %d\n", best_colormodel);
241 // Try hardware accelerated
242 switch(best_colormodel)
245 if(device->out_config->driver == PLAYBACK_X11_XV &&
246 output->canvas->accel_available(best_colormodel) &&
247 !output->use_scrollbars)
249 bitmap = new BC_Bitmap(output->canvas,
254 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
255 bitmap->get_y_offset(),
256 bitmap->get_u_offset(),
257 bitmap->get_v_offset(),
261 bitmap_type = BITMAP_PRIMARY;
266 if(device->out_config->driver == PLAYBACK_X11_XV &&
267 output->canvas->accel_available(best_colormodel) &&
268 !output->use_scrollbars)
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;
285 if(device->out_config->driver == PLAYBACK_X11_XV &&
286 output->canvas->accel_available(BC_YUV422))
288 bitmap = new BC_Bitmap(output->canvas,
293 bitmap_type = BITMAP_TEMP;
298 //printf("VDeviceX11::new_output_buffer 3\n");
299 if(device->out_config->driver == PLAYBACK_X11_XV &&
300 output->canvas->accel_available(best_colormodel) &&
301 !output->use_scrollbars)
303 //printf("VDeviceX11::new_output_buffer 4\n");
304 bitmap = new BC_Bitmap(output->canvas,
309 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
310 bitmap->get_y_offset(),
311 bitmap->get_u_offset(),
312 bitmap->get_v_offset(),
316 bitmap_type = BITMAP_PRIMARY;
319 if(device->out_config->driver == PLAYBACK_X11_XV &&
320 output->canvas->accel_available(BC_YUV422P))
322 //printf("VDeviceX11::new_output_buffer 5\n");
323 bitmap = new BC_Bitmap(output->canvas,
328 //printf("VDeviceX11::new_output_buffer 6\n");
329 bitmap_type = BITMAP_TEMP;
330 //printf("VDeviceX11::new_output_buffer 7\n");
334 //printf("VDeviceX11::new_output_buffer 8\n");
336 // Try default colormodel
339 best_colormodel = output->canvas->get_color_model();
340 bitmap = new BC_Bitmap(output->canvas,
341 output->canvas->get_w(),
342 output->canvas->get_h(),
345 bitmap_type = BITMAP_TEMP;
346 //printf("VDeviceX11::new_output_buffer 9\n");
349 if(bitmap_type == BITMAP_TEMP)
351 // Intermediate frame
352 output_frame = new VFrame(0,
356 bitmap_type = BITMAP_TEMP;
357 //printf("VDeviceX11::new_output_buffer 10\n");
359 color_model_selected = 1;
361 //printf("VDeviceX11::new_output_buffer 11\n");
364 if(bitmap_type == BITMAP_PRIMARY)
366 // Only useful if the primary is RGB888 which XFree86 never uses.
367 output_frame->set_shm_offset(bitmap->get_shm_offset());
370 if(bitmap_type == BITMAP_TEMP)
372 output_frame->set_shm_offset(0);
374 //printf("VDeviceX11::new_output_buffer 12\n");
376 // Temporary until multichannel X
377 output_channels[0] = output_frame;
381 int VDeviceX11::start_playback()
383 // Record window is initialized when its monitor starts.
384 if(!device->single_frame)
385 output->canvas->start_video();
389 int VDeviceX11::stop_playback()
391 if(!device->single_frame)
392 output->canvas->stop_video();
393 // Record window goes back to monitoring
394 // get the last frame played and store it in the video_out
398 int VDeviceX11::write_buffer(VFrame **output_channels, EDL *edl)
402 //printf("VDeviceX11::write_buffer 1\n");
403 output->canvas->lock_window("VDeviceX11::write_buffer");
404 //printf("VDeviceX11::write_buffer 2\n");
405 output->get_transfers(edl,
414 (bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) ? bitmap->get_w() : -1,
415 (bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) ? bitmap->get_h() : -1);
417 //output->canvas->unlock_window();
419 // printf("VDeviceX11::write_buffer 2 %d\n", bitmap_type);
420 // for(int j = 0; j < output_channels[0]->get_w() * 3 * 5; j++)
421 // output_channels[0]->get_rows()[0][j] = 255;
423 // Convert colormodel
424 if(bitmap_type == BITMAP_TEMP)
426 // printf("VDeviceX11::write_buffer 1 %d %d, %d %d %d %d -> %d %d %d %d\n",
436 // out_h );fflush(stdout);
438 //printf("VDeviceX11::write_buffer 2\n");
440 //printf("VDeviceX11::write_buffer 3 %p %p\n", bitmap->get_row_pointers(), output_channels[0]->get_rows());
442 if(bitmap->hardware_scaling())
444 cmodel_transfer(bitmap->get_row_pointers(),
445 output_channels[0]->get_rows(),
449 output_channels[0]->get_y(),
450 output_channels[0]->get_u(),
451 output_channels[0]->get_v(),
454 output_channels[0]->get_w(),
455 output_channels[0]->get_h(),
460 output_channels[0]->get_color_model(),
461 bitmap->get_color_model(),
463 output_channels[0]->get_w(),
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(),
484 output_channels[0]->get_color_model(),
485 bitmap->get_color_model(),
487 output_channels[0]->get_w(),
492 //printf("VDeviceX11::write_buffer 4 %p\n", bitmap);
493 //for(i = 0; i < 1000; i += 4) bitmap->get_data()[i] = 128;
494 //printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type,
495 // bitmap->get_color_model(),
496 // output->get_color_model());fflush(stdout);
497 // printf("VDeviceX11::write_buffer 2 %d %d, %d %d %d %d -> %d %d %d %d\n",
510 // Select field if using field mode. This may be a useful feature later on
511 // but currently it's being superceded by the heroine 60 encoding.
512 // Doing time base conversion in the display routine produces
513 // pretty big compression artifacts. It also requires implementing a
514 // different transform for each X visual.
515 if(device->out_config->x11_use_fields)
521 // Cause X server to display it
522 if(bitmap->hardware_scaling())
524 output->canvas->draw_bitmap(bitmap,
525 !device->single_frame,
538 output->canvas->draw_bitmap(bitmap,
539 !device->single_frame,
552 // In single frame mode we want the frame to display once along with overlays
553 // when the device is closed. This prevents intermediate drawing with overlays
554 // from reading the obsolete back buffer before the device is closed.
556 // if(device->single_frame)
558 // output->canvas->flash();
559 // output->canvas->flush();
562 output->canvas->unlock_window();
563 //printf("VDeviceX11::write_buffer 5\n");fflush(stdout);