From 39ac2af90938aec4f4e43b81a6e043e0ebcdd798 Mon Sep 17 00:00:00 2001
From: dknn <yoann.blein@free.fr>
Date: Tue, 26 Jun 2012 16:05:35 +0200
Subject: Single threaded codec


diff --git a/Swiften/ScreenSharing/Image.cpp b/Swiften/ScreenSharing/Image.cpp
new file mode 100644
index 0000000..c3acd69
--- /dev/null
+++ b/Swiften/ScreenSharing/Image.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/Image.h>
+
+namespace Swift {
+
+Image::Image(int width, int height, uint8_t* rgb24data)
+	: width(width), height(height)
+{
+	int len = width * height * 3;
+	if (rgb24data) {
+		data.insert(data.begin(), rgb24data, rgb24data + len);
+	} else {
+		data.resize(len);
+	}
+}
+
+}
diff --git a/Swiften/ScreenSharing/Image.h b/Swiften/ScreenSharing/Image.h
new file mode 100644
index 0000000..5cdf043
--- /dev/null
+++ b/Swiften/ScreenSharing/Image.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <stdint.h>
+
+namespace Swift {
+	class Image {
+		public:
+			typedef boost::shared_ptr<Image> ref;
+
+			Image(int width, int height, uint8_t* rgb24data = 0);
+
+			int width;
+			int height;
+			std::vector<uint8_t> data;
+	};
+}
diff --git a/Swiften/ScreenSharing/SConscript b/Swiften/ScreenSharing/SConscript
index 21b8aa9..3658173 100644
--- a/Swiften/ScreenSharing/SConscript
+++ b/Swiften/ScreenSharing/SConscript
@@ -1,9 +1,11 @@
 Import("swiften_env", "env")
 
 sources = [
-		"VideoFrame.cpp",
-		"VideoEncoder.cpp",
+		"Image.cpp",
 		"VP8Encoder.cpp",
+		"VP8RTPPacketizer.cpp",
+		"VP8Decoder.cpp",
+		"VP8RTPParser.cpp",
 	]
 
 swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources))
diff --git a/Swiften/ScreenSharing/VP8Decoder.cpp b/Swiften/ScreenSharing/VP8Decoder.cpp
new file mode 100644
index 0000000..40f631f
--- /dev/null
+++ b/Swiften/ScreenSharing/VP8Decoder.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/VP8Decoder.h>
+
+#include <Swiften/ScreenSharing/Image.h>
+#include <Swiften/Base/Log.h>
+#include "vpx/vp8dx.h"
+
+namespace Swift {
+
+inline int clamp8(int v)
+{
+	return std::min(std::max(v, 0), 255);
+}
+
+VP8Decoder::VP8Decoder()
+	: VideoDecoder(),
+	  codecInterface(vpx_codec_vp8_dx()), codecFlags(0)
+{
+	SWIFT_LOG(debug) << "VP8 Decoder:" << vpx_codec_iface_name(codecInterface) << std::endl;
+
+	updateCodecConfig();
+}
+
+VP8Decoder::~VP8Decoder()
+{
+}
+
+void VP8Decoder::updateCodecConfig()
+{
+	// TODO: vpx_codec_flags_t flags = VPX_CODEC_USE_INPUT_FRAGMENTS;
+	vpx_codec_err_t err = vpx_codec_dec_init(&codecContext, codecInterface, NULL, codecFlags);
+	if (err) {
+		SWIFT_LOG(debug) << "VP8 Decoder: Failed to initialize decoder, " << vpx_codec_err_to_string(err) << std::endl;
+		// TODO: exception ?
+	}
+}
+
+void VP8Decoder::decodeFrame(const std::vector<uint8_t>& frame)
+{
+	// Decode the frame
+	vpx_codec_err_t err = vpx_codec_decode(&codecContext, &frame[0], frame.size(), NULL, 0);
+	if (err) {
+		SWIFT_LOG(debug) << "VP8 Decoder: Failed to decode frame, " << vpx_codec_err_to_string(err) << std::endl;
+		// TODO: exception ?
+		return;
+	}
+
+	vpx_codec_iter_t iter = NULL;
+	vpx_image_t* img;
+	while ((img = vpx_codec_get_frame(&codecContext, &iter))) {
+		Image rgbImg = convertYV12toRGB(img);
+		onNewImageDecoded(rgbImg);
+	}
+}
+
+Image VP8Decoder::convertYV12toRGB(const vpx_image_t* img)
+{
+	Image rgbImg(img->d_w, img->d_h);
+	std::vector<uint8_t>& data = rgbImg.data;
+
+	uint8_t *yPlane = img->planes[VPX_PLANE_Y];
+	uint8_t *uPlane = img->planes[VPX_PLANE_U];
+	uint8_t *vPlane = img->planes[VPX_PLANE_V];
+
+	int i = 0;
+	for (unsigned int imgY = 0; imgY < img->d_h; imgY++) {
+		for (unsigned int imgX = 0; imgX < img->d_w; imgX++) {
+			int y = yPlane[imgY * img->stride[VPX_PLANE_Y] + imgX];
+			int u = uPlane[(imgY / 2) * img->stride[VPX_PLANE_U] + (imgX / 2)];
+			int v = vPlane[(imgY / 2) * img->stride[VPX_PLANE_V] + (imgX / 2)];
+
+			int c = y - 16;
+			int d = (u - 128);
+			int e = (v - 128);
+
+			// TODO: adjust colors ?
+
+			int r = clamp8((298 * c           + 409 * e + 128) >> 8);
+			int g = clamp8((298 * c - 100 * d - 208 * e + 128) >> 8);
+			int b = clamp8((298 * c + 516 * d           + 128) >> 8);
+
+			// TODO: cast instead of clamp8
+
+			data[i + 0] = static_cast<uint8_t>(r);
+			data[i + 1] = static_cast<uint8_t>(g);
+			data[i + 2] = static_cast<uint8_t>(b);
+
+			i += 3;
+		}
+	}
+	return rgbImg;
+}
+
+}
diff --git a/Swiften/ScreenSharing/VP8Decoder.h b/Swiften/ScreenSharing/VP8Decoder.h
new file mode 100644
index 0000000..8b2575a
--- /dev/null
+++ b/Swiften/ScreenSharing/VP8Decoder.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/ScreenSharing/VideoDecoder.h>
+
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include "vpx/vpx_decoder.h"
+
+namespace Swift {
+	class Image;
+
+	class VP8Decoder : public VideoDecoder {
+		public:
+			VP8Decoder();
+			virtual ~VP8Decoder();
+
+			void updateCodecConfig();
+
+			virtual void decodeFrame(const std::vector<uint8_t>& frame);
+
+		private:
+			Image convertYV12toRGB(const vpx_image_t* img);
+
+		private:
+			vpx_codec_iface_t* codecInterface;
+			vpx_codec_ctx_t codecContext;
+			vpx_codec_flags_t codecFlags;
+	};
+}
diff --git a/Swiften/ScreenSharing/VP8Encoder.cpp b/Swiften/ScreenSharing/VP8Encoder.cpp
index 20c73f9..3ca0edd 100644
--- a/Swiften/ScreenSharing/VP8Encoder.cpp
+++ b/Swiften/ScreenSharing/VP8Encoder.cpp
@@ -5,13 +5,16 @@
  */
 
 #include <Swiften/ScreenSharing/VP8Encoder.h>
+#include <Swiften/ScreenSharing/Image.h>
+#include <Swiften/ScreenSharing/VP8RTPPacketizer.h>
 #include <Swiften/Base/Log.h>
 #include "vpx/vp8cx.h"
 
 namespace Swift {
 
-VP8Encoder::VP8Encoder(unsigned int  width, unsigned int  height) :
-	codecInterface(vpx_codec_vp8_cx()), imageBuffer(0), codecFlags(0), frameFlags(0), frameNumber(0)
+VP8Encoder::VP8Encoder(VP8RTPPacketizer* packetizer, unsigned int  width, unsigned int  height)
+	: VideoEncoder(),
+	  packetizer(packetizer), codecInterface(vpx_codec_vp8_cx()), imageBuffer(0), codecFlags(0), frameFlags(0), frameNumber(0)
 {
 	SWIFT_LOG(debug) << "VP8 Encoder:" << vpx_codec_iface_name(codecInterface) << std::endl;
 
@@ -49,6 +52,7 @@ void VP8Encoder::updateCodecConfig()
 	if (err) {
 		SWIFT_LOG(debug) << "VP8 Encoder: Failed to initialize encoder, " << vpx_codec_err_to_string(err) << std::endl;
 		// TODO: exception
+		return;
 	}
 
 	imageBuffer = vpx_img_alloc(0, VPX_IMG_FMT_YV12, codecConfig.g_w, codecConfig.g_h, 1);
@@ -58,65 +62,63 @@ void VP8Encoder::updateCodecConfig()
 	}
 }
 
-void VP8Encoder::encodingLoop()
+void VP8Encoder::encodeImage(const Image &frame)
 {
-	while (!stop) {
-		VideoFrame::ref frame = popWhenFrameIsAvailable();
-		if (stop)
-			return;
-
-		if (!convertRGB24toYV12inBuffer(frame)) {
-			SWIFT_LOG(debug) << "VP8 Encoder: Failed to convert frame: Image buffer not initialized" << std::endl;
-			return;
-		}
+	if (!convertRGB24toYV12inBuffer(frame)) {
+		SWIFT_LOG(debug) << "VP8 Encoder: Failed to convert frame: Image buffer not initialized" << std::endl;
+		// TODO: exception ?
+		return;
+	}
 
-		vpx_codec_err_t err = vpx_codec_encode(&codecContext, imageBuffer, frameNumber, 1, frameFlags, VPX_DL_REALTIME);
-		if (err) {
-			SWIFT_LOG(debug) << "VP8 Encoder: Failed to encode frame, " << vpx_codec_err_to_string(err) << std::endl;
-			// TODO: signal ?
-			return;
-		}
+	vpx_codec_err_t err = vpx_codec_encode(&codecContext, imageBuffer, frameNumber, 1, frameFlags, VPX_DL_REALTIME);
+	if (err) {
+		SWIFT_LOG(debug) << "VP8 Encoder: Failed to encode frame, " << vpx_codec_err_to_string(err) << std::endl;
+		// TODO: exception ?
+		return;
+	}
 
-		const vpx_codec_cx_pkt_t *pkt;
-		vpx_codec_iter_t iter = NULL;
-		while ((pkt = vpx_codec_get_cx_data(&codecContext, &iter))) {
-			switch (pkt->kind) {
-				case VPX_CODEC_CX_FRAME_PKT:
-					// TODO: Packetize this frame data
-					break;
-				default:
-					break;
-			}
+	const vpx_codec_cx_pkt_t* pkt;
+	vpx_codec_iter_t iter = NULL;
+	while ((pkt = vpx_codec_get_cx_data(&codecContext, &iter))) {
+		switch (pkt->kind) {
+			case VPX_CODEC_CX_FRAME_PKT:
+				// TODO: Packetize this frame data
+				packetizer->packetizeFrame(pkt);
+				break;
+			default:
+				break;
 		}
-
-		++frameNumber;
 	}
+
+	++frameNumber;
 }
 
-bool VP8Encoder::convertRGB24toYV12inBuffer(const VideoFrame::ref frame)
+bool VP8Encoder::convertRGB24toYV12inBuffer(const Image &frame)
 {
 	if (!imageBuffer)
 		return false;
 
-	uint8_t *yPlane = imageBuffer->planes[VPX_PLANE_Y];
-	uint8_t *uPlane = imageBuffer->planes[VPX_PLANE_U];
-	uint8_t *vPlane = imageBuffer->planes[VPX_PLANE_V];
+	uint8_t* yPlane = imageBuffer->planes[VPX_PLANE_Y];
+	uint8_t* uPlane = imageBuffer->planes[VPX_PLANE_U];
+	uint8_t* vPlane = imageBuffer->planes[VPX_PLANE_V];
 
-	unsigned int width = frame->width;
-	unsigned int height = frame->height;
+	unsigned int width = frame.width;
+	unsigned int height = frame.height;
 	unsigned int len = width * height;
-	const std::vector<uint8_t> &data = frame->data;
+	const std::vector<uint8_t> &data = frame.data;
 
 	for (unsigned int  i = 0; i < len; ++i) {
-		yPlane[i] = data[i * 3];
+		const uint8_t* p = &data[3 * i];
+		yPlane[i] = ((66 * p[0] + 129 * p[1] + 25 * p[2] + 128) >> 8) + 16;
 	}
 
 	for (unsigned int line = 0; line < height / 2; ++line) {
 		for (unsigned int col = 0; col < width / 2; ++col) {
-			const uint8_t *p1 = &data[3 * (2 * (line * width + col))];
-			const uint8_t *p2 = &data[3 * (2 * (line * width + col) + 1)];
-			const uint8_t *p3 = &data[3 * (2 * (line * width + col) + width)];
-			const uint8_t *p4 = &data[3 * (2 * (line * width + col) + width + 1)];
+			int pos = 2 * (line * width + col);
+			const uint8_t* p1 = &data[3 * (pos)];
+			const uint8_t* p2 = &data[3 * (pos + 1)];
+			const uint8_t* p3 = &data[3 * (pos + width)];
+			const uint8_t* p4 = &data[3 * (pos + width + 1)];
 
 			int r = (p1[0] + p2[0] + p3[0] + p4[0]) * 0.25;
 			int g = (p1[1] + p2[1] + p3[1] + p4[1]) * 0.25;
diff --git a/Swiften/ScreenSharing/VP8Encoder.h b/Swiften/ScreenSharing/VP8Encoder.h
index b512058..0a343bb 100644
--- a/Swiften/ScreenSharing/VP8Encoder.h
+++ b/Swiften/ScreenSharing/VP8Encoder.h
@@ -4,47 +4,39 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
-#ifndef VP8ENCODER_H
-#define VP8ENCODER_H
-
 #pragma once
 
 #include <Swiften/ScreenSharing/VideoEncoder.h>
-#include <Swiften/Base/boost_bsignals.h>
-
 
 #define VPX_CODEC_DISABLE_COMPAT 1 // Recomended
 #include "vpx/vpx_encoder.h"
 
 
 namespace Swift {
+	class Image;
+	class VP8RTPPacketizer;
+
 	class VP8Encoder : public VideoEncoder {
 		public:
-			VP8Encoder(unsigned int width, unsigned int height);
+			VP8Encoder(VP8RTPPacketizer* packetizer, unsigned int width, unsigned int height);
 			virtual ~VP8Encoder();
 
 			void updateCodecConfig();
 
-		public:
-			boost::signal<void (const vpx_codec_cx_pkt_t *)> onNewFrameEncoded;
-
-		protected:
-			virtual void encodingLoop();
+			virtual void encodeImage(const Image& frame);
 
 		private:
-			bool convertRGB24toYV12inBuffer(const VideoFrame::ref frame);
+			bool convertRGB24toYV12inBuffer(const Image& frame);
 
 		private:
+			VP8RTPPacketizer* packetizer;
 			vpx_codec_iface_t* codecInterface;
 			vpx_codec_ctx_t codecContext;
 			vpx_codec_enc_cfg_t codecConfig;
-			vpx_image_t *imageBuffer;
+			vpx_image_t* imageBuffer;
 			vpx_codec_flags_t codecFlags;
 			vpx_enc_frame_flags_t frameFlags;
 			int frameNumber;
 	};
 
 }
-
-
-#endif // VP8ENCODER_H
diff --git a/Swiften/ScreenSharing/VP8RTPPacketizer.cpp b/Swiften/ScreenSharing/VP8RTPPacketizer.cpp
new file mode 100644
index 0000000..4c1e8e9
--- /dev/null
+++ b/Swiften/ScreenSharing/VP8RTPPacketizer.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/VP8RTPPacketizer.h>
+
+
+namespace Swift {
+
+VP8RTPPacketizer::VP8RTPPacketizer()
+{
+}
+
+void VP8RTPPacketizer::packetizeFrame(const vpx_codec_cx_pkt_t* pkt)
+{
+	if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
+		return;
+
+	// only case there is no partitions is handle (TODO: implement partitions)
+	if (pkt->data.frame.partition_id != -1)
+		return;
+
+	size_t size = pkt->data.frame.sz;
+	uint8_t* buf = static_cast<uint8_t*>(pkt->data.frame.buf);
+	size_t sent = 0;
+	bool firstPacket = true;
+
+	while (sent < size) {
+		payloadBuffer.clear();
+
+		// Payload descriptor
+		uint8_t req = 0;
+		if (firstPacket)
+			req |= SBit;
+		payloadBuffer.push_back(req);
+
+		// Payload header
+		if (firstPacket) {
+			firstPacket = false;
+
+			uint8_t o1 = (size & Size0BitMask) << Size0BitShift; // Size0
+			o1 |= HBit; // H (show frame)
+			if (!(pkt->data.frame.flags & VPX_FRAME_IS_KEY))
+				o1 |= 1; // P (Inverse key frame)
+			payloadBuffer.push_back(o1);
+			payloadBuffer.push_back(static_cast<uint8_t>(size >> 3)); // Size1
+			payloadBuffer.push_back(static_cast<uint8_t>(size >> 11)); // Size2
+		}
+
+		// Payload content
+		size_t toSend = std::min(size - sent, MaxRTPPayloadSize - payloadBuffer.size());
+		payloadBuffer.insert(payloadBuffer.end(), buf, buf + toSend);
+
+		sent += toSend;
+		buf += toSend;
+
+		// Mark rtp packet if last of the curr frame
+		bool lastPacket = (sent >= size);
+
+		// TODO: send packet
+		//parser.newPayloadReceived(&payloadBuffer[0], payloadBuffer.size(), lastPacket);
+		onNewPayloadReady(payloadBuffer, lastPacket);
+	}
+}
+
+}
diff --git a/Swiften/ScreenSharing/VP8RTPPacketizer.h b/Swiften/ScreenSharing/VP8RTPPacketizer.h
new file mode 100644
index 0000000..0ef48be
--- /dev/null
+++ b/Swiften/ScreenSharing/VP8RTPPacketizer.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <stdint.h>
+#include <Swiften/Base/boost_bsignals.h>
+#include "vpx/vpx_encoder.h"
+
+
+namespace Swift {
+	class SafeByteArray;
+
+	class VP8RTPPacketizer {
+		public:
+			VP8RTPPacketizer();
+
+			void packetizeFrame(const vpx_codec_cx_pkt_t* pkt);
+
+			boost::signal<void (const std::vector<uint8_t>&, bool marker)> onNewPayloadReady;
+
+		private:
+			static const uint8_t SBit = 1 << 4;
+			static const uint8_t HBit = 1 << 4;
+			static const uint8_t Size0BitMask = 7;
+			static const uint8_t Size0BitShift = 5;
+			static const size_t MaxRTPPayloadSize = 1400; // Replace with JRTPLIB's one
+
+			std::vector<uint8_t> payloadBuffer;
+	};
+}
diff --git a/Swiften/ScreenSharing/VP8RTPParser.cpp b/Swiften/ScreenSharing/VP8RTPParser.cpp
new file mode 100644
index 0000000..5a725ea
--- /dev/null
+++ b/Swiften/ScreenSharing/VP8RTPParser.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/VP8RTPParser.h>
+
+#include <Swiften/ScreenSharing/VP8Decoder.h>
+
+namespace Swift {
+
+VP8RTPParser::VP8RTPParser(VP8Decoder* decoder)
+	: decoder(decoder), firstPacket(true)
+{
+}
+
+void VP8RTPParser::newPayloadReceived(const uint8_t* data, size_t len, bool hasMarker)
+{
+	// Payload descriptor
+	uint8_t req = data[0];
+	if (firstPacket && !(req & SBit)) { /* Error */ }
+
+	size_t headerSize;
+	// Payload header
+	if (firstPacket) {
+		firstPacket = false;
+
+		uint8_t o1 = data[1];
+		showFrame = (o1 & 1);
+		isKeyFrame = (o1 & HBit);
+		o1 >>= Size0BitShift;
+		frameSize = o1 + 8 * data[2] + 2048 * data[3];
+
+		headerSize = 4;
+	} else {
+		headerSize = 1;
+	}
+
+	buffer.insert(buffer.end(), data + headerSize, data + len);
+
+	if (hasMarker || buffer.size() >= frameSize) {
+		// Frame received
+		decoder->decodeFrame(buffer);
+		buffer.clear();
+		firstPacket = true;
+	}
+}
+
+}
diff --git a/Swiften/ScreenSharing/VP8RTPParser.h b/Swiften/ScreenSharing/VP8RTPParser.h
new file mode 100644
index 0000000..c88e2a6
--- /dev/null
+++ b/Swiften/ScreenSharing/VP8RTPParser.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+#include <stdint.h>
+#include <stddef.h>
+
+namespace Swift {
+	class VP8Decoder;
+
+	class VP8RTPParser {
+		public:
+			VP8RTPParser(VP8Decoder* decoder);
+
+			void newPayloadReceived(const uint8_t* data, size_t len, bool hasMarker);
+
+		private:
+			static const uint8_t SBit = 1 << 4;
+			static const uint8_t HBit = 1 << 4;
+			static const uint8_t Size0BitShift = 5;
+
+			VP8Decoder* decoder;
+
+			std::vector<uint8_t> buffer;
+			bool firstPacket;
+			size_t frameSize;
+			bool isKeyFrame;
+			bool showFrame;
+	};
+}
diff --git a/Swiften/ScreenSharing/VideoDecoder.h b/Swiften/ScreenSharing/VideoDecoder.h
new file mode 100644
index 0000000..810d5ae
--- /dev/null
+++ b/Swiften/ScreenSharing/VideoDecoder.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/boost_bsignals.h>
+#include <boost/shared_ptr.hpp>
+#include <stdint.h>
+
+namespace Swift {
+	class Image;
+
+	class VideoDecoder {
+		public:
+			VideoDecoder() {}
+			virtual ~VideoDecoder() {}
+
+			virtual void decodeFrame(const std::vector<uint8_t>& frame) = 0;
+
+		public:
+			boost::signal<void (const Image&)> onNewImageDecoded;
+	};
+}
diff --git a/Swiften/ScreenSharing/VideoEncoder.cpp b/Swiften/ScreenSharing/VideoEncoder.cpp
deleted file mode 100644
index 40d9bef..0000000
--- a/Swiften/ScreenSharing/VideoEncoder.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012 Yoann Blein
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include <Swiften/ScreenSharing/VideoEncoder.h>
-
-namespace Swift {
-
-void VideoEncoder::addFrame(VideoFrame::ref frame)
-{
-	boost::mutex::scoped_lock lock(queueMutex);
-	frames.push(frame);
-	lock.unlock();
-	queueCondVar.notify_one();
-}
-
-void VideoEncoder::startEncoding()
-{
-	stop = false;
-	encodingThread = boost::thread(&VideoEncoder::encodingLoop, this);
-}
-
-void VideoEncoder::stopEncoding()
-{
-	stop = true;
-	encodingThread.join();
-}
-
-VideoFrame::ref VideoEncoder::popWhenFrameIsAvailable()
-{
-	boost::mutex::scoped_lock lock(queueMutex);
-	while (frames.empty()) {
-		queueCondVar.wait(lock);
-	}
-	VideoFrame::ref popped = frames.front();
-	frames.pop();
-	return popped;
-}
-
-}
diff --git a/Swiften/ScreenSharing/VideoEncoder.h b/Swiften/ScreenSharing/VideoEncoder.h
index d98b854..718b59f 100644
--- a/Swiften/ScreenSharing/VideoEncoder.h
+++ b/Swiften/ScreenSharing/VideoEncoder.h
@@ -4,41 +4,20 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
-#ifndef VIDEOENCODER_H
-#define VIDEOENCODER_H
+#pragma once
 
-#include <Swiften/ScreenSharing/VideoFrame.h>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition_variable.hpp>
 #include <stdint.h>
-#include <queue>
-
+#include <boost/shared_ptr.hpp>
 
 namespace Swift {
+	class Image;
+	class Packetizer;
+
 	class VideoEncoder {
 		public:
 			VideoEncoder() {}
 			virtual ~VideoEncoder() {}
 
-			void addFrame(VideoFrame::ref frame);
-
-			void startEncoding();
-			void stopEncoding();
-
-		protected:
-			virtual void encodingLoop() = 0;
-			VideoFrame::ref popWhenFrameIsAvailable();
-
-		protected:
-			bool stop;
-
-		private:
-			std::queue<VideoFrame::ref> frames;
-			boost::mutex queueMutex;
-			boost::condition_variable queueCondVar;
-			boost::thread encodingThread;
+			virtual void encodeImage(const Image& frame) = 0;
 	};
 }
-
-#endif // VIDEOENCODER_H
diff --git a/Swiften/ScreenSharing/VideoFrame.cpp b/Swiften/ScreenSharing/VideoFrame.cpp
deleted file mode 100644
index d36ec5c..0000000
--- a/Swiften/ScreenSharing/VideoFrame.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2012 Yoann Blein
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include <Swiften/ScreenSharing/VideoFrame.h>
-
-namespace Swift {
-
-VideoFrame::VideoFrame(int width, int height, uint8_t *rgb24data)
-	: width(width), height(height)
-{
-	int len = width * height;
-	data.insert(data.begin(), rgb24data, rgb24data + len);
-}
-
-}
diff --git a/Swiften/ScreenSharing/VideoFrame.h b/Swiften/ScreenSharing/VideoFrame.h
deleted file mode 100644
index 1d98062..0000000
--- a/Swiften/ScreenSharing/VideoFrame.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2012 Yoann Blein
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#ifndef VIDEOFRAME_H
-#define VIDEOFRAME_H
-
-#pragma once
-
-#include <boost/shared_ptr.hpp>
-#include <vector>
-#include <stdint.h>
-
-namespace Swift {
-	class VideoFrame {
-		public:
-			typedef boost::shared_ptr<VideoFrame> ref;
-
-			VideoFrame(int width, int height, uint8_t *rgb24data);
-
-			int width;
-			int height;
-			std::vector<uint8_t> data;
-	};
-}
-
-#endif // VIDEOFRAME_H
-- 
cgit v0.10.2-6-g49f6