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))
248 bitmap = new BC_Bitmap(output->canvas,
253 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
254 bitmap->get_y_offset(),
255 bitmap->get_u_offset(),
256 bitmap->get_v_offset(),
260 bitmap_type = BITMAP_PRIMARY;
265 if(device->out_config->driver == PLAYBACK_X11_XV &&
266 output->canvas->accel_available(best_colormodel))
268 bitmap = new BC_Bitmap(output->canvas,
273 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
274 bitmap->get_y_offset(),
275 bitmap->get_u_offset(),
276 bitmap->get_v_offset(),
280 bitmap_type = BITMAP_PRIMARY;
283 if(device->out_config->driver == PLAYBACK_X11_XV &&
284 output->canvas->accel_available(BC_YUV422))
286 bitmap = new BC_Bitmap(output->canvas,
291 bitmap_type = BITMAP_TEMP;
296 //printf("VDeviceX11::new_output_buffer 3\n");
297 if(device->out_config->driver == PLAYBACK_X11_XV &&
298 output->canvas->accel_available(best_colormodel))
300 //printf("VDeviceX11::new_output_buffer 4\n");
301 bitmap = new BC_Bitmap(output->canvas,
306 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
307 bitmap->get_y_offset(),
308 bitmap->get_u_offset(),
309 bitmap->get_v_offset(),
313 bitmap_type = BITMAP_PRIMARY;
316 if(device->out_config->driver == PLAYBACK_X11_XV &&
317 output->canvas->accel_available(BC_YUV422P))
319 //printf("VDeviceX11::new_output_buffer 5\n");
320 bitmap = new BC_Bitmap(output->canvas,
325 //printf("VDeviceX11::new_output_buffer 6\n");
326 bitmap_type = BITMAP_TEMP;
327 //printf("VDeviceX11::new_output_buffer 7\n");
331 //printf("VDeviceX11::new_output_buffer 8\n");
333 // Not accelerated --- use specified Format/Video/Color model instead
336 best_colormodel = output->canvas->get_color_model();
337 bitmap = new BC_Bitmap(output->canvas,
338 output->canvas->get_w(),
339 output->canvas->get_h(),
342 bitmap_type = BITMAP_TEMP;
343 //printf("VDeviceX11::new_output_buffer 9\n");
346 if(bitmap_type == BITMAP_TEMP)
348 // Intermediate frame
349 output_frame = new VFrame(0,
353 bitmap_type = BITMAP_TEMP;
354 //printf("VDeviceX11::new_output_buffer 10\n");
356 color_model_selected = 1;
358 //printf("VDeviceX11::new_output_buffer 11\n");
361 if(bitmap_type == BITMAP_PRIMARY)
363 // Only useful if the primary is RGB888 which XFree86 never uses.
364 output_frame->set_shm_offset(bitmap->get_shm_offset());
367 if(bitmap_type == BITMAP_TEMP)
369 output_frame->set_shm_offset(0);
371 //printf("VDeviceX11::new_output_buffer 12\n");
373 // Temporary until multichannel X
374 output_channels[0] = output_frame;
378 int VDeviceX11::start_playback()
380 // Record window is initialized when its monitor starts.
381 if(!device->single_frame)
382 output->canvas->start_video();
386 int VDeviceX11::stop_playback()
388 if(!device->single_frame)
389 output->canvas->stop_video();
390 // Record window goes back to monitoring
391 // get the last frame played and store it in the video_out
395 int VDeviceX11::write_buffer(VFrame **output_channels, EDL *edl)
399 //printf("VDeviceX11::write_buffer 1\n");
400 output->canvas->lock_window("VDeviceX11::write_buffer");
401 //printf("VDeviceX11::write_buffer 2\n");
402 output->get_transfers(edl,
411 (bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) ? bitmap->get_w() : -1,
412 (bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) ? bitmap->get_h() : -1);
414 //output->canvas->unlock_window();
416 // printf("VDeviceX11::write_buffer 2 %d\n", bitmap_type);
417 // for(int j = 0; j < output_channels[0]->get_w() * 3 * 5; j++)
418 // output_channels[0]->get_rows()[0][j] = 255;
420 // Convert colormodel
421 if(bitmap_type == BITMAP_TEMP)
423 // printf("VDeviceX11::write_buffer 1 %d %d, %d %d %d %d -> %d %d %d %d\n",
433 // out_h );fflush(stdout);
435 //printf("VDeviceX11::write_buffer 2\n");
437 //printf("VDeviceX11::write_buffer 3 %p %p\n", bitmap->get_row_pointers(), output_channels[0]->get_rows());
439 if(bitmap->hardware_scaling())
441 cmodel_transfer(bitmap->get_row_pointers(),
442 output_channels[0]->get_rows(),
446 output_channels[0]->get_y(),
447 output_channels[0]->get_u(),
448 output_channels[0]->get_v(),
451 output_channels[0]->get_w(),
452 output_channels[0]->get_h(),
457 output_channels[0]->get_color_model(),
458 bitmap->get_color_model(),
460 output_channels[0]->get_w(),
465 cmodel_transfer(bitmap->get_row_pointers(),
466 output_channels[0]->get_rows(),
470 output_channels[0]->get_y(),
471 output_channels[0]->get_u(),
472 output_channels[0]->get_v(),
481 output_channels[0]->get_color_model(),
482 bitmap->get_color_model(),
484 output_channels[0]->get_w(),
489 //printf("VDeviceX11::write_buffer 4 %p\n", bitmap);
490 //for(i = 0; i < 1000; i += 4) bitmap->get_data()[i] = 128;
491 //printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type,
492 // bitmap->get_color_model(),
493 // output->get_color_model());fflush(stdout);
494 // printf("VDeviceX11::write_buffer 2 %d %d, %d %d %d %d -> %d %d %d %d\n",
507 // Select field if using field mode. This may be a useful feature later on
508 // but currently it's being superceded by the heroine 60 encoding.
509 // Doing time base conversion in the display routine produces
510 // pretty big compression artifacts. It also requires implementing a
511 // different transform for each X visual.
512 if(device->out_config->x11_use_fields)
518 // Cause X server to display it
519 if(bitmap->hardware_scaling())
521 output->canvas->draw_bitmap(bitmap,
522 !device->single_frame,
535 output->canvas->draw_bitmap(bitmap,
536 !device->single_frame,
549 // In single frame mode we want the frame to display once along with overlays
550 // when the device is closed. This prevents intermediate drawing with overlays
551 // from reading the obsolete back buffer before the device is closed.
553 // if(device->single_frame)
555 // output->canvas->flash();
556 // output->canvas->flush();
559 output->canvas->unlock_window();
560 //printf("VDeviceX11::write_buffer 5\n");fflush(stdout);