diff options
Diffstat (limited to 'Swiften/ScreenSharing/VP8Encoder.cpp')
-rw-r--r-- | Swiften/ScreenSharing/VP8Encoder.cpp | 86 |
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; |