From dce09fe24d55d67f60d7bc691e285897f1d64fc2 Mon Sep 17 00:00:00 2001 From: dknn Date: Thu, 16 Aug 2012 23:52:56 +0200 Subject: Add error resilience on decoder side diff --git a/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp b/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp index b932765..2e9a75d 100644 --- a/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp +++ b/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp @@ -123,7 +123,8 @@ void ScreenSharingController::handleStateChange(ScreenSharing::SCState state) void ScreenSharingController::handleWindowStopRequest() { remoteScreenWindow->onStopRequest.disconnect(boost::bind(&ScreenSharingController::handleWindowStopRequest, this)); - screenSharing->stop(); + if (screenSharing) + screenSharing->stop(); } } diff --git a/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp b/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp index a5eeafd..aae2ff1 100644 --- a/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp +++ b/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp @@ -11,20 +11,17 @@ #include #include +#include +#include + #include -/*#include -#include */ +#include namespace Swift { QtDesktopScreenGrabber::QtDesktopScreenGrabber() { - /*Image img = grab(); - QImage qImg(img.data.data(), img.width, img.height, QImage::Format_RGB888); - QLabel *label = new QLabel; - label->setPixmap(QPixmap::fromImage(qImg)); - label->show();*/ } QtDesktopScreenGrabber::~QtDesktopScreenGrabber() @@ -33,7 +30,35 @@ QtDesktopScreenGrabber::~QtDesktopScreenGrabber() Image QtDesktopScreenGrabber::grab() const { - QImage qImg = QPixmap::grabWindow(QApplication::desktop()->winId()).toImage().convertToFormat(QImage::Format_RGB888); + QImage qImg = QPixmap::grabWindow(QApplication::desktop()->winId()).toImage();//.convertToFormat(QImage::Format_RGB888); +// QImage qImg("/home/yb/Images/wallpaper-1681250.jpg"); + qImg = qImg.scaled(qImg.width() * 0.7, qImg.height() * 0.7, Qt::KeepAspectRatio, Qt::SmoothTransformation); +// SWIFT_LOG(debug) << "Format RGB32: " << (qImg.format() == QImage::Format_RGB32) << std::endl; + +// QImage qImg(1920, 1080, QImage::Format_RGB32); +// qImg.fill(QColor(qrand() % 255, qrand()%255, qrand()%255)); +// QPainter p(&qImg); +// p.translate(qImg.width() / 2, qImg.height() / 2); +// p.setBrush(Qt::black); +// static int x = 0; +// static int y = 0; +// x = (x+50)%qImg.width(); +// y = (y+50)%qImg.height(); +// p.drawEllipse(x, y, 100, 100); + +// for (int i = 0; i < 40; ++i) { +// p.setBrush(QColor(qrand() % 255, qrand()%255, qrand()%255)); +// p.drawEllipse(qrand()%qImg.width(), qrand()%qImg.height(), qrand()%(qImg.width()/4), qrand()%(qImg.height()/4)); +// } +// p.end(); + + qImg = qImg.convertToFormat(QImage::Format_RGB888); + +// uchar* bits = qImg.bits(); +// for (int i = 0; i < qImg.byteCount(); ++i) { +// bits[i] = qrand(); +// } + return Image(qImg.width(), qImg.height(), qImg.constBits()); } diff --git a/Swiften/ScreenSharing/ScreenSharing.cpp b/Swiften/ScreenSharing/ScreenSharing.cpp index 7fb1280..f2977a2 100644 --- a/Swiften/ScreenSharing/ScreenSharing.cpp +++ b/Swiften/ScreenSharing/ScreenSharing.cpp @@ -84,8 +84,9 @@ bool ScreenSharing::addBestCandidate(boost::shared_ptrbindOnAvailablePort(addr); -// int port = serverSocket->bind(HostAddressPort(addr, 29999)); + int port = serverSocket->bind(HostAddressPort(addr, 29999)); + if (port != 29999) + port = serverSocket->bindOnAvailablePort(addr); if (!port) continue; diff --git a/Swiften/ScreenSharing/VP8Decoder.cpp b/Swiften/ScreenSharing/VP8Decoder.cpp index 2634cc5..90f5101 100644 --- a/Swiften/ScreenSharing/VP8Decoder.cpp +++ b/Swiften/ScreenSharing/VP8Decoder.cpp @@ -19,7 +19,7 @@ inline int clamp8(int v) VP8Decoder::VP8Decoder() : VideoDecoder(), - codecInterface(vpx_codec_vp8_dx()), codecFlags(0) + codecInterface(vpx_codec_vp8_dx()), codecFlags(0), refFrame(0) { SWIFT_LOG(debug) << "VP8 Decoder:" << vpx_codec_iface_name(codecInterface) << std::endl; @@ -28,6 +28,11 @@ VP8Decoder::VP8Decoder() VP8Decoder::~VP8Decoder() { + vpx_codec_destroy(&codecContext); + if (refFrame) { + vpx_img_free(&refFrame->img); + delete refFrame; + } } void VP8Decoder::updateCodecConfig() @@ -53,10 +58,34 @@ void VP8Decoder::decodeFrame(const std::vector& frame, int pictureID) } vpx_codec_iter_t iter = NULL; - vpx_image_t* img; - while ((img = vpx_codec_get_frame(&codecContext, &iter))) { - Image rgbImg = convertYV12toRGB(img); + vpx_image_t* decodedImg; + while ((decodedImg = vpx_codec_get_frame(&codecContext, &iter))) { + Image rgbImg = convertYV12toRGB(decodedImg); onNewImageAvailable(rgbImg); + // Restore ref from last save if corrupted, else save the ref + int corrupted = 0; + vpx_codec_control(&codecContext, VP8D_GET_FRAME_CORRUPTED, &corrupted); + if (corrupted) { + vpx_codec_control(&codecContext, VP8_SET_REFERENCE, refFrame); + } else { + // Re-alloc the image ref if the format has changed + if (refFrame && (decodedImg->d_w != refFrame->img.d_w + || decodedImg->d_h != refFrame->img.d_h + || decodedImg->fmt != refFrame->img.fmt)) { + vpx_img_free(&refFrame->img); + delete refFrame; + refFrame = 0; + } + if (!refFrame) { + refFrame = new vpx_ref_frame_t; + refFrame->frame_type = VP8_LAST_FRAME; + unsigned int align = 1; + if (decodedImg->d_w % 32 == 0) + align = 32; + vpx_img_alloc(&refFrame->img, decodedImg->fmt, decodedImg->d_w, decodedImg->d_h, align); + } + vpx_codec_control(&codecContext, VP8_COPY_REFERENCE, refFrame); + } } } diff --git a/Swiften/ScreenSharing/VP8Decoder.h b/Swiften/ScreenSharing/VP8Decoder.h index 0bdc664..0ed6334 100644 --- a/Swiften/ScreenSharing/VP8Decoder.h +++ b/Swiften/ScreenSharing/VP8Decoder.h @@ -10,6 +10,7 @@ #define VPX_CODEC_DISABLE_COMPAT 1 #include "vpx/vpx_decoder.h" +#include "vpx/vp8.h" namespace Swift { class Image; @@ -30,5 +31,6 @@ namespace Swift { vpx_codec_iface_t* codecInterface; vpx_codec_ctx_t codecContext; vpx_codec_flags_t codecFlags; + vpx_ref_frame_t* refFrame; }; } diff --git a/Swiften/ScreenSharing/VP8Encoder.cpp b/Swiften/ScreenSharing/VP8Encoder.cpp index c25e153..e48d6d9 100644 --- a/Swiften/ScreenSharing/VP8Encoder.cpp +++ b/Swiften/ScreenSharing/VP8Encoder.cpp @@ -76,6 +76,7 @@ void VP8Encoder::encodeImage(const Image& frame) vpx_enc_frame_flags_t localFrameFlags = frameFlags; if (!rpsiReceived && frameNumber > 1) { + SWIFT_LOG(error) << "VP8 Encoder: RPSI not received, do not ref last frame" << std::endl; localFrameFlags |= VP8_EFLAG_NO_REF_LAST; // VP8_EFLAG_FORCE_GF; // TODO: VP8_EFLAG_NO_REF_LAST; } -- cgit v0.10.2-6-g49f6