00001 #include "assets.h"
00002 #include "bccapture.h"
00003 #include "bcsignals.h"
00004 #include "canvas.h"
00005 #include "colormodels.h"
00006 #include "mwindow.h"
00007 #include "playbackconfig.h"
00008 #include "preferences.h"
00009 #include "recordconfig.h"
00010 #include "strategies.inc"
00011 #include "vdevicex11.h"
00012 #include "vframe.h"
00013 #include "videodevice.h"
00014 #include "videowindow.h"
00015 #include "videowindowgui.h"
00016
00017 #include <string.h>
00018 #include <unistd.h>
00019
00020 VDeviceX11::VDeviceX11(VideoDevice *device, Canvas *output)
00021 : VDeviceBase(device)
00022 {
00023 reset_parameters();
00024 this->output = output;
00025 }
00026
00027 VDeviceX11::~VDeviceX11()
00028 {
00029 close_all();
00030 }
00031
00032 int VDeviceX11::reset_parameters()
00033 {
00034 output_frame = 0;
00035 bitmap = 0;
00036 bitmap_w = 0;
00037 bitmap_h = 0;
00038 output = 0;
00039 in_x = 0;
00040 in_y = 0;
00041 in_w = 0;
00042 in_h = 0;
00043 out_x = 0;
00044 out_y = 0;
00045 out_w = 0;
00046 out_h = 0;
00047 capture_bitmap = 0;
00048 color_model_selected = 0;
00049 return 0;
00050 }
00051
00052 int VDeviceX11::open_input()
00053 {
00054
00055 capture_bitmap = new BC_Capture(device->in_config->w,
00056 device->in_config->h,
00057 device->in_config->screencapture_display);
00058
00059
00060 return 0;
00061 }
00062
00063 int VDeviceX11::open_output()
00064 {
00065 if(output)
00066 {
00067 output->canvas->lock_window("VDeviceX11::open_output");
00068 if(!device->single_frame)
00069 output->start_video();
00070 else
00071 output->start_single();
00072 output->canvas->unlock_window();
00073 }
00074 return 0;
00075 }
00076
00077
00078 int VDeviceX11::output_visible()
00079 {
00080 if(!output || output->canvas->get_hidden())
00081 return 0;
00082 else
00083 return 1;
00084 }
00085
00086
00087 int VDeviceX11::close_all()
00088 {
00089 if(output)
00090 {
00091 output->canvas->lock_window("VDeviceX11::close_all");
00092 }
00093
00094 if(output && output_frame)
00095 {
00096
00097 if (bitmap && bitmap_type == BITMAP_PRIMARY)
00098 {
00099 if(output->refresh_frame &&
00100 (output->refresh_frame->get_w() != device->out_w ||
00101 output->refresh_frame->get_h() != device->out_h ||
00102 output->refresh_frame->get_color_model() != output_frame->get_color_model()))
00103 {
00104 delete output->refresh_frame;
00105 output->refresh_frame = 0;
00106 }
00107
00108 if(!output->refresh_frame)
00109 {
00110 output->refresh_frame = new VFrame(0,
00111 device->out_w,
00112 device->out_h,
00113 output_frame->get_color_model());
00114 }
00115
00116 output->refresh_frame->copy_from(output_frame);
00117 }
00118 else
00119 {
00120 if(output->refresh_frame)
00121 delete output->refresh_frame;
00122
00123 output->refresh_frame = output_frame;
00124 output_frame = 0;
00125 }
00126
00127 if(!device->single_frame)
00128 output->stop_video();
00129 else
00130 output->stop_single();
00131 output->draw_refresh();
00132
00133
00134 } else
00135 {
00136 if(bitmap)
00137 delete output_frame;
00138 }
00139 if(bitmap)
00140 {
00141 delete bitmap;
00142 bitmap = 0;
00143 }
00144
00145 if(capture_bitmap) delete capture_bitmap;
00146
00147 if(output)
00148 {
00149 output->canvas->unlock_window();
00150 }
00151
00152
00153 reset_parameters();
00154 return 0;
00155 }
00156
00157 int VDeviceX11::read_buffer(VFrame *frame)
00158 {
00159 capture_bitmap->capture_frame(frame, device->input_x, device->input_y);
00160 return 0;
00161 }
00162
00163
00164 int VDeviceX11::get_best_colormodel(Asset *asset)
00165 {
00166 return BC_RGB888;
00167 }
00168
00169
00170 int VDeviceX11::get_best_colormodel(int colormodel)
00171 {
00172 int result = -1;
00173 if(!device->single_frame)
00174 {
00175 switch(colormodel)
00176 {
00177 case BC_YUV420P:
00178 case BC_YUV422P:
00179 case BC_YUV422:
00180 result = colormodel;
00181 break;
00182 }
00183 }
00184
00185 if(result < 0)
00186 {
00187 switch(colormodel)
00188 {
00189 case BC_RGB888:
00190 case BC_RGBA8888:
00191 case BC_RGB161616:
00192 case BC_RGBA16161616:
00193 case BC_YUV888:
00194 case BC_YUVA8888:
00195 case BC_YUV161616:
00196 case BC_YUVA16161616:
00197 result = colormodel;
00198 break;
00199
00200 default:
00201 result = output->canvas->get_color_model();
00202 break;
00203 }
00204 }
00205
00206
00207 return result;
00208 }
00209
00210
00211 void VDeviceX11::new_output_buffer(VFrame **output_channels, int colormodel)
00212 {
00213
00214
00215 output->canvas->lock_window("VDeviceX11::new_output_buffer");
00216
00217 for(int i = 0; i < MAX_CHANNELS; i++)
00218 output_channels[i] = 0;
00219
00220
00221 int best_colormodel = get_best_colormodel(colormodel);
00222
00223
00224 if(bitmap)
00225 {
00226
00227 if(!color_model_selected ||
00228 (!bitmap->hardware_scaling() &&
00229 (bitmap->get_w() != output->canvas->get_w() ||
00230 bitmap->get_h() != output->canvas->get_h())) ||
00231 colormodel != output_frame->get_color_model())
00232 {
00233 int size_change = (bitmap->get_w() != output->canvas->get_w() ||
00234 bitmap->get_h() != output->canvas->get_h());
00235 delete bitmap;
00236 delete output_frame;
00237 bitmap = 0;
00238 output_frame = 0;
00239
00240
00241 if(size_change)
00242 {
00243 output->canvas->set_color(BLACK);
00244 output->canvas->draw_box(0, 0, output->w, output->h);
00245 output->canvas->flash();
00246 }
00247 }
00248 else
00249
00250 if(bitmap_type == BITMAP_PRIMARY)
00251 {
00252
00253
00254 output_frame->set_memory((unsigned char*)bitmap->get_data() ,
00255 bitmap->get_y_offset(),
00256 bitmap->get_u_offset(),
00257 bitmap->get_v_offset());
00258 }
00259 }
00260
00261
00262
00263 if(!bitmap)
00264 {
00265
00266 switch(best_colormodel)
00267 {
00268 case BC_YUV420P:
00269
00270 if(device->out_config->driver == PLAYBACK_X11_XV &&
00271 output->canvas->accel_available(best_colormodel, 0))
00272 {
00273
00274 bitmap = new BC_Bitmap(output->canvas,
00275 device->out_w,
00276 device->out_h,
00277 best_colormodel,
00278 1);
00279
00280 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
00281 bitmap->get_y_offset(),
00282 bitmap->get_u_offset(),
00283 bitmap->get_v_offset(),
00284 device->out_w,
00285 device->out_h,
00286 best_colormodel);
00287 bitmap_type = BITMAP_PRIMARY;
00288 }
00289 break;
00290
00291 case BC_YUV422P:
00292 if(device->out_config->driver == PLAYBACK_X11_XV &&
00293 output->canvas->accel_available(best_colormodel, 0))
00294 {
00295 bitmap = new BC_Bitmap(output->canvas,
00296 device->out_w,
00297 device->out_h,
00298 best_colormodel,
00299 1);
00300 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
00301 bitmap->get_y_offset(),
00302 bitmap->get_u_offset(),
00303 bitmap->get_v_offset(),
00304 device->out_w,
00305 device->out_h,
00306 best_colormodel);
00307 bitmap_type = BITMAP_PRIMARY;
00308 }
00309 else
00310 if(device->out_config->driver == PLAYBACK_X11_XV &&
00311 output->canvas->accel_available(BC_YUV422, 0))
00312 {
00313 bitmap = new BC_Bitmap(output->canvas,
00314 device->out_w,
00315 device->out_h,
00316 BC_YUV422,
00317 1);
00318 bitmap_type = BITMAP_TEMP;
00319 }
00320 break;
00321
00322 case BC_YUV422:
00323 if(device->out_config->driver == PLAYBACK_X11_XV &&
00324 output->canvas->accel_available(best_colormodel, 0))
00325 {
00326 bitmap = new BC_Bitmap(output->canvas,
00327 device->out_w,
00328 device->out_h,
00329 best_colormodel,
00330 1);
00331 output_frame = new VFrame((unsigned char*)bitmap->get_data() + bitmap->get_shm_offset(),
00332 bitmap->get_y_offset(),
00333 bitmap->get_u_offset(),
00334 bitmap->get_v_offset(),
00335 device->out_w,
00336 device->out_h,
00337 best_colormodel);
00338 bitmap_type = BITMAP_PRIMARY;
00339 }
00340 else
00341 if(device->out_config->driver == PLAYBACK_X11_XV &&
00342 output->canvas->accel_available(BC_YUV422P, 0))
00343 {
00344 bitmap = new BC_Bitmap(output->canvas,
00345 device->out_w,
00346 device->out_h,
00347 BC_YUV422P,
00348 1);
00349 bitmap_type = BITMAP_TEMP;
00350 }
00351 break;
00352 }
00353
00354
00355 if(!bitmap)
00356 {
00357 best_colormodel = output->canvas->get_color_model();
00358 bitmap = new BC_Bitmap(output->canvas,
00359 output->canvas->get_w(),
00360 output->canvas->get_h(),
00361 best_colormodel,
00362 1);
00363 bitmap_type = BITMAP_TEMP;
00364 }
00365
00366 if(bitmap_type == BITMAP_TEMP)
00367 {
00368
00369 output_frame = new VFrame(0,
00370 device->out_w,
00371 device->out_h,
00372 colormodel);
00373 bitmap_type = BITMAP_TEMP;
00374 }
00375 color_model_selected = 1;
00376 }
00377
00378
00379
00380
00381 if(bitmap_type == BITMAP_PRIMARY)
00382 {
00383
00384 output_frame->set_shm_offset(bitmap->get_shm_offset());
00385 }
00386 else
00387 if(bitmap_type == BITMAP_TEMP)
00388 {
00389 output_frame->set_shm_offset(0);
00390 }
00391
00392
00393
00394
00395 output_channels[0] = output_frame;
00396
00397 output->canvas->unlock_window();
00398
00399 }
00400
00401
00402 int VDeviceX11::start_playback()
00403 {
00404
00405 if(!device->single_frame)
00406 output->start_video();
00407 return 0;
00408 }
00409
00410 int VDeviceX11::stop_playback()
00411 {
00412 if(!device->single_frame)
00413 output->stop_video();
00414
00415
00416 return 0;
00417 }
00418
00419 int VDeviceX11::write_buffer(VFrame **output_channels, EDL *edl)
00420 {
00421 int i = 0;
00422
00423
00424
00425 if (device->single_frame)
00426 return 0;
00427
00428 output->canvas->lock_window("VDeviceX11::write_buffer");
00429 output->get_transfers(edl,
00430 in_x,
00431 in_y,
00432 in_w,
00433 in_h,
00434 out_x,
00435 out_y,
00436 out_w,
00437 out_h,
00438 (bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) ? bitmap->get_w() : -1,
00439 (bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) ? bitmap->get_h() : -1);
00440
00441
00442
00443
00444
00445
00446
00447
00448 if(bitmap_type == BITMAP_TEMP)
00449 {
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 if(bitmap->hardware_scaling())
00467 {
00468 cmodel_transfer(bitmap->get_row_pointers(),
00469 output_channels[0]->get_rows(),
00470 0,
00471 0,
00472 0,
00473 output_channels[0]->get_y(),
00474 output_channels[0]->get_u(),
00475 output_channels[0]->get_v(),
00476 0,
00477 0,
00478 output_channels[0]->get_w(),
00479 output_channels[0]->get_h(),
00480 0,
00481 0,
00482 bitmap->get_w(),
00483 bitmap->get_h(),
00484 output_channels[0]->get_color_model(),
00485 bitmap->get_color_model(),
00486 0,
00487 output_channels[0]->get_w(),
00488 bitmap->get_w());
00489 }
00490 else
00491 {
00492 cmodel_transfer(bitmap->get_row_pointers(),
00493 output_channels[0]->get_rows(),
00494 0,
00495 0,
00496 0,
00497 output_channels[0]->get_y(),
00498 output_channels[0]->get_u(),
00499 output_channels[0]->get_v(),
00500 in_x,
00501 in_y,
00502 in_w,
00503 in_h,
00504 0,
00505 0,
00506 out_w,
00507 out_h,
00508 output_channels[0]->get_color_model(),
00509 bitmap->get_color_model(),
00510 0,
00511 output_channels[0]->get_w(),
00512 bitmap->get_w());
00513 }
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 if(device->out_config->x11_use_fields)
00540 {
00541 }
00542
00543
00544
00545
00546 if(bitmap->hardware_scaling())
00547 {
00548 output->canvas->draw_bitmap(bitmap,
00549 !device->single_frame,
00550 out_x,
00551 out_y,
00552 out_w,
00553 out_h,
00554 in_x,
00555 in_y,
00556 in_w,
00557 in_h,
00558 0);
00559 }
00560 else
00561 {
00562 output->canvas->draw_bitmap(bitmap,
00563 !device->single_frame,
00564 out_x,
00565 out_y,
00566 out_w,
00567 out_h,
00568 0,
00569 0,
00570 out_w,
00571 out_h,
00572 0);
00573 }
00574
00575
00576 output->canvas->unlock_window();
00577 return 0;
00578 }
00579
00580