When trying to generate an avatar from a webcam capture, kopete crashed. I fixed the crash and committed it (just a guard on the size of the destination of memcpy - r1066810 [trunk], r1066826 [4.3]), but the underlying problem was still there, causing the image from the webcam to be screwed up.
The problem is that the configure dialog's A/V page webcam widget sets the webcam capture size to 320x240, then the avatar webcam dialog tries to set it to 640x480. This fails (because the device is in use), but the VideoDevice class goes ahead assuming it worked. The attached patch is a quick fix for it. It also fixes the problem where you can get a camera listed multiple times in the A/V config page. The fix is pretty straightforward and minimal - I'd like to tidy up the webcam support in kopete properly when we're out of feature freeze. Alex -- Why have I got six monitors? Because I haven't got room for eight. -- Terry Pratchett
Index: libkopete/ui/avatarwebcamdialog.cpp =================================================================== --- libkopete/ui/avatarwebcamdialog.cpp (revision 1066578) +++ libkopete/ui/avatarwebcamdialog.cpp (working copy) @@ -65,6 +65,7 @@ d->m_devicePool = Kopete::AV::VideoDevicePool::self(); d->m_devicePool->loadConfig(); d->m_devicePool->open(); + // NB: this may fail if the device is already in use d->m_devicePool->setSize(640, 480); d->m_devicePool->startCapturing(); #endif @@ -73,7 +74,8 @@ connect( d->m_timer, SIGNAL(timeout()), this, SLOT(updateImage())); d->mainWidget = new Kopete::WebcamWidget(this); - d->mainWidget->setMinimumSize(645, 485); + d->mainWidget->setMinimumSize(d->m_devicePool->width() + 5, + d->m_devicePool->height() + 5); d->m_timer->start(40); setMainWidget(d->mainWidget); } Index: libkopete/avdevice/videodevicepool.cpp =================================================================== --- libkopete/avdevice/videodevicepool.cpp (revision 1066578) +++ libkopete/avdevice/videodevicepool.cpp (working copy) @@ -640,15 +640,19 @@ { /// @todo implement me - kDebug() << "called"; + if (m_videodevice.isEmpty()) { + kDebug() << "called"; #if defined(__linux__) && defined(ENABLE_AV) - foreach (Solid::Device device, - Solid::Device::listFromType(Solid::DeviceInterface::Video, QString())) { - registerDevice( device ); - } + foreach (Solid::Device device, + Solid::Device::listFromType(Solid::DeviceInterface::Video, QString())) { + registerDevice( device ); + } #endif - kDebug() << "exited successfuly"; + kDebug() << "exited successfuly"; + } else { + kDebug() << "Not scanning: initial device list already loaded"; + } return EXIT_SUCCESS; } Index: libkopete/avdevice/videodevice.cpp =================================================================== --- libkopete/avdevice/videodevice.cpp (revision 1066810) +++ libkopete/avdevice/videodevice.cpp (working copy) @@ -628,34 +628,35 @@ // It should not be there. It must remain in a completely distict place, cause this method should not change the pixelformat. // It shouldn't try to find a suitable pixel format this way. It should use values discovered by - detectPixelFormats() - to choose a valid one. kDebug() << "Trying YUY422P"; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_YUV422P)) + errno = 0; + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_YUV422P) && errno != EBUSY) { kDebug() << "Device doesn't seem to support YUV422P format. Trying YUYV."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_YUYV)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_YUYV) && errno != EBUSY) { kDebug() << "Device doesn't seem to support YUYV format. Trying UYVY."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_UYVY)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_UYVY) && errno != EBUSY) { kDebug() << "Device doesn't seem to support UYVY format. Trying YUV420P."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_YUV420P)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_YUV420P) && errno != EBUSY) { kDebug() << "Device doesn't seem to support YUV420P format. Trying RGB24."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_RGB24)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_RGB24) && errno != EBUSY) { kDebug() << "Device doesn't seem to support RGB24 format. Trying BGR24."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_BGR24)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_BGR24) && errno != EBUSY) { kDebug() << "Device doesn't seem to support RGB24 format. Trying RGB32."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_RGB32)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_RGB32) && errno != EBUSY) { kDebug() << "Device doesn't seem to support RGB32 format. Trying BGR32."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_BGR32)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_BGR32) && errno != EBUSY) { kDebug() << "Device doesn't seem to support BGR32 format. Trying SBGGR8."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_SBGGR8)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_SBGGR8) && errno != EBUSY) { kDebug() << "Device doesn't seem to support SBGGR8 format. Trying SN9C10X."; - if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_SN9C10X)) + if(PIXELFORMAT_NONE == setPixelFormat(PIXELFORMAT_SN9C10X) && errno != EBUSY) { kDebug() << "Device doesn't seem to support BGR32 format. Fallback to it is not yet implemented."; } @@ -668,6 +669,10 @@ } } } + if (errno == EBUSY) { + kDebug() << "Can't change the video size: device in use"; + return EXIT_FAILURE; + } if(newwidth > maxwidth ) newwidth = maxwidth; if(newheight > maxheight) newheight = maxheight;
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ kopete-devel mailing list kopete-devel@kde.org https://mail.kde.org/mailman/listinfo/kopete-devel