00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef __HAVE_FBDEV__
00034
00035 #include "mmsgui/fb/mmsfbdevdavinci.h"
00036 #include <sys/ioctl.h>
00037 #include <cstring>
00038
00039 #define INITCHECK if(!this->isinitialized){MMSFB_SetError(0,"MMSFBDevDavinci is not initialized");return false;}
00040
00041 MMSFBDevDavinci::MMSFBDevDavinci() {
00042 this->osd0.fbdev = NULL;
00043 this->osd1.fbdev = NULL;
00044 this->vid0.fbdev = NULL;
00045 this->vid1.fbdev = NULL;
00046 }
00047
00048 MMSFBDevDavinci::~MMSFBDevDavinci() {
00049 closeDevice();
00050 }
00051
00052 bool MMSFBDevDavinci::openDevice(char *device_file, int console) {
00053
00054 closeDevice();
00055
00056
00057 for (int i = 0; i < 4; i++) {
00058 MMSFBDev *fbdev;
00059 char dev[100];
00060 sprintf(dev, "/dev/fb%d", i);
00061 fbdev = new MMSFBDev();
00062 if (!fbdev->openDevice(dev, (!i)?-1:-2)) {
00063 delete fbdev;
00064 closeDevice();
00065 return false;
00066 }
00067
00068 if (memcmp(fbdev->fix_screeninfo.id, "dm_osd0_fb", 10) == 0) {
00069 this->osd0.fbdev = fbdev;
00070 strcpy(this->osd0.device, dev);
00071 this->osd0.width = -1;
00072 }
00073 else
00074 if (memcmp(fbdev->fix_screeninfo.id, "dm_vid0_fb", 10) == 0) {
00075 this->vid0.fbdev = fbdev;
00076 strcpy(this->vid0.device, dev);
00077 this->vid0.width = 0;
00078
00079 this->vid0.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00080 }
00081 else
00082 if (memcmp(fbdev->fix_screeninfo.id, "dm_osd1_fb", 10) == 0) {
00083 this->osd1.fbdev = fbdev;
00084 strcpy(this->osd1.device, dev);
00085 this->osd1.width = -1;
00086 }
00087 else
00088 if (memcmp(fbdev->fix_screeninfo.id, "dm_vid1_fb", 10) == 0) {
00089 this->vid1.fbdev = fbdev;
00090 strcpy(this->vid1.device, dev);
00091 this->vid1.width = 0;
00092
00093 this->vid1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00094 }
00095 else {
00096
00097 printf("MMSFBDevDavinci: unsupported accelerator %d (%.16s)\n", fbdev->fix_screeninfo.accel, fbdev->fix_screeninfo.id);
00098 delete fbdev;
00099 closeDevice();
00100 return false;
00101 }
00102
00103 if (!i && !this->osd0.fbdev) {
00104
00105 printf("MMSFBDevDavinci: /dev/fb0 is not osd0\n");
00106 closeDevice();
00107 return false;
00108 }
00109 }
00110
00111
00112 this->isinitialized = true;
00113
00114 return true;
00115 }
00116
00117 void MMSFBDevDavinci::closeDevice() {
00118
00119 if (this->vid1.fbdev) {
00120 delete this->vid1.fbdev;
00121 this->vid1.fbdev = NULL;
00122 }
00123 if (this->vid0.fbdev) {
00124 delete this->vid0.fbdev;
00125 this->vid0.fbdev = NULL;
00126 }
00127 if (this->osd1.fbdev) {
00128 delete this->osd1.fbdev;
00129 this->osd1.fbdev = NULL;
00130 }
00131 if (this->osd0.fbdev) {
00132 delete this->osd0.fbdev;
00133 this->osd0.fbdev = NULL;
00134 }
00135
00136
00137 this->isinitialized = false;
00138 }
00139
00140 bool MMSFBDevDavinci::waitForVSync() {
00141
00142 INITCHECK;
00143
00144 if (!this->osd0.fbdev)
00145 return false;
00146
00147 static const int s = 0;
00148 if (ioctl(this->osd0.fbdev->fd, FBIO_WAITFORVSYNC, &s)) {
00149
00150 }
00151
00152 return true;
00153 }
00154
00155 bool MMSFBDevDavinci::panDisplay(int buffer_id, void *framebuffer_base) {
00156
00157 INITCHECK;
00158
00159 if ((framebuffer_base == this->osd0.fbdev->framebuffer_base)
00160 ||(framebuffer_base == this->osd1.fbdev->framebuffer_base)) {
00161
00162 if (this->osd0.fbdev)
00163 this->osd0.fbdev->panDisplay(buffer_id);
00164 if (this->osd1.fbdev)
00165 this->osd1.fbdev->panDisplay(buffer_id);
00166 return true;
00167 }
00168 else
00169 if (framebuffer_base == this->vid0.fbdev->framebuffer_base) {
00170
00171 if (this->vid0.fbdev)
00172 return this->vid0.fbdev->panDisplay(buffer_id);
00173 return false;
00174 }
00175 else
00176 if (framebuffer_base == this->vid1.fbdev->framebuffer_base) {
00177
00178 if (this->vid1.fbdev)
00179 return this->vid1.fbdev->panDisplay(buffer_id);
00180 return false;
00181 }
00182
00183
00184 printf("MMSFBDevDavinci: framebuffer base pointer not correct\n");
00185 return false;
00186 }
00187
00188 bool MMSFBDevDavinci::testLayer(int layer_id) {
00189
00190 INITCHECK;
00191
00192 switch (layer_id) {
00193 case 0:
00194
00195 return true;
00196 case 1:
00197
00198 return true;
00199 case 2:
00200
00201 return true;
00202 default:
00203 printf("MMSFBDevDavinci: layer %d is not supported\n", layer_id);
00204 break;
00205 }
00206
00207 return false;
00208 }
00209
00210
00211 bool MMSFBDevDavinci::initLayer(int layer_id, int width, int height, MMSFBSurfacePixelFormat pixelformat, int backbuffer) {
00212
00213 INITCHECK;
00214
00215 switch (layer_id) {
00216 case 0:
00217
00218 if ((!this->osd0.fbdev) || (!this->osd1.fbdev)) {
00219 printf("MMSFBDevDavinci: OSD Layer %d not initialized\n", layer_id);
00220 return false;
00221 }
00222
00223 if ((pixelformat != MMSFB_PF_ARGB3565)
00224 &&(pixelformat != MMSFB_PF_RGB16)) {
00225 printf("MMSFBDevDavinci: OSD Layer %d needs pixelformat ARGB3565 or RGB16, but %s given\n",
00226 layer_id, getMMSFBPixelFormatString(pixelformat).c_str());
00227 return false;
00228 }
00229
00230 if (backbuffer) {
00231 printf("MMSFBDevDavinci: OSD Layer %d does not support backbuffer handling\n", layer_id);
00232 return false;
00233 }
00234
00235
00236 if (this->osd0.fbdev->initLayer(0, width, height, MMSFB_PF_RGB16, backbuffer)) {
00237
00238 if (this->osd1.fbdev->initLayer(0, width, height, MMSFB_PF_A4, backbuffer)) {
00239
00240 this->layers[layer_id].width = width;
00241 this->layers[layer_id].height = height;
00242 this->layers[layer_id].pixelformat = pixelformat;
00243
00244
00245 memcpy(this->layers[layer_id].buffers, this->osd0.fbdev->layers[0].buffers, sizeof(this->osd0.fbdev->layers[0].buffers));
00246
00247
00248 if (pixelformat == MMSFB_PF_ARGB3565) {
00249
00250 switch (backbuffer) {
00251 case 2:
00252 this->layers[layer_id].buffers[2].ptr2 = this->osd1.fbdev->layers[0].buffers[2].ptr;
00253 this->layers[layer_id].buffers[2].pitch2 = this->osd1.fbdev->layers[0].buffers[2].pitch;
00254 case 1:
00255 this->layers[layer_id].buffers[1].ptr2 = this->osd1.fbdev->layers[0].buffers[1].ptr;
00256 this->layers[layer_id].buffers[1].pitch2 = this->osd1.fbdev->layers[0].buffers[1].pitch;
00257 case 0:
00258 this->layers[layer_id].buffers[0].ptr2 = this->osd1.fbdev->layers[0].buffers[0].ptr;
00259 this->layers[layer_id].buffers[0].pitch2 = this->osd1.fbdev->layers[0].buffers[0].pitch;
00260 break;
00261 default:
00262 return false;
00263 }
00264 }
00265
00266
00267 if (pixelformat == MMSFB_PF_ARGB3565) {
00268 MMSFBColor color(0x00, 0x00, 0x00, 0x00);
00269 mmsfb_fillrectangle_argb3565(&(this->layers[layer_id].buffers[0]), this->layers[layer_id].height,
00270 0, 0, this->layers[layer_id].width, this->layers[layer_id].height, color);
00271 }
00272 else {
00273 MMSFBColor color(0x00, 0x00, 0x00, 0xff);
00274 mmsfb_fillrectangle_rgb16(&(this->layers[layer_id].buffers[0]), this->layers[layer_id].height,
00275 0, 0, this->layers[layer_id].width, this->layers[layer_id].height, color);
00276 }
00277
00278
00279 this->layers[layer_id].isinitialized = true;
00280
00281 printf("MMSFBDevDavinci: OSD Layer %d initialized with %dx%dx%d, pixelformat %s\n",
00282 layer_id, width, height, backbuffer+1, getMMSFBPixelFormatString(pixelformat).c_str());
00283
00284 this->osd0.width = this->osd1.width = width;
00285 this->osd0.height = this->osd1.height = height;
00286 this->osd0.pixelformat = this->osd1.pixelformat = pixelformat;
00287 this->osd0.backbuffer = this->osd1.backbuffer = backbuffer;
00288 return true;
00289 }
00290 }
00291 return false;
00292
00293 case 1:
00294
00295 if (!this->vid0.fbdev) {
00296 printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00297 return false;
00298 }
00299
00300 if (pixelformat != MMSFB_PF_YUY2) {
00301 printf("MMSFBDevDavinci: Video Layer %d needs pixelformat YUY2, but %s given\n",
00302 layer_id, getMMSFBPixelFormatString(pixelformat).c_str());
00303 return false;
00304 }
00305
00306
00307 if (this->vid1.fbdev) {
00308 this->vid1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00309 this->vid1.width = 0;
00310 }
00311
00312
00313 if (this->vid0.fbdev->initLayer(0, width, height, MMSFB_PF_YUY2, backbuffer)) {
00314
00315 this->layers[layer_id].width = width;
00316 this->layers[layer_id].height = height;
00317 this->layers[layer_id].pixelformat = pixelformat;
00318
00319
00320 memcpy(this->layers[layer_id].buffers, this->vid0.fbdev->layers[0].buffers, sizeof(this->vid0.fbdev->layers[0].buffers));
00321
00322
00323 MMSFBColor color(0x00, 0x00, 0x00, 0xff);
00324 mmsfb_fillrectangle_yuy2(&(this->layers[layer_id].buffers[0]), this->layers[layer_id].height,
00325 0, 0, this->layers[layer_id].width, this->layers[layer_id].height, color);
00326
00327
00328 this->layers[layer_id].isinitialized = true;
00329
00330 printf("MMSFBDevDavinci: Video Layer %d initialized with %dx%dx%d, pixelformat %s\n",
00331 layer_id, width, height, backbuffer+1, getMMSFBPixelFormatString(pixelformat).c_str());
00332
00333 this->vid0.width = width;
00334 this->vid0.height = height;
00335 this->vid0.pixelformat = pixelformat;
00336 this->vid0.backbuffer = backbuffer;
00337
00338 return true;
00339 }
00340 return false;
00341
00342 case 2:
00343
00344 if (!this->vid1.fbdev) {
00345 printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00346 return false;
00347 }
00348
00349 if (pixelformat != MMSFB_PF_YUY2) {
00350 printf("MMSFBDevDavinci: Video Layer %d needs pixelformat YUY2, but %s given\n",
00351 layer_id, getMMSFBPixelFormatString(pixelformat).c_str());
00352 return false;
00353 }
00354
00355
00356 if (this->vid0.fbdev) {
00357 this->vid0.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00358 this->vid0.width = 0;
00359 }
00360
00361
00362 if (this->vid1.fbdev->initLayer(0, width, height, MMSFB_PF_YUY2, backbuffer)) {
00363
00364 this->layers[layer_id].width = width;
00365 this->layers[layer_id].height = height;
00366 this->layers[layer_id].pixelformat = pixelformat;
00367
00368
00369 memcpy(this->layers[layer_id].buffers, this->vid1.fbdev->layers[0].buffers, sizeof(this->vid1.fbdev->layers[0].buffers));
00370
00371
00372 MMSFBColor color(0x00, 0x00, 0x00, 0xff);
00373 mmsfb_fillrectangle_yuy2(&(this->layers[layer_id].buffers[0]), this->layers[layer_id].height,
00374 0, 0, this->layers[layer_id].width, this->layers[layer_id].height, color);
00375
00376
00377 this->layers[layer_id].isinitialized = true;
00378
00379 printf("MMSFBDevDavinci: Video Layer %d initialized with %dx%dx%d, pixelformat %s\n",
00380 layer_id, width, height, backbuffer+1, getMMSFBPixelFormatString(pixelformat).c_str());
00381
00382 this->vid1.width = width;
00383 this->vid1.height = height;
00384 this->vid1.pixelformat = pixelformat;
00385 this->vid1.backbuffer = backbuffer;
00386
00387 return true;
00388 }
00389 return false;
00390 default:
00391 printf("MMSFBDevDavinci: layer %d is not supported\n", layer_id);
00392 break;
00393 }
00394
00395 return false;
00396 }
00397
00398 bool MMSFBDevDavinci::releaseLayer(int layer_id) {
00399
00400 INITCHECK;
00401
00402 switch (layer_id) {
00403 case 0:
00404
00405 printf("MMSFBDevDavinci: layer %d cannot be released\n", layer_id);
00406 return false;
00407 case 1:
00408
00409 if (this->vid0.fbdev) {
00410
00411 this->vid0.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00412
00413 this->vid0.fbdev->closeDevice();
00414 return true;
00415 }
00416 printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00417 return false;
00418 case 2:
00419
00420 if (this->vid1.fbdev) {
00421
00422 this->vid1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00423
00424 this->vid1.fbdev->closeDevice();
00425 return true;
00426 }
00427 printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00428 return false;
00429 default:
00430 printf("MMSFBDevDavinci: layer %d is not supported\n", layer_id);
00431 break;
00432 }
00433
00434 return false;
00435 }
00436
00437 bool MMSFBDevDavinci::restoreLayer(int layer_id) {
00438
00439 INITCHECK;
00440
00441 switch (layer_id) {
00442 case 0:
00443
00444 printf("MMSFBDevDavinci: layer %d cannot be restored\n", layer_id);
00445 return false;
00446 case 1:
00447
00448 if (this->vid0.fbdev) {
00449 if (this->vid0.fbdev->openDevice(this->vid0.device, -2)) {
00450 if (!this->vid0.width)
00451 return this->vid0.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00452 else
00453 if (this->vid0.width > 0)
00454 return this->vid0.fbdev->initLayer(0, this->vid0.width, this->vid0.height,
00455 this->vid0.pixelformat, this->vid0.backbuffer);
00456 return true;
00457 }
00458 return false;
00459 }
00460 printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00461 return false;
00462 case 2:
00463
00464 if (this->vid1.fbdev) {
00465 if (this->vid1.fbdev->openDevice(this->vid1.device, -2)) {
00466 if (!this->vid1.width)
00467 return this->vid1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00468 else
00469 if (this->vid1.width > 0)
00470 return this->vid1.fbdev->initLayer(0, this->vid1.width, this->vid1.height,
00471 this->vid1.pixelformat, this->vid1.backbuffer);
00472 return true;
00473 }
00474 return false;
00475 }
00476 printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00477 return false;
00478 default:
00479 printf("MMSFBDevDavinci: layer %d is not supported\n", layer_id);
00480 break;
00481 }
00482
00483 return false;
00484 }
00485
00486 bool MMSFBDevDavinci::vtGetFd(int *fd) {
00487 if (this->osd0.fbdev) {
00488 if (this->osd0.fbdev->vt.fd != -1) {
00489 *fd = this->osd0.fbdev->vt.fd;
00490 return true;
00491 }
00492 }
00493 return false;
00494 }
00495
00496 #endif