diff options
| author | dknn <yoann.blein@free.fr> | 2012-08-16 21:52:56 (GMT) | 
|---|---|---|
| committer | dknn <yoann.blein@free.fr> | 2012-09-22 09:32:38 (GMT) | 
| commit | dce09fe24d55d67f60d7bc691e285897f1d64fc2 (patch) | |
| tree | f064c11c7c25a647a73c42d01e2cb836ea601bb3 | |
| parent | 867a950d5b3eb1422051a57c2533509188014b1a (diff) | |
| download | swift-contrib-dce09fe24d55d67f60d7bc691e285897f1d64fc2.zip swift-contrib-dce09fe24d55d67f60d7bc691e285897f1d64fc2.tar.bz2 | |
Add error resilience on decoder side
| -rw-r--r-- | Swift/Controllers/ScreenSharing/ScreenSharingController.cpp | 3 | ||||
| -rw-r--r-- | Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp | 41 | ||||
| -rw-r--r-- | Swiften/ScreenSharing/ScreenSharing.cpp | 5 | ||||
| -rw-r--r-- | Swiften/ScreenSharing/VP8Decoder.cpp | 37 | ||||
| -rw-r--r-- | Swiften/ScreenSharing/VP8Decoder.h | 2 | ||||
| -rw-r--r-- | Swiften/ScreenSharing/VP8Encoder.cpp | 1 | 
6 files changed, 74 insertions, 15 deletions
| 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 <QApplication>  #include <QDesktopWidget> +#include <QPainter> +#include <QColor> +  #include <Swiften/ScreenSharing/Image.h> -/*#include <QImage> -#include <QLabel>*/ +#include <Swiften/Base/Log.h>  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_ptr<JingleRawUDPTransportPayl  				if (addr.getRawAddress().is_v6() && addr.toString().compare(2, scopeLinkBeginning.length(), scopeLinkBeginning) == 0)  					continue; -				int port = serverSocket->bindOnAvailablePort(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<uint8_t>& 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;  	} | 
 Swift
 Swift