summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/ScreenSharing/VP8Encoder.cpp')
-rw-r--r--Swiften/ScreenSharing/VP8Encoder.cpp86
1 files changed, 44 insertions, 42 deletions
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;