summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordknn <yoann.blein@free.fr>2012-06-26 14:05:35 (GMT)
committerdknn <yoann.blein@free.fr>2012-09-22 08:53:12 (GMT)
commit39ac2af90938aec4f4e43b81a6e043e0ebcdd798 (patch)
treeadd99f9eb287778191ebde47917adbaa96a39b8a
parentf374887e7a27831771304a09a74d6cd54f8ef4e4 (diff)
downloadswift-contrib-39ac2af90938aec4f4e43b81a6e043e0ebcdd798.zip
swift-contrib-39ac2af90938aec4f4e43b81a6e043e0ebcdd798.tar.bz2
Single threaded codec
-rw-r--r--Swiften/ScreenSharing/Image.cpp22
-rw-r--r--Swiften/ScreenSharing/Image.h (renamed from Swiften/ScreenSharing/VideoFrame.h)11
-rw-r--r--Swiften/ScreenSharing/SConscript6
-rw-r--r--Swiften/ScreenSharing/VP8Decoder.cpp99
-rw-r--r--Swiften/ScreenSharing/VP8Decoder.h34
-rw-r--r--Swiften/ScreenSharing/VP8Encoder.cpp86
-rw-r--r--Swiften/ScreenSharing/VP8Encoder.h24
-rw-r--r--Swiften/ScreenSharing/VP8RTPPacketizer.cpp68
-rw-r--r--Swiften/ScreenSharing/VP8RTPPacketizer.h36
-rw-r--r--Swiften/ScreenSharing/VP8RTPParser.cpp50
-rw-r--r--Swiften/ScreenSharing/VP8RTPParser.h35
-rw-r--r--Swiften/ScreenSharing/VideoDecoder.h26
-rw-r--r--Swiften/ScreenSharing/VideoEncoder.cpp42
-rw-r--r--Swiften/ScreenSharing/VideoEncoder.h33
-rw-r--r--Swiften/ScreenSharing/VideoFrame.cpp18
15 files changed, 435 insertions, 155 deletions
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/VideoFrame.h b/Swiften/ScreenSharing/Image.h
index 1d98062..5cdf043 100644
--- a/Swiften/ScreenSharing/VideoFrame.h
+++ b/Swiften/ScreenSharing/Image.h
@@ -4,9 +4,6 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#ifndef VIDEOFRAME_H
-#define VIDEOFRAME_H
-
#pragma once
#include <boost/shared_ptr.hpp>
@@ -14,16 +11,14 @@
#include <stdint.h>
namespace Swift {
- class VideoFrame {
+ class Image {
public:
- typedef boost::shared_ptr<VideoFrame> ref;
+ typedef boost::shared_ptr<Image> ref;
- VideoFrame(int width, int height, uint8_t *rgb24data);
+ Image(int width, int height, uint8_t* rgb24data = 0);
int width;
int height;
std::vector<uint8_t> data;
};
}
-
-#endif // VIDEOFRAME_H
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);
-}
-
-}