Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vdevicex11.C

Go to the documentation of this file.
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 //printf("VDeviceX11::open_input 1\n");
00055         capture_bitmap = new BC_Capture(device->in_config->w, 
00056                 device->in_config->h,
00057                 device->in_config->screencapture_display);
00058 //printf("VDeviceX11::open_input 2\n");
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 // We need to copy when the memory is shared, which is when bimap_type is primary
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 //printf("VDeviceX11::get_best_colormodel %d %d %d\n", device->single_frame, colormodel, result);
00207         return result;
00208 }
00209 
00210 
00211 void VDeviceX11::new_output_buffer(VFrame **output_channels, int colormodel)
00212 {
00213 //TRACE("VDeviceX11::new_output_buffer 1");
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 // Get the best colormodel the display can handle.
00221         int best_colormodel = get_best_colormodel(colormodel);
00222 
00223 // Conform existing bitmap to new colormodel and output size
00224         if(bitmap)
00225         {
00226 // Restart if output size changed or output colormodel changed
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 // Blank only if size changed
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 // Update the ring buffer
00250                 if(bitmap_type == BITMAP_PRIMARY)
00251                 {
00252 
00253 //printf("VDeviceX11::new_output_buffer\n");
00254                         output_frame->set_memory((unsigned char*)bitmap->get_data() /* + bitmap->get_shm_offset() */,
00255                                                 bitmap->get_y_offset(),
00256                                                 bitmap->get_u_offset(),
00257                                                 bitmap->get_v_offset());
00258                 }
00259         }
00260 //TRACE("VDeviceX11::new_output_buffer 10");
00261 
00262 // Create new bitmap
00263         if(!bitmap)
00264         {
00265 // Try hardware accelerated
00266                 switch(best_colormodel)
00267                 {
00268                         case BC_YUV420P:
00269 //TRACE("VDeviceX11::new_output_buffer 10");
00270                                 if(device->out_config->driver == PLAYBACK_X11_XV &&
00271                                         output->canvas->accel_available(best_colormodel, 0))
00272                                 {
00273 //TRACE("VDeviceX11::new_output_buffer 20");
00274                                         bitmap = new BC_Bitmap(output->canvas, 
00275                                                 device->out_w,
00276                                                 device->out_h,
00277                                                 best_colormodel,
00278                                                 1);
00279 //TRACE("VDeviceX11::new_output_buffer 30");
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 // Not accelerated --- use specified Format/Video/Color model instead
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 // Intermediate frame
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 //TRACE("VDeviceX11::new_output_buffer 100");
00379 
00380 // Fill arguments
00381         if(bitmap_type == BITMAP_PRIMARY)
00382         {
00383 // Only useful if the primary is RGB888 which XFree86 never uses.
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 //printf("VDeviceX11::new_output_buffer 200\n");
00393 
00394 // Temporary until multichannel X
00395         output_channels[0] = output_frame;
00396 
00397         output->canvas->unlock_window();
00398 
00399 }
00400 
00401 
00402 int VDeviceX11::start_playback()
00403 {
00404 // Record window is initialized when its monitor starts.
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 // Record window goes back to monitoring
00415 // get the last frame played and store it in the video_out
00416         return 0;
00417 }
00418 
00419 int VDeviceX11::write_buffer(VFrame **output_channels, EDL *edl)
00420 {
00421         int i = 0;
00422 
00423 // The reason for not drawing single frame is that it is _always_ drawn 
00424 // when drawing draw_refresh in cwindowgui and vwindowgui
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 //output->canvas->unlock_window();
00442 //return 0;
00443 // printf("VDeviceX11::write_buffer 2 %d\n", bitmap_type);
00444 // for(int j = 0; j < output_channels[0]->get_w() * 3 * 5; j++)
00445 //      output_channels[0]->get_rows()[0][j] = 255;
00446 
00447 // Convert colormodel
00448         if(bitmap_type == BITMAP_TEMP)
00449         {
00450 // printf("VDeviceX11::write_buffer 1 %d %d, %d %d %d %d -> %d %d %d %d\n",
00451 //                      output->w,
00452 //                      output->h,
00453 //                      in_x, 
00454 //                      in_y, 
00455 //                      in_w, 
00456 //                      in_h,
00457 //                      out_x, 
00458 //                      out_y, 
00459 //                      out_w, 
00460 //                      out_h );fflush(stdout);
00461 
00462 //printf("VDeviceX11::write_buffer 2\n");
00463 
00464 //printf("VDeviceX11::write_buffer 3 %p %p\n", bitmap->get_row_pointers(), output_channels[0]->get_rows());
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 //printf("VDeviceX11::write_buffer 4 %p\n", bitmap);
00517 //for(i = 0; i < 1000; i += 4) bitmap->get_data()[i] = 128;
00518 //printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type, 
00519 //      bitmap->get_color_model(), 
00520 //      output->get_color_model());fflush(stdout);
00521 // printf("VDeviceX11::write_buffer 2 %d %d, %d %d %d %d -> %d %d %d %d\n",
00522 //                      output->w,
00523 //                      output->h,
00524 //                      in_x, 
00525 //                      in_y, 
00526 //                      in_w, 
00527 //                      in_h,
00528 //                      out_x, 
00529 //                      out_y, 
00530 //                      out_w, 
00531 //                      out_h);
00532 
00533 
00534 // Select field if using field mode.  This may be a useful feature later on
00535 // but currently it's being superceded by the heroine 60 encoding.
00536 // Doing time base conversion in the display routine produces 
00537 // pretty big compression artifacts.  It also requires implementing a
00538 // different transform for each X visual.
00539         if(device->out_config->x11_use_fields)
00540         {
00541         }
00542 
00543 
00544 
00545 // Cause X server to display it
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 

Generated on Sun Jan 8 13:39:02 2006 for Cinelerra-svn by  doxygen 1.4.4