mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 12:15:34 +08:00
[fix] fix all unused variables and type conversions
This commit is contained in:
@@ -12,7 +12,7 @@ VideoFrame::VideoFrame(size_t size) {
|
||||
height_ = 0;
|
||||
}
|
||||
|
||||
VideoFrame::VideoFrame(size_t size, size_t width, size_t height) {
|
||||
VideoFrame::VideoFrame(size_t size, uint32_t width, uint32_t height) {
|
||||
buffer_ = new uint8_t[size];
|
||||
size_ = size;
|
||||
width_ = width;
|
||||
@@ -27,8 +27,8 @@ VideoFrame::VideoFrame(const uint8_t *buffer, size_t size) {
|
||||
height_ = 0;
|
||||
}
|
||||
|
||||
VideoFrame::VideoFrame(const uint8_t *buffer, size_t size, size_t width,
|
||||
size_t height) {
|
||||
VideoFrame::VideoFrame(const uint8_t *buffer, size_t size, uint32_t width,
|
||||
uint32_t height) {
|
||||
buffer_ = new uint8_t[size];
|
||||
memcpy(buffer_, buffer, size);
|
||||
size_ = size;
|
||||
|
||||
@@ -14,9 +14,10 @@ class VideoFrame {
|
||||
public:
|
||||
VideoFrame();
|
||||
VideoFrame(size_t size);
|
||||
VideoFrame(size_t size, size_t width, size_t height);
|
||||
VideoFrame(size_t size, uint32_t width, uint32_t height);
|
||||
VideoFrame(const uint8_t *buffer, size_t size);
|
||||
VideoFrame(const uint8_t *buffer, size_t size, size_t width, size_t height);
|
||||
VideoFrame(const uint8_t *buffer, size_t size, uint32_t width,
|
||||
uint32_t height);
|
||||
VideoFrame(const VideoFrame &video_frame);
|
||||
VideoFrame(VideoFrame &&video_frame);
|
||||
VideoFrame &operator=(const VideoFrame &video_frame);
|
||||
@@ -27,18 +28,18 @@ class VideoFrame {
|
||||
public:
|
||||
const uint8_t *Buffer() { return buffer_; }
|
||||
size_t Size() { return size_; }
|
||||
size_t Width() { return width_; }
|
||||
size_t Height() { return height_; }
|
||||
uint32_t Width() { return width_; }
|
||||
uint32_t Height() { return height_; }
|
||||
|
||||
void SetSize(size_t size) { size_ = size; }
|
||||
void SetWidth(size_t width) { width_ = width; }
|
||||
void SetHeight(size_t height) { height_ = height; }
|
||||
void SetWidth(uint32_t width) { width_ = width; }
|
||||
void SetHeight(uint32_t height) { height_ = height; }
|
||||
|
||||
private:
|
||||
uint8_t *buffer_ = nullptr;
|
||||
size_t size_ = 0;
|
||||
size_t width_ = 0;
|
||||
size_t height_ = 0;
|
||||
uint32_t width_ = 0;
|
||||
uint32_t height_ = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -190,11 +190,10 @@ int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cb_closed(GObject *src, GAsyncResult *res, gpointer data) {
|
||||
NiceAgent *agent = NICE_AGENT(src);
|
||||
g_debug("test-turn:%s: %p", G_STRFUNC, agent);
|
||||
|
||||
*((gboolean *)data) = TRUE;
|
||||
void cb_closed(GObject *src, [[maybe_unused]] GAsyncResult *res,
|
||||
[[maybe_unused]] gpointer data) {
|
||||
[[maybe_unused]] NiceAgent *agent = NICE_AGENT(src);
|
||||
LOG_INFO("Nice agent closed");
|
||||
}
|
||||
|
||||
int IceAgent::DestroyIceAgent() {
|
||||
@@ -384,11 +383,11 @@ int IceAgent::Send(const char *data, size_t size) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
int ret = nice_agent_send(agent_, stream_id_, 1, size, data);
|
||||
bool ret = nice_agent_send(agent_, stream_id_, 1, (guint)size, data);
|
||||
|
||||
#ifdef SAVE_IO_STREAM
|
||||
fwrite(data, 1, size, file_out_);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return ret ? 0 : -1;
|
||||
}
|
||||
@@ -6,12 +6,20 @@ std::shared_ptr<spdlog::logger> get_logger() {
|
||||
}
|
||||
|
||||
auto now = std::chrono::system_clock::now() + std::chrono::hours(8);
|
||||
auto timet = std::chrono::system_clock::to_time_t(now);
|
||||
auto localTime = *std::gmtime(&timet);
|
||||
auto now_time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
std::tm tm_info;
|
||||
|
||||
#ifdef _WIN32
|
||||
gmtime_s(&tm_info, &now_time);
|
||||
#else
|
||||
std::gmtime_r(&now_time, &tm_info);
|
||||
#endif
|
||||
|
||||
std::stringstream ss;
|
||||
std::string filename;
|
||||
ss << LOGGER_NAME;
|
||||
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log");
|
||||
ss << std::put_time(&tm_info, "-%Y%m%d-%H%M%S.log");
|
||||
ss >> filename;
|
||||
|
||||
std::string path = "logs/" + filename;
|
||||
|
||||
@@ -36,11 +36,11 @@ int AudioDecoder::Init() {
|
||||
}
|
||||
|
||||
int AudioDecoder::Decode(
|
||||
const uint8_t* data, int size,
|
||||
const uint8_t* data, size_t size,
|
||||
std::function<void(uint8_t*, int)> on_receive_decoded_frame) {
|
||||
// LOG_ERROR("input opus size = {}", size);
|
||||
auto frame_size =
|
||||
opus_decode(opus_decoder_, data, size, out_data, MAX_FRAME_SIZE, 0);
|
||||
auto frame_size = opus_decode(opus_decoder_, data, (opus_int32)size, out_data,
|
||||
MAX_FRAME_SIZE, 0);
|
||||
|
||||
if (frame_size < 0) {
|
||||
LOG_ERROR("Decode opus frame failed");
|
||||
|
||||
@@ -26,7 +26,7 @@ class AudioDecoder {
|
||||
public:
|
||||
int Init();
|
||||
|
||||
int Decode(const uint8_t *data, int size,
|
||||
int Decode(const uint8_t *data, size_t size,
|
||||
std::function<void(uint8_t *, int)> on_receive_decoded_frame);
|
||||
|
||||
std::string GetDecoderName() { return "Opus"; }
|
||||
|
||||
@@ -52,7 +52,7 @@ int AudioEncoder::Init() {
|
||||
}
|
||||
|
||||
int AudioEncoder::Encode(
|
||||
const uint8_t *data, int size,
|
||||
const uint8_t *data, size_t size,
|
||||
std::function<int(char *encoded_audio_buffer, size_t size)>
|
||||
on_encoded_audio_buffer) {
|
||||
if (!on_encoded_audio_buffer_) {
|
||||
@@ -67,7 +67,7 @@ int AudioEncoder::Encode(
|
||||
// printf("1 Time cost: %d size: %d\n", now_ts - last_ts, size);
|
||||
// last_ts = now_ts;
|
||||
|
||||
auto ret = opus_encode(opus_encoder_, (opus_int16 *)data, size, out_data,
|
||||
auto ret = opus_encode(opus_encoder_, (opus_int16 *)data, (int)size, out_data,
|
||||
MAX_PACKET_SIZE);
|
||||
if (ret < 0) {
|
||||
printf("opus decode failed, %d\n", ret);
|
||||
@@ -76,15 +76,7 @@ int AudioEncoder::Encode(
|
||||
|
||||
if (on_encoded_audio_buffer_) {
|
||||
on_encoded_audio_buffer_((char *)out_data, ret);
|
||||
} else {
|
||||
OnEncodedAudioBuffer((char *)out_data, ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AudioEncoder::OnEncodedAudioBuffer(char *encoded_audio_buffer,
|
||||
size_t size) {
|
||||
LOG_INFO("OnEncodedAudioBuffer not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,12 +23,10 @@ class AudioEncoder {
|
||||
public:
|
||||
int Init();
|
||||
|
||||
int Encode(const uint8_t* data, int size,
|
||||
int Encode(const uint8_t* data, size_t size,
|
||||
std::function<int(char* encoded_audio_buffer, size_t size)>
|
||||
on_encoded_audio_buffer);
|
||||
|
||||
int OnEncodedAudioBuffer(char* encoded_audio_buffer, size_t size);
|
||||
|
||||
std::string GetEncoderName() { return "Opus"; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -27,69 +27,64 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
#include <time.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock.h>
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#undef ERROR
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SOCKET int
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
enum LogLevel {
|
||||
TRACE,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR,
|
||||
FATAL
|
||||
};
|
||||
enum LogLevel { TRACE, INFO, WARNING, ERROR, FATAL };
|
||||
|
||||
namespace simplelogger{
|
||||
namespace simplelogger {
|
||||
class Logger {
|
||||
public:
|
||||
Logger(LogLevel level, bool bPrintTimeStamp) : level(level), bPrintTimeStamp(bPrintTimeStamp) {}
|
||||
public:
|
||||
Logger(LogLevel level, bool bPrintTimeStamp)
|
||||
: level(level), bPrintTimeStamp(bPrintTimeStamp) {}
|
||||
virtual ~Logger() {}
|
||||
virtual std::ostream& GetStream() = 0;
|
||||
virtual std::ostream &GetStream() = 0;
|
||||
virtual void FlushStream() {}
|
||||
bool ShouldLogFor(LogLevel l) {
|
||||
return l >= level;
|
||||
}
|
||||
char* GetLead(LogLevel l, const char *szFile, int nLine, const char *szFunc) {
|
||||
bool ShouldLogFor(LogLevel l) { return l >= level; }
|
||||
char *GetLead(LogLevel l, [[maybe_unused]] const char *szFile,
|
||||
[[maybe_unused]] int nLine,
|
||||
[[maybe_unused]] const char *szFunc) {
|
||||
if (l < TRACE || l > FATAL) {
|
||||
sprintf(szLead, "[?????] ");
|
||||
return szLead;
|
||||
}
|
||||
|
||||
const char *szLevels[] = {"TRACE", "INFO", "WARN", "ERROR", "FATAL"};
|
||||
if (bPrintTimeStamp) {
|
||||
time_t t = time(NULL);
|
||||
struct tm *ptm = localtime(&t);
|
||||
sprintf(szLead, "[%-5s][%02d:%02d:%02d] ",
|
||||
szLevels[l], ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
|
||||
sprintf(szLead, "[%-5s][%02d:%02d:%02d] ", szLevels[l], ptm->tm_hour,
|
||||
ptm->tm_min, ptm->tm_sec);
|
||||
} else {
|
||||
sprintf(szLead, "[%-5s] ", szLevels[l]);
|
||||
}
|
||||
return szLead;
|
||||
}
|
||||
void EnterCriticalSection() {
|
||||
mtx.lock();
|
||||
}
|
||||
void LeaveCriticalSection() {
|
||||
mtx.unlock();
|
||||
}
|
||||
private:
|
||||
void EnterCriticalSection() { mtx.lock(); }
|
||||
void LeaveCriticalSection() { mtx.unlock(); }
|
||||
|
||||
private:
|
||||
LogLevel level;
|
||||
char szLead[80];
|
||||
bool bPrintTimeStamp;
|
||||
@@ -97,20 +92,23 @@ private:
|
||||
};
|
||||
|
||||
class LoggerFactory {
|
||||
public:
|
||||
static Logger* CreateFileLogger(std::string strFilePath,
|
||||
LogLevel level = INFO, bool bPrintTimeStamp = true) {
|
||||
public:
|
||||
static Logger *CreateFileLogger(std::string strFilePath,
|
||||
LogLevel level = INFO,
|
||||
bool bPrintTimeStamp = true) {
|
||||
return new FileLogger(strFilePath, level, bPrintTimeStamp);
|
||||
}
|
||||
static Logger* CreateConsoleLogger(LogLevel level = INFO,
|
||||
static Logger *CreateConsoleLogger(LogLevel level = INFO,
|
||||
bool bPrintTimeStamp = true) {
|
||||
return new ConsoleLogger(level, bPrintTimeStamp);
|
||||
}
|
||||
static Logger* CreateUdpLogger(char *szHost, unsigned uPort, LogLevel level = INFO,
|
||||
static Logger *CreateUdpLogger(char *szHost, unsigned uPort,
|
||||
LogLevel level = INFO,
|
||||
bool bPrintTimeStamp = true) {
|
||||
return new UdpLogger(szHost, uPort, level, bPrintTimeStamp);
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
LoggerFactory() {}
|
||||
|
||||
class FileLogger : public Logger {
|
||||
@@ -120,12 +118,9 @@ private:
|
||||
pFileOut = new std::ofstream();
|
||||
pFileOut->open(strFilePath.c_str());
|
||||
}
|
||||
~FileLogger() {
|
||||
pFileOut->close();
|
||||
}
|
||||
std::ostream& GetStream() {
|
||||
return *pFileOut;
|
||||
}
|
||||
~FileLogger() { pFileOut->close(); }
|
||||
std::ostream &GetStream() { return *pFileOut; }
|
||||
|
||||
private:
|
||||
std::ofstream *pFileOut;
|
||||
};
|
||||
@@ -134,16 +129,15 @@ private:
|
||||
public:
|
||||
ConsoleLogger(LogLevel level, bool bPrintTimeStamp)
|
||||
: Logger(level, bPrintTimeStamp) {}
|
||||
std::ostream& GetStream() {
|
||||
return std::cout;
|
||||
}
|
||||
std::ostream &GetStream() { return std::cout; }
|
||||
};
|
||||
|
||||
class UdpLogger : public Logger {
|
||||
private:
|
||||
class UdpOstream : public std::ostream {
|
||||
public:
|
||||
UdpOstream(char *szHost, unsigned short uPort) : std::ostream(&sb), socket(INVALID_SOCKET){
|
||||
UdpOstream(char *szHost, unsigned short uPort)
|
||||
: std::ostream(&sb), socket(INVALID_SOCKET) {
|
||||
#ifdef _WIN32
|
||||
WSADATA w;
|
||||
if (WSAStartup(0x0101, &w) != 0) {
|
||||
@@ -162,7 +156,8 @@ private:
|
||||
#ifdef _WIN32
|
||||
unsigned int b1, b2, b3, b4;
|
||||
sscanf(szHost, "%u.%u.%u.%u", &b1, &b2, &b3, &b4);
|
||||
struct in_addr addr = {(unsigned char)b1, (unsigned char)b2, (unsigned char)b3, (unsigned char)b4};
|
||||
struct in_addr addr = {(unsigned char)b1, (unsigned char)b2,
|
||||
(unsigned char)b3, (unsigned char)b4};
|
||||
#else
|
||||
struct in_addr addr = {inet_addr(szHost)};
|
||||
#endif
|
||||
@@ -181,8 +176,9 @@ private:
|
||||
#endif
|
||||
}
|
||||
void Flush() {
|
||||
if (sendto(socket, sb.str().c_str(), (int)sb.str().length() + 1,
|
||||
0, (struct sockaddr *)&server, (int)sizeof(sockaddr_in)) == -1) {
|
||||
if (sendto(socket, sb.str().c_str(), (int)sb.str().length() + 1, 0,
|
||||
(struct sockaddr *)&server,
|
||||
(int)sizeof(sockaddr_in)) == -1) {
|
||||
fprintf(stderr, "sendto() failed.\n");
|
||||
}
|
||||
sb.str("");
|
||||
@@ -193,23 +189,25 @@ private:
|
||||
SOCKET socket;
|
||||
struct sockaddr_in server;
|
||||
};
|
||||
|
||||
public:
|
||||
UdpLogger(char *szHost, unsigned uPort, LogLevel level, bool bPrintTimeStamp)
|
||||
: Logger(level, bPrintTimeStamp), udpOut(szHost, (unsigned short)uPort) {}
|
||||
UdpOstream& GetStream() {
|
||||
return udpOut;
|
||||
}
|
||||
virtual void FlushStream() {
|
||||
udpOut.Flush();
|
||||
}
|
||||
UdpLogger(char *szHost, unsigned uPort, LogLevel level,
|
||||
bool bPrintTimeStamp)
|
||||
: Logger(level, bPrintTimeStamp),
|
||||
udpOut(szHost, (unsigned short)uPort) {}
|
||||
UdpOstream &GetStream() { return udpOut; }
|
||||
virtual void FlushStream() { udpOut.Flush(); }
|
||||
|
||||
private:
|
||||
UdpOstream udpOut;
|
||||
};
|
||||
};
|
||||
|
||||
class LogTransaction {
|
||||
public:
|
||||
LogTransaction(Logger *pLogger, LogLevel level, const char *szFile, const int nLine, const char *szFunc) : pLogger(pLogger), level(level) {
|
||||
public:
|
||||
LogTransaction(Logger *pLogger, LogLevel level, const char *szFile,
|
||||
const int nLine, const char *szFunc)
|
||||
: pLogger(pLogger), level(level) {
|
||||
if (!pLogger) {
|
||||
std::cout << "[-----] ";
|
||||
return;
|
||||
@@ -235,7 +233,7 @@ public:
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
std::ostream& GetStream() {
|
||||
std::ostream &GetStream() {
|
||||
if (!pLogger) {
|
||||
return std::cout;
|
||||
}
|
||||
@@ -244,13 +242,17 @@ public:
|
||||
}
|
||||
return pLogger->GetStream();
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
Logger *pLogger;
|
||||
LogLevel level;
|
||||
std::ostringstream ossNull;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace simplelogger
|
||||
|
||||
extern simplelogger::Logger *logger;
|
||||
#define LOG(level) simplelogger::LogTransaction(logger, level, __FILE__, __LINE__, __FUNCTION__).GetStream()
|
||||
#define LOG(level) \
|
||||
simplelogger::LogTransaction(logger, level, __FILE__, __LINE__, \
|
||||
__FUNCTION__) \
|
||||
.GetStream()
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4244)
|
||||
|
||||
#include "NvDecoder.h"
|
||||
|
||||
@@ -222,7 +224,7 @@ int NvDecoder::HandleVideoSequence(CUVIDEOFORMAT *pVideoFormat) {
|
||||
if (!decodecaps.bIsSupported) {
|
||||
NVDEC_THROW_ERROR("Codec not supported on this GPU",
|
||||
CUDA_ERROR_NOT_SUPPORTED);
|
||||
return nDecodeSurface;
|
||||
// return nDecodeSurface;
|
||||
}
|
||||
|
||||
if ((pVideoFormat->coded_width > decodecaps.nMaxWidth) ||
|
||||
@@ -237,7 +239,7 @@ int NvDecoder::HandleVideoSequence(CUVIDEOFORMAT *pVideoFormat) {
|
||||
|
||||
const std::string cErr = errorString.str();
|
||||
NVDEC_THROW_ERROR(cErr, CUDA_ERROR_NOT_SUPPORTED);
|
||||
return nDecodeSurface;
|
||||
// return nDecodeSurface;
|
||||
}
|
||||
|
||||
if ((pVideoFormat->coded_width >> 4) * (pVideoFormat->coded_height >> 4) >
|
||||
@@ -254,7 +256,7 @@ int NvDecoder::HandleVideoSequence(CUVIDEOFORMAT *pVideoFormat) {
|
||||
|
||||
const std::string cErr = errorString.str();
|
||||
NVDEC_THROW_ERROR(cErr, CUDA_ERROR_NOT_SUPPORTED);
|
||||
return nDecodeSurface;
|
||||
// return nDecodeSurface;
|
||||
}
|
||||
|
||||
if (m_nWidth && m_nLumaHeight && m_nChromaHeight) {
|
||||
@@ -571,7 +573,7 @@ int NvDecoder::setReconfigParams(const Rect *pCropRect, const Dim *pResizeDim) {
|
||||
int NvDecoder::HandlePictureDecode(CUVIDPICPARAMS *pPicParams) {
|
||||
if (!m_hDecoder) {
|
||||
NVDEC_THROW_ERROR("Decoder not initialized.", CUDA_ERROR_NOT_INITIALIZED);
|
||||
return false;
|
||||
// return false;
|
||||
}
|
||||
m_nPicNumInDecodeOrder[pPicParams->CurrPicIdx] = m_nDecodePicCnt++;
|
||||
CUDA_DRVAPI_CALL(cuCtxPushCurrent(m_cuContext));
|
||||
@@ -921,3 +923,4 @@ void NvDecoder::UnlockFrame(uint8_t **pFrame) {
|
||||
uint64_t timestamp[2] = {0};
|
||||
m_vTimestamp.insert(m_vTimestamp.end(), ×tamp[0], ×tamp[1]);
|
||||
}
|
||||
#pragma warning(pop)
|
||||
@@ -769,12 +769,11 @@ uint32_t NvEncoder::GetWidthInBytes(const NV_ENC_BUFFER_FORMAT bufferFormat,
|
||||
return width * 4;
|
||||
default:
|
||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
||||
return 0;
|
||||
// return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NvEncoder::GetNumChromaPlanes(
|
||||
const NV_ENC_BUFFER_FORMAT bufferFormat) {
|
||||
int32_t NvEncoder::GetNumChromaPlanes(const NV_ENC_BUFFER_FORMAT bufferFormat) {
|
||||
switch (bufferFormat) {
|
||||
case NV_ENC_BUFFER_FORMAT_NV12:
|
||||
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
|
||||
@@ -792,11 +791,11 @@ uint32_t NvEncoder::GetNumChromaPlanes(
|
||||
return 0;
|
||||
default:
|
||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
||||
return -1;
|
||||
// return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NvEncoder::GetChromaPitch(const NV_ENC_BUFFER_FORMAT bufferFormat,
|
||||
int32_t NvEncoder::GetChromaPitch(const NV_ENC_BUFFER_FORMAT bufferFormat,
|
||||
const uint32_t lumaPitch) {
|
||||
switch (bufferFormat) {
|
||||
case NV_ENC_BUFFER_FORMAT_NV12:
|
||||
@@ -815,7 +814,7 @@ uint32_t NvEncoder::GetChromaPitch(const NV_ENC_BUFFER_FORMAT bufferFormat,
|
||||
return 0;
|
||||
default:
|
||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
||||
return -1;
|
||||
// return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,7 +870,7 @@ uint32_t NvEncoder::GetChromaHeight(const NV_ENC_BUFFER_FORMAT bufferFormat,
|
||||
return 0;
|
||||
default:
|
||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
||||
return 0;
|
||||
// return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,7 +896,7 @@ uint32_t NvEncoder::GetChromaWidthInBytes(
|
||||
return 0;
|
||||
default:
|
||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
||||
return 0;
|
||||
// return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,7 +933,7 @@ int NvEncoder::GetFrameSize() const {
|
||||
return 4 * GetEncodeWidth() * GetEncodeHeight();
|
||||
default:
|
||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
||||
return 0;
|
||||
// return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -317,14 +317,14 @@ class NvEncoder {
|
||||
* @brief This a static function to get the chroma plane pitch for YUV planar
|
||||
* formats.
|
||||
*/
|
||||
static uint32_t GetChromaPitch(const NV_ENC_BUFFER_FORMAT bufferFormat,
|
||||
static int32_t GetChromaPitch(const NV_ENC_BUFFER_FORMAT bufferFormat,
|
||||
const uint32_t lumaPitch);
|
||||
|
||||
/**
|
||||
* @brief This a static function to get the number of chroma planes for YUV
|
||||
* planar formats.
|
||||
*/
|
||||
static uint32_t GetNumChromaPlanes(const NV_ENC_BUFFER_FORMAT bufferFormat);
|
||||
static int32_t GetNumChromaPlanes(const NV_ENC_BUFFER_FORMAT bufferFormat);
|
||||
|
||||
/**
|
||||
* @brief This a static function to get the chroma plane width in bytes for
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,23 +2,27 @@
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define SAVE_RECEIVED_AV1_STREAM 0
|
||||
#define SAVE_DECODED_NV12_STREAM 0
|
||||
// #define SAVE_DECODED_NV12_STREAM
|
||||
// #define SAVE_RECEIVED_AV1_STREAM
|
||||
|
||||
AomAv1Decoder::AomAv1Decoder() {}
|
||||
|
||||
AomAv1Decoder::~AomAv1Decoder() {
|
||||
if (SAVE_RECEIVED_AV1_STREAM && file_av1_) {
|
||||
fflush(file_av1_);
|
||||
fclose(file_av1_);
|
||||
file_av1_ = nullptr;
|
||||
}
|
||||
|
||||
if (SAVE_DECODED_NV12_STREAM && file_nv12_) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
if (file_nv12_) {
|
||||
fflush(file_nv12_);
|
||||
fclose(file_nv12_);
|
||||
file_nv12_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SAVE_RECEIVED_AV1_STREAM
|
||||
if (file_av1_) {
|
||||
fflush(file_av1_);
|
||||
fclose(file_av1_);
|
||||
file_av1_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nv12_frame_) {
|
||||
delete nv12_frame_;
|
||||
@@ -43,29 +47,29 @@ int AomAv1Decoder::Init() {
|
||||
aom_codec_control(&aom_av1_decoder_ctx_, AV1D_GET_IMG_FORMAT,
|
||||
AOM_IMG_FMT_NV12);
|
||||
|
||||
if (SAVE_RECEIVED_AV1_STREAM) {
|
||||
file_av1_ = fopen("received_av1_stream.ivf", "w+b");
|
||||
if (!file_av1_) {
|
||||
LOG_WARN("Fail to open received_av1_stream.ivf");
|
||||
}
|
||||
}
|
||||
|
||||
if (SAVE_DECODED_NV12_STREAM) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
||||
if (!file_nv12_) {
|
||||
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SAVE_RECEIVED_AV1_STREAM
|
||||
file_av1_ = fopen("received_av1_stream.ivf", "w+b");
|
||||
if (!file_av1_) {
|
||||
LOG_WARN("Fail to open received_av1_stream.ivf");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AomAv1Decoder::Decode(
|
||||
const uint8_t *data, int size,
|
||||
const uint8_t *data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
||||
if (SAVE_RECEIVED_AV1_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_AV1_STREAM
|
||||
fwrite((unsigned char *)data, 1, size, file_av1_);
|
||||
}
|
||||
#endif
|
||||
|
||||
aom_codec_iter_t iter = nullptr;
|
||||
aom_codec_err_t ret =
|
||||
@@ -105,7 +109,7 @@ int AomAv1Decoder::Decode(
|
||||
}
|
||||
}
|
||||
int corrupted = 0;
|
||||
int ret = aom_codec_control(&aom_av1_decoder_ctx_, AOMD_GET_FRAME_CORRUPTED,
|
||||
ret = aom_codec_control(&aom_av1_decoder_ctx_, AOMD_GET_FRAME_CORRUPTED,
|
||||
&corrupted);
|
||||
if (ret != AOM_CODEC_OK) {
|
||||
LOG_ERROR("Failed to get frame corrupted");
|
||||
@@ -140,10 +144,10 @@ int AomAv1Decoder::Decode(
|
||||
|
||||
on_receive_decoded_frame(*nv12_frame_);
|
||||
|
||||
if (SAVE_DECODED_NV12_STREAM) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
fwrite((unsigned char *)nv12_frame_->Buffer(), 1, nv12_frame_->Size(),
|
||||
file_nv12_);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class AomAv1Decoder : public VideoDecoder {
|
||||
public:
|
||||
int Init();
|
||||
|
||||
int Decode(const uint8_t *data, int size,
|
||||
int Decode(const uint8_t *data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame);
|
||||
|
||||
std::string GetDecoderName() { return "AomAv1"; }
|
||||
@@ -32,8 +32,8 @@ class AomAv1Decoder : public VideoDecoder {
|
||||
int nv12_frame_capacity_ = 0;
|
||||
int nv12_frame_size_ = 0;
|
||||
|
||||
int frame_width_ = 0;
|
||||
int frame_height_ = 0;
|
||||
uint32_t frame_width_ = 0;
|
||||
uint32_t frame_height_ = 0;
|
||||
|
||||
FILE *file_av1_ = nullptr;
|
||||
FILE *file_nv12_ = nullptr;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define SAVE_RECEIVED_AV1_STREAM 0
|
||||
#define SAVE_DECODED_NV12_STREAM 0
|
||||
// #define SAVE_DECODED_NV12_STREAM
|
||||
// #define SAVE_RECEIVED_AV1_STREAM
|
||||
|
||||
#include "libyuv.h"
|
||||
|
||||
@@ -28,7 +28,8 @@ class ScopedDav1dData {
|
||||
};
|
||||
|
||||
// Calling `dav1d_data_wrap` requires a `free_callback` to be registered.
|
||||
void NullFreeCallback(const uint8_t *buffer, void *opaque) {}
|
||||
void NullFreeCallback([[maybe_unused]] const uint8_t *buffer,
|
||||
[[maybe_unused]] void *opaque) {}
|
||||
|
||||
void Yuv420pToNv12(unsigned char *SrcY, unsigned char *SrcU,
|
||||
unsigned char *SrcV, int y_stride, int uv_stride,
|
||||
@@ -49,17 +50,21 @@ void Yuv420pToNv12(unsigned char *SrcY, unsigned char *SrcU,
|
||||
Dav1dAv1Decoder::Dav1dAv1Decoder() {}
|
||||
|
||||
Dav1dAv1Decoder::~Dav1dAv1Decoder() {
|
||||
if (SAVE_RECEIVED_AV1_STREAM && file_av1_) {
|
||||
fflush(file_av1_);
|
||||
fclose(file_av1_);
|
||||
file_av1_ = nullptr;
|
||||
}
|
||||
|
||||
if (SAVE_DECODED_NV12_STREAM && file_nv12_) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
if (file_nv12_) {
|
||||
fflush(file_nv12_);
|
||||
fclose(file_nv12_);
|
||||
file_nv12_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SAVE_RECEIVED_AV1_STREAM
|
||||
if (file_av1_) {
|
||||
fflush(file_av1_);
|
||||
fclose(file_av1_);
|
||||
file_av1_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nv12_frame_) {
|
||||
delete nv12_frame_;
|
||||
@@ -83,29 +88,29 @@ int Dav1dAv1Decoder::Init() {
|
||||
LOG_ERROR("Dav1d AV1 decoder open failed");
|
||||
}
|
||||
|
||||
if (SAVE_RECEIVED_AV1_STREAM) {
|
||||
file_av1_ = fopen("received_av1_stream.ivf", "w+b");
|
||||
if (!file_av1_) {
|
||||
LOG_WARN("Fail to open received_av1_stream.ivf");
|
||||
}
|
||||
}
|
||||
|
||||
if (SAVE_DECODED_NV12_STREAM) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
||||
if (!file_nv12_) {
|
||||
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SAVE_RECEIVED_AV1_STREAM
|
||||
file_av1_ = fopen("received_av1_stream.ivf", "w+b");
|
||||
if (!file_av1_) {
|
||||
LOG_WARN("Fail to open received_av1_stream.ivf");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Dav1dAv1Decoder::Decode(
|
||||
const uint8_t *data, int size,
|
||||
const uint8_t *data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
||||
if (SAVE_RECEIVED_AV1_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_AV1_STREAM
|
||||
fwrite((unsigned char *)data, 1, size, file_av1_);
|
||||
}
|
||||
#endif
|
||||
|
||||
ScopedDav1dData scoped_dav1d_data;
|
||||
Dav1dData &dav1d_data = scoped_dav1d_data.Data();
|
||||
@@ -176,14 +181,14 @@ int Dav1dAv1Decoder::Decode(
|
||||
Yuv420pToNv12((unsigned char *)dav1d_picture.data[0],
|
||||
(unsigned char *)dav1d_picture.data[1],
|
||||
(unsigned char *)dav1d_picture.data[2],
|
||||
dav1d_picture.stride[0], dav1d_picture.stride[1],
|
||||
(int)dav1d_picture.stride[0], (int)dav1d_picture.stride[1],
|
||||
(unsigned char *)nv12_frame_->Buffer(), frame_width_,
|
||||
frame_height_);
|
||||
} else {
|
||||
libyuv::I420ToNV12(
|
||||
(const uint8_t *)dav1d_picture.data[0], dav1d_picture.stride[0],
|
||||
(const uint8_t *)dav1d_picture.data[1], dav1d_picture.stride[1],
|
||||
(const uint8_t *)dav1d_picture.data[2], dav1d_picture.stride[1],
|
||||
(const uint8_t *)dav1d_picture.data[0], (int)dav1d_picture.stride[0],
|
||||
(const uint8_t *)dav1d_picture.data[1], (int)dav1d_picture.stride[1],
|
||||
(const uint8_t *)dav1d_picture.data[2], (int)dav1d_picture.stride[1],
|
||||
(uint8_t *)nv12_frame_->Buffer(), frame_width_,
|
||||
(uint8_t *)nv12_frame_->Buffer() + frame_width_ * frame_height_,
|
||||
frame_width_, frame_width_, frame_height_);
|
||||
@@ -191,10 +196,10 @@ int Dav1dAv1Decoder::Decode(
|
||||
|
||||
on_receive_decoded_frame(*nv12_frame_);
|
||||
|
||||
if (SAVE_DECODED_NV12_STREAM) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
fwrite((unsigned char *)nv12_frame_->Buffer(), 1, nv12_frame_->Size(),
|
||||
file_nv12_);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -20,18 +20,18 @@ class Dav1dAv1Decoder : public VideoDecoder {
|
||||
public:
|
||||
int Init();
|
||||
|
||||
int Decode(const uint8_t *data, int size,
|
||||
int Decode(const uint8_t *data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame);
|
||||
|
||||
std::string GetDecoderName() { return "Dav1dAv1"; }
|
||||
|
||||
private:
|
||||
VideoFrame *nv12_frame_ = 0;
|
||||
int nv12_frame_capacity_ = 0;
|
||||
int nv12_frame_size_ = 0;
|
||||
size_t nv12_frame_capacity_ = 0;
|
||||
size_t nv12_frame_size_ = 0;
|
||||
|
||||
int frame_width_ = 0;
|
||||
int frame_height_ = 0;
|
||||
uint32_t frame_width_ = 0;
|
||||
uint32_t frame_height_ = 0;
|
||||
|
||||
FILE *file_av1_ = nullptr;
|
||||
FILE *file_nv12_ = nullptr;
|
||||
|
||||
@@ -3,22 +3,26 @@
|
||||
#include "log.h"
|
||||
#include "nvcodec_api.h"
|
||||
|
||||
#define SAVE_RECEIVED_H264_STREAM 0
|
||||
#define SAVE_DECODED_NV12_STREAM 0
|
||||
// #define SAVE_DECODED_NV12_STREAM
|
||||
// #define SAVE_RECEIVED_H264_STREAM
|
||||
|
||||
NvidiaVideoDecoder::NvidiaVideoDecoder() {}
|
||||
NvidiaVideoDecoder::~NvidiaVideoDecoder() {
|
||||
if (SAVE_RECEIVED_H264_STREAM && file_h264_) {
|
||||
fflush(file_h264_);
|
||||
fclose(file_h264_);
|
||||
file_h264_ = nullptr;
|
||||
}
|
||||
|
||||
if (SAVE_DECODED_NV12_STREAM && file_nv12_) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
if (file_nv12_) {
|
||||
fflush(file_nv12_);
|
||||
fclose(file_nv12_);
|
||||
file_nv12_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||
if (file_h264_) {
|
||||
fflush(file_h264_);
|
||||
fclose(file_h264_);
|
||||
file_h264_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int NvidiaVideoDecoder::Init() {
|
||||
@@ -42,55 +46,55 @@ int NvidiaVideoDecoder::Init() {
|
||||
|
||||
decoder = new NvDecoder(cuContext, false, cudaVideoCodec_H264, true);
|
||||
|
||||
if (SAVE_RECEIVED_H264_STREAM) {
|
||||
file_h264_ = fopen("received_h264_stream.h264", "w+b");
|
||||
if (!file_h264_) {
|
||||
LOG_WARN("Fail to open received_h264_stream.h264");
|
||||
}
|
||||
}
|
||||
|
||||
if (SAVE_DECODED_NV12_STREAM) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
||||
if (!file_nv12_) {
|
||||
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||
file_h264_ = fopen("received_h264_stream.h264", "w+b");
|
||||
if (!file_h264_) {
|
||||
LOG_WARN("Fail to open received_h264_stream.h264");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NvidiaVideoDecoder::Decode(
|
||||
const uint8_t *data, int size,
|
||||
const uint8_t *data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
||||
if (!decoder) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SAVE_RECEIVED_H264_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||
fwrite((unsigned char *)data, 1, size, file_h264_);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((*(data + 4) & 0x1f) == 0x07) {
|
||||
// LOG_WARN("Receive key frame");
|
||||
}
|
||||
|
||||
int num_frame_returned = decoder->Decode(data, size);
|
||||
|
||||
int num_frame_returned = decoder->Decode(data, (int)size);
|
||||
for (size_t i = 0; i < num_frame_returned; ++i) {
|
||||
cudaVideoSurfaceFormat format = decoder->GetOutputFormat();
|
||||
if (format == cudaVideoSurfaceFormat_NV12) {
|
||||
uint8_t *data = nullptr;
|
||||
data = decoder->GetFrame();
|
||||
if (data) {
|
||||
uint8_t *decoded_frame_buffer = nullptr;
|
||||
decoded_frame_buffer = decoder->GetFrame();
|
||||
if (decoded_frame_buffer) {
|
||||
if (on_receive_decoded_frame) {
|
||||
VideoFrame decoded_frame(
|
||||
data, decoder->GetWidth() * decoder->GetHeight() * 3 / 2,
|
||||
decoded_frame_buffer,
|
||||
decoder->GetWidth() * decoder->GetHeight() * 3 / 2,
|
||||
decoder->GetWidth(), decoder->GetHeight());
|
||||
on_receive_decoded_frame(decoded_frame);
|
||||
if (SAVE_DECODED_NV12_STREAM) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
fwrite((unsigned char *)decoded_frame.Buffer(), 1,
|
||||
decoded_frame.Size(), file_nv12_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class NvidiaVideoDecoder : public VideoDecoder {
|
||||
public:
|
||||
int Init();
|
||||
|
||||
int Decode(const uint8_t* data, int size,
|
||||
int Decode(const uint8_t* data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame);
|
||||
|
||||
std::string GetDecoderName() { return "NvidiaH264"; }
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "libyuv.h"
|
||||
#include "log.h"
|
||||
|
||||
#define SAVE_NV12_STREAM 0
|
||||
#define SAVE_H264_STREAM 0
|
||||
// #define SAVE_DECODED_NV12_STREAM
|
||||
// #define SAVE_RECEIVED_H264_STREAM
|
||||
|
||||
void CopyYuvWithStride(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v,
|
||||
int width, int height, int stride_y, int stride_u,
|
||||
@@ -65,31 +65,35 @@ OpenH264Decoder::~OpenH264Decoder() {
|
||||
delete[] yuv420p_frame_;
|
||||
}
|
||||
|
||||
if (SAVE_H264_STREAM && h264_stream_) {
|
||||
fflush(h264_stream_);
|
||||
h264_stream_ = nullptr;
|
||||
}
|
||||
|
||||
if (SAVE_NV12_STREAM && nv12_stream_) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
if (nv12_stream_) {
|
||||
fflush(nv12_stream_);
|
||||
nv12_stream_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||
if (h264_stream_) {
|
||||
fflush(h264_stream_);
|
||||
h264_stream_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int OpenH264Decoder::Init() {
|
||||
if (SAVE_NV12_STREAM) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
nv12_stream_ = fopen("nv12_receive_.yuv", "w+b");
|
||||
if (!nv12_stream_) {
|
||||
LOG_WARN("Fail to open nv12_receive_.yuv");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SAVE_NV12_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||
h264_stream_ = fopen("h264_receive.h264", "w+b");
|
||||
if (!h264_stream_) {
|
||||
LOG_WARN("Fail to open h264_receive.h264");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
frame_width_ = 1280;
|
||||
frame_height_ = 720;
|
||||
@@ -115,15 +119,15 @@ int OpenH264Decoder::Init() {
|
||||
}
|
||||
|
||||
int OpenH264Decoder::Decode(
|
||||
const uint8_t *data, int size,
|
||||
const uint8_t *data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
||||
if (!openh264_decoder_) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SAVE_H264_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||
fwrite((unsigned char *)data, 1, size, h264_stream_);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((*(data + 4) & 0x1f) == 0x07) {
|
||||
// LOG_WARN("Receive key frame");
|
||||
@@ -132,7 +136,7 @@ int OpenH264Decoder::Decode(
|
||||
SBufferInfo sDstBufInfo;
|
||||
memset(&sDstBufInfo, 0, sizeof(SBufferInfo));
|
||||
|
||||
openh264_decoder_->DecodeFrameNoDelay(data, size, yuv420p_planes_,
|
||||
openh264_decoder_->DecodeFrameNoDelay(data, (int)size, yuv420p_planes_,
|
||||
&sDstBufInfo);
|
||||
|
||||
frame_width_ = sDstBufInfo.UsrData.sSystemBuffer.iWidth;
|
||||
@@ -200,10 +204,10 @@ int OpenH264Decoder::Decode(
|
||||
|
||||
on_receive_decoded_frame(*nv12_frame_);
|
||||
|
||||
if (SAVE_NV12_STREAM) {
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
fwrite((unsigned char *)nv12_frame_->Buffer(), 1, nv12_frame_->Size(),
|
||||
nv12_stream_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class OpenH264Decoder : public VideoDecoder {
|
||||
public:
|
||||
int Init();
|
||||
|
||||
int Decode(const uint8_t* data, int size,
|
||||
int Decode(const uint8_t* data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame);
|
||||
|
||||
std::string GetDecoderName() { return "OpenH264"; }
|
||||
@@ -37,8 +37,8 @@ class OpenH264Decoder : public VideoDecoder {
|
||||
FILE* h264_stream_ = nullptr;
|
||||
uint8_t* decoded_frame_ = nullptr;
|
||||
int decoded_frame_size_ = 0;
|
||||
int frame_width_ = 1280;
|
||||
int frame_height_ = 720;
|
||||
uint32_t frame_width_ = 1280;
|
||||
uint32_t frame_height_ = 720;
|
||||
|
||||
unsigned char* yuv420p_planes_[3] = {nullptr, nullptr, nullptr};
|
||||
unsigned char* yuv420p_frame_ = nullptr;
|
||||
|
||||
@@ -20,7 +20,7 @@ class VideoDecoder {
|
||||
virtual int Init() = 0;
|
||||
|
||||
virtual int Decode(
|
||||
const uint8_t *data, int size,
|
||||
const uint8_t *data, size_t size,
|
||||
std::function<void(VideoFrame)> on_receive_decoded_frame) = 0;
|
||||
|
||||
virtual std::string GetDecoderName() = 0;
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define SAVE_RECEIVED_NV12_STREAM 0
|
||||
#define SAVE_ENCODED_AV1_STREAM 0
|
||||
// #define SAVE_RECEIVED_NV12_STREAM
|
||||
// #define SAVE_ENCODED_AV1_STREAM
|
||||
|
||||
#define SET_ENCODER_PARAM_OR_RETURN_ERROR(param_id, param_value) \
|
||||
do { \
|
||||
@@ -104,17 +104,21 @@ int AomAv1Encoder::ResetEncodeResolution(unsigned int width,
|
||||
AomAv1Encoder::AomAv1Encoder() {}
|
||||
|
||||
AomAv1Encoder::~AomAv1Encoder() {
|
||||
if (SAVE_RECEIVED_NV12_STREAM && file_nv12_) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
if (file_nv12_) {
|
||||
fflush(file_nv12_);
|
||||
fclose(file_nv12_);
|
||||
file_nv12_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SAVE_ENCODED_AV1_STREAM && file_av1_) {
|
||||
#ifdef SAVE_ENCODED_AV1_STREAM
|
||||
if (file_av1_) {
|
||||
fflush(file_av1_);
|
||||
fclose(file_av1_);
|
||||
file_av1_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete[] encoded_frame_;
|
||||
encoded_frame_ = nullptr;
|
||||
@@ -245,19 +249,19 @@ int AomAv1Encoder::Init() {
|
||||
frame_for_encode_ = aom_img_wrap(nullptr, AOM_IMG_FMT_NV12, frame_width_,
|
||||
frame_height_, 1, nullptr);
|
||||
|
||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
file_nv12_ = fopen("received_nv12_stream.yuv", "w+b");
|
||||
if (!file_nv12_) {
|
||||
LOG_ERROR("Fail to open received_nv12_stream.yuv");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SAVE_ENCODED_AV1_STREAM) {
|
||||
#ifdef SAVE_ENCODED_AV1_STREAM
|
||||
file_av1_ = fopen("encoded_av1_stream.ivf", "w+b");
|
||||
if (!file_av1_) {
|
||||
LOG_ERROR("Fail to open encoded_av1_stream.ivf");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -266,9 +270,9 @@ int AomAv1Encoder::Encode(const XVideoFrame *video_frame,
|
||||
std::function<int(char *encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image) {
|
||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
||||
}
|
||||
#endif
|
||||
|
||||
aom_codec_err_t ret = AOM_CODEC_OK;
|
||||
|
||||
@@ -293,7 +297,7 @@ int AomAv1Encoder::Encode(const XVideoFrame *video_frame,
|
||||
}
|
||||
|
||||
const uint32_t duration =
|
||||
kRtpTicksPerSecond / static_cast<float>(max_frame_rate_);
|
||||
(uint32_t)(kRtpTicksPerSecond / static_cast<float>(max_frame_rate_));
|
||||
timestamp_ += duration;
|
||||
|
||||
frame_for_encode_->planes[AOM_PLANE_Y] = (unsigned char *)(video_frame->data);
|
||||
@@ -327,7 +331,6 @@ int AomAv1Encoder::Encode(const XVideoFrame *video_frame,
|
||||
}
|
||||
|
||||
aom_codec_iter_t iter = nullptr;
|
||||
int data_pkt_count = 0;
|
||||
while (const aom_codec_cx_pkt_t *pkt =
|
||||
aom_codec_get_cx_data(&aom_av1_encoder_ctx_, &iter)) {
|
||||
if (pkt->kind == AOM_CODEC_CX_FRAME_PKT && pkt->data.frame.sz > 0) {
|
||||
@@ -341,11 +344,9 @@ int AomAv1Encoder::Encode(const XVideoFrame *video_frame,
|
||||
if (on_encoded_image) {
|
||||
on_encoded_image((char *)encoded_frame_, encoded_frame_size_,
|
||||
frame_type);
|
||||
if (SAVE_ENCODED_AV1_STREAM) {
|
||||
#ifdef SAVE_ENCODED_AV1_STREAM
|
||||
fwrite(encoded_frame_, 1, encoded_frame_size_, file_av1_);
|
||||
}
|
||||
} else {
|
||||
OnEncodedImage((char *)encoded_frame_, encoded_frame_size_);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -353,11 +354,6 @@ int AomAv1Encoder::Encode(const XVideoFrame *video_frame,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AomAv1Encoder::OnEncodedImage(char *encoded_packets, size_t size) {
|
||||
LOG_INFO("OnEncodedImage not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AomAv1Encoder::ForceIdr() {
|
||||
force_i_frame_flags_ = AOM_EFLAG_FORCE_KF;
|
||||
return 0;
|
||||
|
||||
@@ -36,20 +36,12 @@ class AomAv1Encoder : public VideoEncoder {
|
||||
|
||||
public:
|
||||
int Init();
|
||||
int Encode(const uint8_t* pData, int nSize,
|
||||
std::function<int(char* encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Encode(const XVideoFrame* video_frame,
|
||||
std::function<int(char* encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image);
|
||||
|
||||
int OnEncodedImage(char* encoded_packets, size_t size);
|
||||
|
||||
int ForceIdr();
|
||||
|
||||
std::string GetEncoderName() { return "AomAV1"; }
|
||||
@@ -65,8 +57,8 @@ class AomAv1Encoder : public VideoEncoder {
|
||||
int Release();
|
||||
|
||||
private:
|
||||
int frame_width_ = 1280;
|
||||
int frame_height_ = 720;
|
||||
uint32_t frame_width_ = 1280;
|
||||
uint32_t frame_height_ = 720;
|
||||
int key_frame_interval_ = 300;
|
||||
int target_bitrate_ = 1000;
|
||||
int max_bitrate_ = 2500000;
|
||||
@@ -91,7 +83,7 @@ class AomAv1Encoder : public VideoEncoder {
|
||||
aom_enc_frame_flags_t force_i_frame_flags_ = 0;
|
||||
uint8_t* encoded_frame_ = nullptr;
|
||||
size_t encoded_frame_capacity_ = 0;
|
||||
int encoded_frame_size_ = 0;
|
||||
size_t encoded_frame_size_ = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -6,22 +6,26 @@
|
||||
#include "nvcodec_api.h"
|
||||
#include "nvcodec_common.h"
|
||||
|
||||
#define SAVE_RECEIVED_NV12_STREAM 0
|
||||
#define SAVE_ENCODED_H264_STREAM 0
|
||||
// #define SAVE_RECEIVED_NV12_STREAM
|
||||
// #define SAVE_ENCODED_H264_STREAM
|
||||
|
||||
NvidiaVideoEncoder::NvidiaVideoEncoder() {}
|
||||
NvidiaVideoEncoder::~NvidiaVideoEncoder() {
|
||||
if (SAVE_RECEIVED_NV12_STREAM && file_nv12_) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
if (file_nv12_) {
|
||||
fflush(file_nv12_);
|
||||
fclose(file_nv12_);
|
||||
file_nv12_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SAVE_ENCODED_H264_STREAM && file_h264_) {
|
||||
#ifdef SAVE_ENCODED_H264_STREAM
|
||||
if (file_h264_) {
|
||||
fflush(file_h264_);
|
||||
fclose(file_h264_);
|
||||
file_h264_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nv12_data_) {
|
||||
free(nv12_data_);
|
||||
@@ -106,19 +110,20 @@ int NvidiaVideoEncoder::Init() {
|
||||
|
||||
encoder_->CreateEncoder(&init_params);
|
||||
|
||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
file_nv12_ = fopen("received_nv12_stream.yuv", "w+b");
|
||||
if (!file_nv12_) {
|
||||
LOG_WARN("Fail to open received_nv12_stream.yuv");
|
||||
}
|
||||
}
|
||||
|
||||
if (SAVE_ENCODED_H264_STREAM) {
|
||||
#endif
|
||||
|
||||
#ifdef SAVE_ENCODED_H264_STREAM
|
||||
file_h264_ = fopen("encoded_h264_stream.h264", "w+b");
|
||||
if (!file_h264_) {
|
||||
LOG_WARN("Fail to open encoded_h264_stream.h264");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -133,9 +138,9 @@ int NvidiaVideoEncoder::Encode(
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (video_frame->width != frame_width_ ||
|
||||
video_frame->height != frame_height_) {
|
||||
@@ -178,11 +183,9 @@ int NvidiaVideoEncoder::Encode(
|
||||
for (const auto &packet : encoded_packets_) {
|
||||
if (on_encoded_image) {
|
||||
on_encoded_image((char *)packet.data(), packet.size(), frame_type);
|
||||
if (SAVE_ENCODED_H264_STREAM) {
|
||||
#ifdef SAVE_ENCODED_H264_STREAM
|
||||
fwrite((unsigned char *)packet.data(), 1, packet.size(), file_h264_);
|
||||
}
|
||||
} else {
|
||||
OnEncodedImage((char *)packet.data(), packet.size());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,11 +199,6 @@ int NvidiaVideoEncoder::Encode(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NvidiaVideoEncoder::OnEncodedImage(char *encoded_packets, size_t size) {
|
||||
LOG_INFO("OnEncodedImage not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NvidiaVideoEncoder::ForceIdr() {
|
||||
if (!encoder_) {
|
||||
return -1;
|
||||
|
||||
@@ -12,20 +12,12 @@ class NvidiaVideoEncoder : public VideoEncoder {
|
||||
virtual ~NvidiaVideoEncoder();
|
||||
|
||||
int Init();
|
||||
int Encode(const uint8_t* pData, int nSize,
|
||||
std::function<int(char* encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Encode(const XVideoFrame* video_frame,
|
||||
std::function<int(char* encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image);
|
||||
|
||||
virtual int OnEncodedImage(char* encoded_packets, size_t size);
|
||||
|
||||
int ForceIdr();
|
||||
|
||||
std::string GetEncoderName() { return "NvidiaH264"; }
|
||||
|
||||
@@ -5,17 +5,15 @@
|
||||
#include "libyuv.h"
|
||||
#include "log.h"
|
||||
|
||||
#define SAVE_RECEIVED_NV12_STREAM 0
|
||||
#define SAVE_ENCODED_H264_STREAM 0
|
||||
// #define SAVE_RECEIVED_NV12_STREAM
|
||||
// #define SAVE_ENCODED_H264_STREAM
|
||||
|
||||
void Nv12ToI420(unsigned char *Src_data, int src_width, int src_height,
|
||||
unsigned char *Dst_data) {
|
||||
// NV12 video size
|
||||
int NV12_Size = src_width * src_height * 3 / 2;
|
||||
// NV12
|
||||
int NV12_Y_Size = src_width * src_height;
|
||||
|
||||
// YUV420 video size
|
||||
int I420_Size = src_width * src_height * 3 / 2;
|
||||
// YUV420
|
||||
int I420_Y_Size = src_width * src_height;
|
||||
int I420_U_Size = (src_width >> 1) * (src_height >> 1);
|
||||
int I420_V_Size = I420_U_Size;
|
||||
@@ -29,7 +27,7 @@ void Nv12ToI420(unsigned char *Src_data, int src_width, int src_height,
|
||||
// dst: buffer address of Y channel、U channel and V channel
|
||||
unsigned char *Y_data_Dst = Dst_data;
|
||||
unsigned char *U_data_Dst = Dst_data + I420_Y_Size;
|
||||
unsigned char *V_data_Dst = Dst_data + I420_Y_Size + I420_U_Size;
|
||||
unsigned char *V_data_Dst = Dst_data + I420_Y_Size + I420_V_Size;
|
||||
int Dst_Stride_Y = src_width;
|
||||
int Dst_Stride_U = src_width >> 1;
|
||||
int Dst_Stride_V = Dst_Stride_U;
|
||||
@@ -43,17 +41,21 @@ void Nv12ToI420(unsigned char *Src_data, int src_width, int src_height,
|
||||
OpenH264Encoder::OpenH264Encoder() {}
|
||||
|
||||
OpenH264Encoder::~OpenH264Encoder() {
|
||||
if (SAVE_RECEIVED_NV12_STREAM && file_nv12_) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
if (file_nv12_) {
|
||||
fflush(file_nv12_);
|
||||
fclose(file_nv12_);
|
||||
file_nv12_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SAVE_ENCODED_H264_STREAM && file_h264_) {
|
||||
#ifdef SAVE_ENCODED_H264_STREAM
|
||||
if (file_h264_) {
|
||||
fflush(file_h264_);
|
||||
fclose(file_h264_);
|
||||
file_h264_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (yuv420p_frame_) {
|
||||
delete[] yuv420p_frame_;
|
||||
@@ -160,19 +162,19 @@ int OpenH264Encoder::Init() {
|
||||
video_format_ = EVideoFormatType::videoFormatI420;
|
||||
openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT, &video_format_);
|
||||
|
||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
file_nv12_ = fopen("received_nv12_stream.yuv", "w+b");
|
||||
if (!file_nv12_) {
|
||||
LOG_WARN("Fail to open received_nv12_stream.yuv");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SAVE_ENCODED_H264_STREAM) {
|
||||
#ifdef SAVE_ENCODED_H264_STREAM
|
||||
file_h264_ = fopen("encoded_h264_stream.h264", "w+b");
|
||||
if (!file_h264_) {
|
||||
LOG_WARN("Fail to open encoded_h264_stream.h264");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -187,9 +189,9 @@ int OpenH264Encoder::Encode(
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
||||
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!yuv420p_frame_) {
|
||||
yuv420p_frame_capacity_ = video_frame->size;
|
||||
@@ -267,7 +269,7 @@ int OpenH264Encoder::Encode(
|
||||
}
|
||||
|
||||
size_t frag = 0;
|
||||
int encoded_frame_size = 0;
|
||||
size_t encoded_frame_size = 0;
|
||||
for (int layer = 0; layer < info.iLayerNum; ++layer) {
|
||||
const SLayerBSInfo &layerInfo = info.sLayerInfo[layer];
|
||||
size_t layer_len = 0;
|
||||
@@ -281,11 +283,9 @@ int OpenH264Encoder::Encode(
|
||||
|
||||
if (on_encoded_image) {
|
||||
on_encoded_image((char *)encoded_frame_, encoded_frame_size_, frame_type);
|
||||
if (SAVE_ENCODED_H264_STREAM) {
|
||||
#ifdef SAVE_ENCODED_H264_STREAM
|
||||
fwrite(encoded_frame_, 1, encoded_frame_size_, file_h264_);
|
||||
}
|
||||
} else {
|
||||
OnEncodedImage((char *)encoded_frame_, encoded_frame_size_);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
if (info.eFrameType == videoFrameTypeInvalid) {
|
||||
@@ -327,11 +327,9 @@ int OpenH264Encoder::Encode(
|
||||
|
||||
if (on_encoded_image) {
|
||||
on_encoded_image((char *)encoded_frame_, frame_type);
|
||||
if (SAVE_ENCODED_H264_STREAM) {
|
||||
#ifdef SAVE_ENCODED_H264_STREAM
|
||||
fwrite(encoded_frame_, 1, encoded_frame_size_, file_h264_);
|
||||
}
|
||||
} else {
|
||||
OnEncodedImage((char *)encoded_frame_, encoded_frame_size_);
|
||||
#endif
|
||||
}
|
||||
|
||||
EVideoFrameType ft_temp = info.eFrameType;
|
||||
@@ -353,11 +351,6 @@ int OpenH264Encoder::Encode(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OpenH264Encoder::OnEncodedImage(char *encoded_packets, size_t size) {
|
||||
LOG_INFO("OnEncodedImage not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OpenH264Encoder::ForceIdr() {
|
||||
if (openh264_encoder_) {
|
||||
return openh264_encoder_->ForceIntraFrame(true);
|
||||
|
||||
@@ -23,20 +23,12 @@ class OpenH264Encoder : public VideoEncoder {
|
||||
virtual ~OpenH264Encoder();
|
||||
|
||||
int Init();
|
||||
int Encode(const uint8_t* pData, int nSize,
|
||||
std::function<int(char* encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Encode(const XVideoFrame* video_frame,
|
||||
std::function<int(char* encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image);
|
||||
|
||||
int OnEncodedImage(char* encoded_packets, size_t size);
|
||||
|
||||
int ForceIdr();
|
||||
|
||||
std::string GetEncoderName() { return "OpenH264"; }
|
||||
@@ -48,8 +40,8 @@ class OpenH264Encoder : public VideoEncoder {
|
||||
int Release();
|
||||
|
||||
private:
|
||||
int frame_width_ = 1280;
|
||||
int frame_height_ = 720;
|
||||
uint32_t frame_width_ = 1280;
|
||||
uint32_t frame_height_ = 720;
|
||||
int key_frame_interval_ = 300;
|
||||
int target_bitrate_ = 10000000;
|
||||
int max_bitrate_ = 10000000;
|
||||
@@ -68,10 +60,10 @@ class OpenH264Encoder : public VideoEncoder {
|
||||
int video_format_;
|
||||
SSourcePicture raw_frame_;
|
||||
unsigned char* yuv420p_frame_ = nullptr;
|
||||
int yuv420p_frame_capacity_ = 0;
|
||||
size_t yuv420p_frame_capacity_ = 0;
|
||||
uint8_t* encoded_frame_ = nullptr;
|
||||
int encoded_frame_capacity_ = 0;
|
||||
int encoded_frame_size_ = 0;
|
||||
size_t encoded_frame_capacity_ = 0;
|
||||
size_t encoded_frame_size_ = 0;
|
||||
bool got_output = false;
|
||||
bool is_keyframe = false;
|
||||
int temporal_ = 1;
|
||||
|
||||
@@ -20,18 +20,11 @@ class VideoEncoder {
|
||||
public:
|
||||
virtual int Init() = 0;
|
||||
|
||||
virtual int Encode(const uint8_t* pData, int nSize,
|
||||
std::function<int(char* encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image) = 0;
|
||||
|
||||
virtual int Encode(const XVideoFrame* video_frame,
|
||||
std::function<int(char* encoded_packets, size_t size,
|
||||
VideoFrameType frame_type)>
|
||||
on_encoded_image) = 0;
|
||||
|
||||
virtual int OnEncodedImage(char* encoded_packets, size_t size) = 0;
|
||||
|
||||
virtual int ForceIdr() = 0;
|
||||
|
||||
virtual std::string GetEncoderName() = 0;
|
||||
|
||||
1306
src/qos/kcp/ikcp.c
1306
src/qos/kcp/ikcp.c
File diff suppressed because it is too large
Load Diff
@@ -1,416 +0,0 @@
|
||||
//=====================================================================
|
||||
//
|
||||
// KCP - A Better ARQ Protocol Implementation
|
||||
// skywind3000 (at) gmail.com, 2010-2011
|
||||
//
|
||||
// Features:
|
||||
// + Average RTT reduce 30% - 40% vs traditional ARQ like tcp.
|
||||
// + Maximum RTT reduce three times vs tcp.
|
||||
// + Lightweight, distributed as a single source file.
|
||||
//
|
||||
//=====================================================================
|
||||
#ifndef __IKCP_H__
|
||||
#define __IKCP_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// 32BIT INTEGER DEFINITION
|
||||
//=====================================================================
|
||||
#ifndef __INTEGER_32_BITS__
|
||||
#define __INTEGER_32_BITS__
|
||||
#if defined(_WIN64) || defined(WIN64) || defined(__amd64__) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_IA64) || \
|
||||
defined(_M_AMD64)
|
||||
typedef unsigned int ISTDUINT32;
|
||||
typedef int ISTDINT32;
|
||||
#elif defined(_WIN32) || defined(WIN32) || defined(__i386__) || \
|
||||
defined(__i386) || defined(_M_X86)
|
||||
typedef unsigned long ISTDUINT32;
|
||||
typedef long ISTDINT32;
|
||||
#elif defined(__MACOS__)
|
||||
typedef UInt32 ISTDUINT32;
|
||||
typedef SInt32 ISTDINT32;
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#include <sys/types.h>
|
||||
typedef u_int32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#elif defined(__BEOS__)
|
||||
#include <sys/inttypes.h>
|
||||
typedef u_int32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#elif (defined(_MSC_VER) || defined(__BORLANDC__)) && (!defined(__MSDOS__))
|
||||
typedef unsigned __int32 ISTDUINT32;
|
||||
typedef __int32 ISTDINT32;
|
||||
#elif defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
typedef uint32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#else
|
||||
typedef unsigned long ISTDUINT32;
|
||||
typedef long ISTDINT32;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// Integer Definition
|
||||
//=====================================================================
|
||||
#ifndef __IINT8_DEFINED
|
||||
#define __IINT8_DEFINED
|
||||
typedef char IINT8;
|
||||
#endif
|
||||
|
||||
#ifndef __IUINT8_DEFINED
|
||||
#define __IUINT8_DEFINED
|
||||
typedef unsigned char IUINT8;
|
||||
#endif
|
||||
|
||||
#ifndef __IUINT16_DEFINED
|
||||
#define __IUINT16_DEFINED
|
||||
typedef unsigned short IUINT16;
|
||||
#endif
|
||||
|
||||
#ifndef __IINT16_DEFINED
|
||||
#define __IINT16_DEFINED
|
||||
typedef short IINT16;
|
||||
#endif
|
||||
|
||||
#ifndef __IINT32_DEFINED
|
||||
#define __IINT32_DEFINED
|
||||
typedef ISTDINT32 IINT32;
|
||||
#endif
|
||||
|
||||
#ifndef __IUINT32_DEFINED
|
||||
#define __IUINT32_DEFINED
|
||||
typedef ISTDUINT32 IUINT32;
|
||||
#endif
|
||||
|
||||
#ifndef __IINT64_DEFINED
|
||||
#define __IINT64_DEFINED
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 IINT64;
|
||||
#else
|
||||
typedef long long IINT64;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __IUINT64_DEFINED
|
||||
#define __IUINT64_DEFINED
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef unsigned __int64 IUINT64;
|
||||
#else
|
||||
typedef unsigned long long IUINT64;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef INLINE
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
|
||||
#define INLINE __inline__ __attribute__((always_inline))
|
||||
#else
|
||||
#define INLINE __inline__
|
||||
#endif
|
||||
|
||||
#elif (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__WATCOMC__))
|
||||
#define INLINE __inline
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (!defined(__cplusplus)) && (!defined(inline))
|
||||
#define inline INLINE
|
||||
#endif
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// QUEUE DEFINITION
|
||||
//=====================================================================
|
||||
#ifndef __IQUEUE_DEF__
|
||||
#define __IQUEUE_DEF__
|
||||
|
||||
struct IQUEUEHEAD {
|
||||
struct IQUEUEHEAD *next, *prev;
|
||||
};
|
||||
|
||||
typedef struct IQUEUEHEAD iqueue_head;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// queue init
|
||||
//---------------------------------------------------------------------
|
||||
#define IQUEUE_HEAD_INIT(name) { &(name), &(name) }
|
||||
#define IQUEUE_HEAD(name) \
|
||||
struct IQUEUEHEAD name = IQUEUE_HEAD_INIT(name)
|
||||
|
||||
#define IQUEUE_INIT(ptr) ( \
|
||||
(ptr)->next = (ptr), (ptr)->prev = (ptr))
|
||||
|
||||
#define IOFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
|
||||
#define ICONTAINEROF(ptr, type, member) ( \
|
||||
(type*)( ((char*)((type*)ptr)) - IOFFSETOF(type, member)) )
|
||||
|
||||
#define IQUEUE_ENTRY(ptr, type, member) ICONTAINEROF(ptr, type, member)
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// queue operation
|
||||
//---------------------------------------------------------------------
|
||||
#define IQUEUE_ADD(node, head) ( \
|
||||
(node)->prev = (head), (node)->next = (head)->next, \
|
||||
(head)->next->prev = (node), (head)->next = (node))
|
||||
|
||||
#define IQUEUE_ADD_TAIL(node, head) ( \
|
||||
(node)->prev = (head)->prev, (node)->next = (head), \
|
||||
(head)->prev->next = (node), (head)->prev = (node))
|
||||
|
||||
#define IQUEUE_DEL_BETWEEN(p, n) ((n)->prev = (p), (p)->next = (n))
|
||||
|
||||
#define IQUEUE_DEL(entry) (\
|
||||
(entry)->next->prev = (entry)->prev, \
|
||||
(entry)->prev->next = (entry)->next, \
|
||||
(entry)->next = 0, (entry)->prev = 0)
|
||||
|
||||
#define IQUEUE_DEL_INIT(entry) do { \
|
||||
IQUEUE_DEL(entry); IQUEUE_INIT(entry); } while (0)
|
||||
|
||||
#define IQUEUE_IS_EMPTY(entry) ((entry) == (entry)->next)
|
||||
|
||||
#define iqueue_init IQUEUE_INIT
|
||||
#define iqueue_entry IQUEUE_ENTRY
|
||||
#define iqueue_add IQUEUE_ADD
|
||||
#define iqueue_add_tail IQUEUE_ADD_TAIL
|
||||
#define iqueue_del IQUEUE_DEL
|
||||
#define iqueue_del_init IQUEUE_DEL_INIT
|
||||
#define iqueue_is_empty IQUEUE_IS_EMPTY
|
||||
|
||||
#define IQUEUE_FOREACH(iterator, head, TYPE, MEMBER) \
|
||||
for ((iterator) = iqueue_entry((head)->next, TYPE, MEMBER); \
|
||||
&((iterator)->MEMBER) != (head); \
|
||||
(iterator) = iqueue_entry((iterator)->MEMBER.next, TYPE, MEMBER))
|
||||
|
||||
#define iqueue_foreach(iterator, head, TYPE, MEMBER) \
|
||||
IQUEUE_FOREACH(iterator, head, TYPE, MEMBER)
|
||||
|
||||
#define iqueue_foreach_entry(pos, head) \
|
||||
for( (pos) = (head)->next; (pos) != (head) ; (pos) = (pos)->next )
|
||||
|
||||
|
||||
#define __iqueue_splice(list, head) do { \
|
||||
iqueue_head *first = (list)->next, *last = (list)->prev; \
|
||||
iqueue_head *at = (head)->next; \
|
||||
(first)->prev = (head), (head)->next = (first); \
|
||||
(last)->next = (at), (at)->prev = (last); } while (0)
|
||||
|
||||
#define iqueue_splice(list, head) do { \
|
||||
if (!iqueue_is_empty(list)) __iqueue_splice(list, head); } while (0)
|
||||
|
||||
#define iqueue_splice_init(list, head) do { \
|
||||
iqueue_splice(list, head); iqueue_init(list); } while (0)
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4311)
|
||||
#pragma warning(disable:4312)
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// BYTE ORDER & ALIGNMENT
|
||||
//---------------------------------------------------------------------
|
||||
#ifndef IWORDS_BIG_ENDIAN
|
||||
#ifdef _BIG_ENDIAN_
|
||||
#if _BIG_ENDIAN_
|
||||
#define IWORDS_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#ifndef IWORDS_BIG_ENDIAN
|
||||
#if defined(__hppa__) || \
|
||||
defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
|
||||
(defined(__MIPS__) && defined(__MIPSEB__)) || \
|
||||
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
|
||||
defined(__sparc__) || defined(__powerpc__) || \
|
||||
defined(__mc68000__) || defined(__s390x__) || defined(__s390__)
|
||||
#define IWORDS_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#ifndef IWORDS_BIG_ENDIAN
|
||||
#define IWORDS_BIG_ENDIAN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef IWORDS_MUST_ALIGN
|
||||
#if defined(__i386__) || defined(__i386) || defined(_i386_)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#elif defined(_M_IX86) || defined(_X86_) || defined(__x86_64__)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#elif defined(__amd64) || defined(__amd64__)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#else
|
||||
#define IWORDS_MUST_ALIGN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// SEGMENT
|
||||
//=====================================================================
|
||||
struct IKCPSEG
|
||||
{
|
||||
struct IQUEUEHEAD node;
|
||||
IUINT32 conv;
|
||||
IUINT32 cmd;
|
||||
IUINT32 frg;
|
||||
IUINT32 wnd;
|
||||
IUINT32 ts;
|
||||
IUINT32 sn;
|
||||
IUINT32 una;
|
||||
IUINT32 len;
|
||||
IUINT32 resendts;
|
||||
IUINT32 rto;
|
||||
IUINT32 fastack;
|
||||
IUINT32 xmit;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// IKCPCB
|
||||
//---------------------------------------------------------------------
|
||||
struct IKCPCB
|
||||
{
|
||||
IUINT32 conv, mtu, mss, state;
|
||||
IUINT32 snd_una, snd_nxt, rcv_nxt;
|
||||
IUINT32 ts_recent, ts_lastack, ssthresh;
|
||||
IINT32 rx_rttval, rx_srtt, rx_rto, rx_minrto;
|
||||
IUINT32 snd_wnd, rcv_wnd, rmt_wnd, cwnd, probe;
|
||||
IUINT32 current, interval, ts_flush, xmit;
|
||||
IUINT32 nrcv_buf, nsnd_buf;
|
||||
IUINT32 nrcv_que, nsnd_que;
|
||||
IUINT32 nodelay, updated;
|
||||
IUINT32 ts_probe, probe_wait;
|
||||
IUINT32 dead_link, incr;
|
||||
struct IQUEUEHEAD snd_queue;
|
||||
struct IQUEUEHEAD rcv_queue;
|
||||
struct IQUEUEHEAD snd_buf;
|
||||
struct IQUEUEHEAD rcv_buf;
|
||||
IUINT32 *acklist;
|
||||
IUINT32 ackcount;
|
||||
IUINT32 ackblock;
|
||||
void *user;
|
||||
char *buffer;
|
||||
int fastresend;
|
||||
int fastlimit;
|
||||
int nocwnd, stream;
|
||||
int logmask;
|
||||
int (*output)(const char *buf, int len, struct IKCPCB *kcp, void *user);
|
||||
void (*writelog)(const char *log, struct IKCPCB *kcp, void *user);
|
||||
};
|
||||
|
||||
|
||||
typedef struct IKCPCB ikcpcb;
|
||||
|
||||
#define IKCP_LOG_OUTPUT 1
|
||||
#define IKCP_LOG_INPUT 2
|
||||
#define IKCP_LOG_SEND 4
|
||||
#define IKCP_LOG_RECV 8
|
||||
#define IKCP_LOG_IN_DATA 16
|
||||
#define IKCP_LOG_IN_ACK 32
|
||||
#define IKCP_LOG_IN_PROBE 64
|
||||
#define IKCP_LOG_IN_WINS 128
|
||||
#define IKCP_LOG_OUT_DATA 256
|
||||
#define IKCP_LOG_OUT_ACK 512
|
||||
#define IKCP_LOG_OUT_PROBE 1024
|
||||
#define IKCP_LOG_OUT_WINS 2048
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
// create a new kcp control object, 'conv' must equal in two endpoint
|
||||
// from the same connection. 'user' will be passed to the output callback
|
||||
// output callback can be setup like this: 'kcp->output = my_udp_output'
|
||||
ikcpcb* ikcp_create(IUINT32 conv, void *user);
|
||||
|
||||
// release kcp control object
|
||||
void ikcp_release(ikcpcb *kcp);
|
||||
|
||||
// set output callback, which will be invoked by kcp
|
||||
void ikcp_setoutput(ikcpcb *kcp, int (*output)(const char *buf, int len,
|
||||
ikcpcb *kcp, void *user));
|
||||
|
||||
// user/upper level recv: returns size, returns below zero for EAGAIN
|
||||
int ikcp_recv(ikcpcb *kcp, char *buffer, int len);
|
||||
|
||||
// user/upper level send, returns below zero for error
|
||||
int ikcp_send(ikcpcb *kcp, const char *buffer, int len);
|
||||
|
||||
// update state (call it repeatedly, every 10ms-100ms), or you can ask
|
||||
// ikcp_check when to call it again (without ikcp_input/_send calling).
|
||||
// 'current' - current timestamp in millisec.
|
||||
void ikcp_update(ikcpcb *kcp, IUINT32 current);
|
||||
|
||||
// Determine when should you invoke ikcp_update:
|
||||
// returns when you should invoke ikcp_update in millisec, if there
|
||||
// is no ikcp_input/_send calling. you can call ikcp_update in that
|
||||
// time, instead of call update repeatly.
|
||||
// Important to reduce unnacessary ikcp_update invoking. use it to
|
||||
// schedule ikcp_update (eg. implementing an epoll-like mechanism,
|
||||
// or optimize ikcp_update when handling massive kcp connections)
|
||||
IUINT32 ikcp_check(const ikcpcb *kcp, IUINT32 current);
|
||||
|
||||
// when you received a low level packet (eg. UDP packet), call it
|
||||
int ikcp_input(ikcpcb *kcp, const char *data, long size);
|
||||
|
||||
// flush pending data
|
||||
void ikcp_flush(ikcpcb *kcp);
|
||||
|
||||
// check the size of next message in the recv queue
|
||||
int ikcp_peeksize(const ikcpcb *kcp);
|
||||
|
||||
// change MTU size, default is 1400
|
||||
int ikcp_setmtu(ikcpcb *kcp, int mtu);
|
||||
|
||||
// set maximum window size: sndwnd=32, rcvwnd=32 by default
|
||||
int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd);
|
||||
|
||||
// get how many packet is waiting to be sent
|
||||
int ikcp_waitsnd(const ikcpcb *kcp);
|
||||
|
||||
// fastest: ikcp_nodelay(kcp, 1, 20, 2, 1)
|
||||
// nodelay: 0:disable(default), 1:enable
|
||||
// interval: internal update timer interval in millisec, default is 100ms
|
||||
// resend: 0:disable fast resend(default), 1:enable fast resend
|
||||
// nc: 0:normal congestion control(default), 1:disable congestion control
|
||||
int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc);
|
||||
|
||||
|
||||
void ikcp_log(ikcpcb *kcp, int mask, const char *fmt, ...);
|
||||
|
||||
// setup allocator
|
||||
void ikcp_allocator(void* (*new_malloc)(size_t), void (*new_free)(void*));
|
||||
|
||||
// read conv
|
||||
IUINT32 ikcp_getconv(const void *ptr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <thread>
|
||||
|
||||
#include "common.h"
|
||||
#include "ikcp.h"
|
||||
#include "log.h"
|
||||
#if __APPLE__
|
||||
#else
|
||||
@@ -49,7 +48,7 @@ int IceTransmission::SetLocalCapabilities(
|
||||
hardware_acceleration_ = hardware_acceleration;
|
||||
use_trickle_ice_ = use_trickle_ice;
|
||||
use_reliable_ice_ = use_reliable_ice;
|
||||
enable_turn_ = force_turn;
|
||||
enable_turn_ = enable_turn;
|
||||
force_turn_ = force_turn;
|
||||
support_video_payload_types_ = video_payload_types;
|
||||
support_audio_payload_types_ = audio_payload_types;
|
||||
@@ -105,10 +104,9 @@ int IceTransmission::InitIceTransmission(
|
||||
});
|
||||
rtp_video_receiver_->SetOnReceiveCompleteFrame(
|
||||
[this](VideoFrame &video_frame) -> void {
|
||||
// LOG_ERROR("OnReceiveCompleteFrame {}", video_frame.Size());
|
||||
ice_io_statistics_->UpdateVideoInboundBytes(video_frame.Size());
|
||||
|
||||
int num_frame_returned = video_decoder_->Decode(
|
||||
ice_io_statistics_->UpdateVideoInboundBytes(
|
||||
(uint32_t)video_frame.Size());
|
||||
[[maybe_unused]] int num_frame_returned = video_decoder_->Decode(
|
||||
(uint8_t *)video_frame.Buffer(), video_frame.Size(),
|
||||
[this](VideoFrame video_frame) {
|
||||
if (on_receive_video_) {
|
||||
@@ -140,7 +138,7 @@ int IceTransmission::InitIceTransmission(
|
||||
return -2;
|
||||
}
|
||||
|
||||
ice_io_statistics_->UpdateVideoOutboundBytes(size);
|
||||
ice_io_statistics_->UpdateVideoOutboundBytes((uint32_t)size);
|
||||
return ice_agent_->Send(data, size);
|
||||
});
|
||||
|
||||
@@ -166,9 +164,9 @@ int IceTransmission::InitIceTransmission(
|
||||
});
|
||||
rtp_audio_receiver_->SetOnReceiveData([this](const char *data,
|
||||
size_t size) -> void {
|
||||
ice_io_statistics_->UpdateAudioInboundBytes(size);
|
||||
ice_io_statistics_->UpdateAudioInboundBytes((uint32_t)size);
|
||||
|
||||
int num_frame_returned = audio_decoder_->Decode(
|
||||
[[maybe_unused]] int num_frame_returned = audio_decoder_->Decode(
|
||||
(uint8_t *)data, size, [this](uint8_t *data, int size) {
|
||||
if (on_receive_audio_) {
|
||||
on_receive_audio_((const char *)data, size, remote_user_id_.data(),
|
||||
@@ -192,7 +190,7 @@ int IceTransmission::InitIceTransmission(
|
||||
return -2;
|
||||
}
|
||||
|
||||
ice_io_statistics_->UpdateAudioOutboundBytes(size);
|
||||
ice_io_statistics_->UpdateAudioOutboundBytes((uint32_t)size);
|
||||
return ice_agent_->Send(data, size);
|
||||
});
|
||||
|
||||
@@ -218,7 +216,7 @@ int IceTransmission::InitIceTransmission(
|
||||
});
|
||||
rtp_data_receiver_->SetOnReceiveData(
|
||||
[this](const char *data, size_t size) -> void {
|
||||
ice_io_statistics_->UpdateDataInboundBytes(size);
|
||||
ice_io_statistics_->UpdateDataInboundBytes((uint32_t)size);
|
||||
|
||||
if (on_receive_data_) {
|
||||
on_receive_data_(data, size, remote_user_id_.data(),
|
||||
@@ -241,7 +239,7 @@ int IceTransmission::InitIceTransmission(
|
||||
return -2;
|
||||
}
|
||||
|
||||
ice_io_statistics_->UpdateDataOutboundBytes(size);
|
||||
ice_io_statistics_->UpdateDataOutboundBytes((uint32_t)size);
|
||||
return ice_agent_->Send(data, size);
|
||||
});
|
||||
|
||||
@@ -253,8 +251,9 @@ int IceTransmission::InitIceTransmission(
|
||||
turn_password);
|
||||
|
||||
ice_agent_->CreateIceAgent(
|
||||
[](NiceAgent *agent, guint stream_id, guint component_id,
|
||||
NiceComponentState state, gpointer user_ptr) {
|
||||
[]([[maybe_unused]] NiceAgent *agent, [[maybe_unused]] guint stream_id,
|
||||
[[maybe_unused]] guint component_id, NiceComponentState state,
|
||||
gpointer user_ptr) {
|
||||
if (user_ptr) {
|
||||
IceTransmission *ice_transmission_obj =
|
||||
static_cast<IceTransmission *>(user_ptr);
|
||||
@@ -313,7 +312,8 @@ int IceTransmission::InitIceTransmission(
|
||||
}
|
||||
}
|
||||
},
|
||||
[](NiceAgent *agent, guint stream_id, gpointer user_ptr) {
|
||||
[]([[maybe_unused]] NiceAgent *agent, [[maybe_unused]] guint stream_id,
|
||||
gpointer user_ptr) {
|
||||
// non-trickle
|
||||
if (user_ptr) {
|
||||
IceTransmission *ice_transmission_obj =
|
||||
@@ -365,8 +365,9 @@ int IceTransmission::InitIceTransmission(
|
||||
&net_traffic_stats, ice_transmission_obj->user_data_);
|
||||
}
|
||||
},
|
||||
[](NiceAgent *agent, guint stream_id, guint component_id, guint size,
|
||||
gchar *buffer, gpointer user_ptr) {
|
||||
[]([[maybe_unused]] NiceAgent *agent, [[maybe_unused]] guint stream_id,
|
||||
[[maybe_unused]] guint component_id, guint size, gchar *buffer,
|
||||
gpointer user_ptr) {
|
||||
if (user_ptr) {
|
||||
IceTransmission *ice_transmission_obj =
|
||||
static_cast<IceTransmission *>(user_ptr);
|
||||
@@ -977,7 +978,7 @@ int IceTransmission::SendVideoFrame(const XVideoFrame *video_frame) {
|
||||
if (video_rtp_codec_) {
|
||||
video_rtp_codec_->Encode(
|
||||
static_cast<RtpCodec::VideoFrameType>(frame_type),
|
||||
(uint8_t *)encoded_frame, size, packets);
|
||||
(uint8_t *)encoded_frame, (uint32_t)size, packets);
|
||||
}
|
||||
rtp_video_sender_->Enqueue(packets);
|
||||
}
|
||||
@@ -1007,15 +1008,15 @@ int IceTransmission::SendAudioFrame(const char *data, size_t size) {
|
||||
if (rtp_audio_sender_) {
|
||||
if (audio_rtp_codec_) {
|
||||
std::vector<RtpPacket> packets;
|
||||
audio_rtp_codec_->Encode((uint8_t *)encoded_audio_buffer, size,
|
||||
packets);
|
||||
audio_rtp_codec_->Encode((uint8_t *)encoded_audio_buffer,
|
||||
(uint32_t)size, packets);
|
||||
rtp_audio_sender_->Enqueue(packets);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int IceTransmission::SendDataFrame(const char *data, size_t size) {
|
||||
@@ -1030,7 +1031,7 @@ int IceTransmission::SendDataFrame(const char *data, size_t size) {
|
||||
|
||||
if (rtp_data_sender_) {
|
||||
if (data_rtp_codec_) {
|
||||
data_rtp_codec_->Encode((uint8_t *)data, size, packets);
|
||||
data_rtp_codec_->Encode((uint8_t *)data, (uint32_t)size, packets);
|
||||
rtp_data_sender_->Enqueue(packets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,8 @@ void WsClient::Ping(websocketpp::connection_hdl hdl) {
|
||||
|
||||
WsStatus WsClient::GetStatus() { return ws_status_; }
|
||||
|
||||
void WsClient::OnOpen(client *c, websocketpp::connection_hdl hdl) {
|
||||
void WsClient::OnOpen([[maybe_unused]] client *c,
|
||||
websocketpp::connection_hdl hdl) {
|
||||
ws_status_ = WsStatus::WsOpened;
|
||||
on_ws_status_(WsStatus::WsOpened);
|
||||
|
||||
@@ -155,13 +156,15 @@ void WsClient::OnOpen(client *c, websocketpp::connection_hdl hdl) {
|
||||
}
|
||||
}
|
||||
|
||||
void WsClient::OnFail(client *c, websocketpp::connection_hdl hdl) {
|
||||
void WsClient::OnFail([[maybe_unused]] client *c,
|
||||
websocketpp::connection_hdl hdl) {
|
||||
ws_status_ = WsStatus::WsFailed;
|
||||
on_ws_status_(WsStatus::WsFailed);
|
||||
Connect(uri_);
|
||||
}
|
||||
|
||||
void WsClient::OnClose(client *c, websocketpp::connection_hdl hdl) {
|
||||
void WsClient::OnClose([[maybe_unused]] client *c,
|
||||
websocketpp::connection_hdl hdl) {
|
||||
ws_status_ = WsStatus::WsServerClosed;
|
||||
on_ws_status_(WsStatus::WsServerClosed);
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
Purschke <purschke@bnl.gov>.
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4267)
|
||||
|
||||
#ifndef WEBSOCKETPP_COMMON_MD5_HPP
|
||||
#define WEBSOCKETPP_COMMON_MD5_HPP
|
||||
@@ -68,8 +70,9 @@
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
/// Provides MD5 hashing functionality
|
||||
@@ -89,16 +92,17 @@ typedef struct md5_state_s {
|
||||
inline void md5_init(md5_state_t *pms);
|
||||
|
||||
/* Append a string to the message. */
|
||||
inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes);
|
||||
inline void md5_append(md5_state_t *pms, md5_byte_t const *data, size_t nbytes);
|
||||
|
||||
/* Finish the message and return the digest. */
|
||||
inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
|
||||
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown \
|
||||
*/
|
||||
#ifdef ARCH_IS_BIG_ENDIAN
|
||||
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#else
|
||||
# define ZSW_MD5_BYTE_ORDER 0
|
||||
#define ZSW_MD5_BYTE_ORDER 0
|
||||
#endif
|
||||
|
||||
#define ZSW_MD5_T_MASK ((md5_word_t)~0)
|
||||
@@ -167,10 +171,9 @@ inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
#define ZSW_MD5_T63 0x2ad7d2bb
|
||||
#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e)
|
||||
|
||||
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
static void md5_process(md5_state_t *pms, md5_byte_t const *data /*[64]*/) {
|
||||
md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2],
|
||||
d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if ZSW_MD5_BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
@@ -178,7 +181,7 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
#else
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
md5_word_t xbuf[16];
|
||||
md5_word_t const * X;
|
||||
md5_word_t const *X;
|
||||
#endif
|
||||
|
||||
{
|
||||
@@ -220,11 +223,11 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if ZSW_MD5_BYTE_ORDER == 0
|
||||
#if ZSW_MD5_BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
#else
|
||||
#define xbuf X /* (static only) */
|
||||
#endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
@@ -237,8 +240,8 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + ZSW_MD5_F(b, c, d) + X[k] + Ti; \
|
||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
|
||||
@@ -263,8 +266,8 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + ZSW_MD5_G(b, c, d) + X[k] + Ti; \
|
||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
|
||||
@@ -289,8 +292,8 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + ZSW_MD5_H(b, c, d) + X[k] + Ti; \
|
||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
|
||||
@@ -315,8 +318,8 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + ZSW_MD5_I(b, c, d) + X[k] + Ti; \
|
||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
|
||||
@@ -354,49 +357,42 @@ void md5_init(md5_state_t *pms) {
|
||||
pms->abcd[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) {
|
||||
md5_byte_t const * p = data;
|
||||
void md5_append(md5_state_t *pms, md5_byte_t const *data, size_t nbytes) {
|
||||
md5_byte_t const *p = data;
|
||||
size_t left = nbytes;
|
||||
int offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
if (nbytes <= 0) return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
if (pms->count[0] < nbits) pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
|
||||
|
||||
std::memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
if (offset + copy < 64) return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
for (; left >= 64; p += 64, left -= 64) md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
std::memcpy(pms->buf, p, left);
|
||||
if (left) std::memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
|
||||
static md5_byte_t const pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
@@ -412,7 +408,7 @@ void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
|
||||
}
|
||||
|
||||
// some convenience c++ functions
|
||||
inline std::string md5_hash_string(std::string const & s) {
|
||||
inline std::string md5_hash_string(std::string const &s) {
|
||||
char digest[16];
|
||||
|
||||
md5_state_t state;
|
||||
@@ -423,14 +419,15 @@ inline std::string md5_hash_string(std::string const & s) {
|
||||
|
||||
std::string ret;
|
||||
ret.resize(16);
|
||||
std::copy(digest,digest+16,ret.begin());
|
||||
std::copy(digest, digest + 16, ret.begin());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
inline std::string md5_hash_hex(std::string const & input) {
|
||||
inline std::string md5_hash_hex(std::string const &input) {
|
||||
std::string hash = md5_hash_string(input);
|
||||
std::string hex;
|
||||
|
||||
@@ -442,7 +439,8 @@ inline std::string md5_hash_hex(std::string const & input) {
|
||||
return hex;
|
||||
}
|
||||
|
||||
} // md5
|
||||
} // websocketpp
|
||||
} // namespace md5
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_MD5_HPP
|
||||
#pragma warning(pop)
|
||||
231
thirdparty/websocketpp/include/websocketpp/frame.hpp
vendored
231
thirdparty/websocketpp/include/websocketpp/frame.hpp
vendored
@@ -24,16 +24,17 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127)
|
||||
#pragma warning(disable : 4267)
|
||||
|
||||
#ifndef WEBSOCKETPP_FRAME_HPP
|
||||
#define WEBSOCKETPP_FRAME_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/common/network.hpp>
|
||||
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/utilities.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
@@ -74,7 +75,7 @@ union uint64_converter {
|
||||
* WebSocket Opcodes are 4 bits. See RFC6455 section 5.2.
|
||||
*/
|
||||
namespace opcode {
|
||||
enum value {
|
||||
enum value {
|
||||
continuation = 0x0,
|
||||
text = 0x1,
|
||||
binary = 0x2,
|
||||
@@ -108,67 +109,61 @@ namespace opcode {
|
||||
CONTROL_RSVD = 0xD,
|
||||
CONTROL_RSVE = 0xE,
|
||||
CONTROL_RSVF = 0xF
|
||||
};
|
||||
};
|
||||
|
||||
/// Check if an opcode is reserved
|
||||
/**
|
||||
/// Check if an opcode is reserved
|
||||
/**
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is reserved.
|
||||
*/
|
||||
inline bool reserved(value v) {
|
||||
return (v >= rsv3 && v <= rsv7) ||
|
||||
(v >= control_rsvb && v <= control_rsvf);
|
||||
}
|
||||
inline bool reserved(value v) {
|
||||
return (v >= rsv3 && v <= rsv7) || (v >= control_rsvb && v <= control_rsvf);
|
||||
}
|
||||
|
||||
/// Check if an opcode is invalid
|
||||
/**
|
||||
/// Check if an opcode is invalid
|
||||
/**
|
||||
* Invalid opcodes are negative or require greater than 4 bits to store.
|
||||
*
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is invalid.
|
||||
*/
|
||||
inline bool invalid(value v) {
|
||||
return (v > 0xF || v < 0);
|
||||
}
|
||||
inline bool invalid(value v) { return (v > 0xF || v < 0); }
|
||||
|
||||
/// Check if an opcode is for a control frame
|
||||
/**
|
||||
/// Check if an opcode is for a control frame
|
||||
/**
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is a control opcode.
|
||||
*/
|
||||
inline bool is_control(value v) {
|
||||
return v >= 0x8;
|
||||
}
|
||||
}
|
||||
inline bool is_control(value v) { return v >= 0x8; }
|
||||
} // namespace opcode
|
||||
|
||||
/// Constants related to frame and payload limits
|
||||
namespace limits {
|
||||
/// Minimum length of a WebSocket frame header.
|
||||
static unsigned int const basic_header_length = 2;
|
||||
/// Minimum length of a WebSocket frame header.
|
||||
static unsigned int const basic_header_length = 2;
|
||||
|
||||
/// Maximum length of a WebSocket header
|
||||
static unsigned int const max_header_length = 14;
|
||||
/// Maximum length of a WebSocket header
|
||||
static unsigned int const max_header_length = 14;
|
||||
|
||||
/// Maximum length of the variable portion of the WebSocket header
|
||||
static unsigned int const max_extended_header_length = 12;
|
||||
/// Maximum length of the variable portion of the WebSocket header
|
||||
static unsigned int const max_extended_header_length = 12;
|
||||
|
||||
/// Maximum size of a basic WebSocket payload
|
||||
static uint8_t const payload_size_basic = 125;
|
||||
/// Maximum size of a basic WebSocket payload
|
||||
static uint8_t const payload_size_basic = 125;
|
||||
|
||||
/// Maximum size of an extended WebSocket payload (basic payload = 126)
|
||||
static uint16_t const payload_size_extended = 0xFFFF; // 2^16, 65535
|
||||
/// Maximum size of an extended WebSocket payload (basic payload = 126)
|
||||
static uint16_t const payload_size_extended = 0xFFFF; // 2^16, 65535
|
||||
|
||||
/// Maximum size of a jumbo WebSocket payload (basic payload = 127)
|
||||
static uint64_t const payload_size_jumbo = 0x7FFFFFFFFFFFFFFFLL;//2^63
|
||||
/// Maximum size of a jumbo WebSocket payload (basic payload = 127)
|
||||
static uint64_t const payload_size_jumbo = 0x7FFFFFFFFFFFFFFFLL; // 2^63
|
||||
|
||||
/// Maximum size of close frame reason
|
||||
/**
|
||||
/// Maximum size of close frame reason
|
||||
/**
|
||||
* This is payload_size_basic - 2 bytes (as first two bytes are used for
|
||||
* the close code
|
||||
*/
|
||||
static uint8_t const close_reason_size = 123;
|
||||
}
|
||||
|
||||
static uint8_t const close_reason_size = 123;
|
||||
} // namespace limits
|
||||
|
||||
// masks for fields in the basic header
|
||||
static uint8_t const BHB0_OPCODE = 0x0F;
|
||||
@@ -187,14 +182,13 @@ typedef uint32_converter masking_key_type;
|
||||
|
||||
/// The constant size component of a WebSocket frame header
|
||||
struct basic_header {
|
||||
basic_header() : b0(0x00),b1(0x00) {}
|
||||
basic_header() : b0(0x00), b1(0x00) {}
|
||||
|
||||
basic_header(uint8_t p0, uint8_t p1) : b0(p0), b1(p1) {}
|
||||
|
||||
basic_header(opcode::value op, uint64_t size, bool fin, bool mask,
|
||||
bool rsv1 = false, bool rsv2 = false, bool rsv3 = false) : b0(0x00),
|
||||
b1(0x00)
|
||||
{
|
||||
bool rsv1 = false, bool rsv2 = false, bool rsv3 = false)
|
||||
: b0(0x00), b1(0x00) {
|
||||
if (fin) {
|
||||
b0 |= BHB0_FIN;
|
||||
}
|
||||
@@ -223,7 +217,6 @@ struct basic_header {
|
||||
basic_value = payload_size_code_64bit;
|
||||
}
|
||||
|
||||
|
||||
b1 |= basic_value;
|
||||
}
|
||||
|
||||
@@ -234,17 +227,17 @@ struct basic_header {
|
||||
/// The variable size component of a WebSocket frame header
|
||||
struct extended_header {
|
||||
extended_header() {
|
||||
std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
|
||||
std::fill_n(this->bytes, MAX_EXTENDED_HEADER_LENGTH, 0x00);
|
||||
}
|
||||
|
||||
extended_header(uint64_t payload_size) {
|
||||
std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
|
||||
std::fill_n(this->bytes, MAX_EXTENDED_HEADER_LENGTH, 0x00);
|
||||
|
||||
copy_payload(payload_size);
|
||||
}
|
||||
|
||||
extended_header(uint64_t payload_size, uint32_t masking_key) {
|
||||
std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
|
||||
std::fill_n(this->bytes, MAX_EXTENDED_HEADER_LENGTH, 0x00);
|
||||
|
||||
// Copy payload size
|
||||
int offset = copy_payload(payload_size);
|
||||
@@ -252,11 +245,12 @@ struct extended_header {
|
||||
// Copy Masking Key
|
||||
uint32_converter temp32;
|
||||
temp32.i = masking_key;
|
||||
std::copy(temp32.c,temp32.c+4,bytes+offset);
|
||||
std::copy(temp32.c, temp32.c + 4, bytes + offset);
|
||||
}
|
||||
|
||||
uint8_t bytes[MAX_EXTENDED_HEADER_LENGTH];
|
||||
private:
|
||||
|
||||
private:
|
||||
int copy_payload(uint64_t payload_size) {
|
||||
int payload_offset = 0;
|
||||
|
||||
@@ -268,9 +262,9 @@ private:
|
||||
|
||||
uint64_converter temp64;
|
||||
temp64.i = lib::net::_htonll(payload_size);
|
||||
std::copy(temp64.c+payload_offset,temp64.c+8,bytes);
|
||||
std::copy(temp64.c + payload_offset, temp64.c + 8, bytes);
|
||||
|
||||
return 8-payload_offset;
|
||||
return 8 - payload_offset;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -295,30 +289,29 @@ uint16_t get_extended_size(extended_header const &);
|
||||
uint64_t get_jumbo_size(extended_header const &);
|
||||
uint64_t get_payload_size(basic_header const &, extended_header const &);
|
||||
|
||||
size_t prepare_masking_key(masking_key_type const & key);
|
||||
size_t prepare_masking_key(masking_key_type const &key);
|
||||
size_t circshift_prepared_key(size_t prepared_key, size_t offset);
|
||||
|
||||
// Functions for performing xor based masking and unmasking
|
||||
template <typename input_iter, typename output_iter>
|
||||
void byte_mask(input_iter b, input_iter e, output_iter o, masking_key_type
|
||||
const & key, size_t key_offset = 0);
|
||||
void byte_mask(input_iter b, input_iter e, output_iter o,
|
||||
masking_key_type const &key, size_t key_offset = 0);
|
||||
template <typename iter_type>
|
||||
void byte_mask(iter_type b, iter_type e, masking_key_type const & key,
|
||||
void byte_mask(iter_type b, iter_type e, masking_key_type const &key,
|
||||
size_t key_offset = 0);
|
||||
void word_mask_exact(uint8_t * input, uint8_t * output, size_t length,
|
||||
masking_key_type const & key);
|
||||
void word_mask_exact(uint8_t * data, size_t length, masking_key_type const &
|
||||
key);
|
||||
size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
void word_mask_exact(uint8_t *input, uint8_t *output, size_t length,
|
||||
masking_key_type const &key);
|
||||
void word_mask_exact(uint8_t *data, size_t length, masking_key_type const &key);
|
||||
size_t word_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||
size_t prepared_key);
|
||||
size_t word_mask_circ(uint8_t * data, size_t length, size_t prepared_key);
|
||||
size_t word_mask_circ(uint8_t *data, size_t length, size_t prepared_key);
|
||||
|
||||
/// Check whether the frame's FIN bit is set.
|
||||
/**
|
||||
* @param [in] h The basic header to extract from.
|
||||
* @return True if the header's fin bit is set.
|
||||
*/
|
||||
inline bool get_fin(basic_header const & h) {
|
||||
inline bool get_fin(basic_header const &h) {
|
||||
return ((h.b0 & BHB0_FIN) == BHB0_FIN);
|
||||
}
|
||||
|
||||
@@ -327,7 +320,7 @@ inline bool get_fin(basic_header const & h) {
|
||||
* @param [out] h Header to set.
|
||||
* @param [in] value Value to set it to.
|
||||
*/
|
||||
inline void set_fin(basic_header & h, bool value) {
|
||||
inline void set_fin(basic_header &h, bool value) {
|
||||
h.b0 = (value ? h.b0 | BHB0_FIN : h.b0 & ~BHB0_FIN);
|
||||
}
|
||||
|
||||
@@ -399,7 +392,7 @@ inline opcode::value get_opcode(const basic_header &h) {
|
||||
* @param [in] h The basic header to extract from.
|
||||
* @return True if the header mask bit is set.
|
||||
*/
|
||||
inline bool get_masked(basic_header const & h) {
|
||||
inline bool get_masked(basic_header const &h) {
|
||||
return ((h.b1 & BHB1_MASK) == BHB1_MASK);
|
||||
}
|
||||
|
||||
@@ -408,7 +401,7 @@ inline bool get_masked(basic_header const & h) {
|
||||
* @param [out] h Header to set.
|
||||
* @param value Value to set it to.
|
||||
*/
|
||||
inline void set_masked(basic_header & h, bool value) {
|
||||
inline void set_masked(basic_header &h, bool value) {
|
||||
h.b1 = (value ? h.b1 | BHB1_MASK : h.b1 & ~BHB1_MASK);
|
||||
}
|
||||
|
||||
@@ -442,7 +435,7 @@ inline uint8_t get_basic_size(const basic_header &h) {
|
||||
* @param h Basic frame header to extract size from.
|
||||
* @return Full length of the extended header.
|
||||
*/
|
||||
inline size_t get_header_len(basic_header const & h) {
|
||||
inline size_t get_header_len(basic_header const &h) {
|
||||
// TODO: check extensions?
|
||||
|
||||
// masking key offset represents the space used for the extended length
|
||||
@@ -486,17 +479,14 @@ inline unsigned int get_masking_key_offset(const basic_header &h) {
|
||||
*
|
||||
* @return A contiguous string containing h and e
|
||||
*/
|
||||
inline std::string prepare_header(const basic_header &h, const
|
||||
extended_header &e)
|
||||
{
|
||||
inline std::string prepare_header(const basic_header &h,
|
||||
const extended_header &e) {
|
||||
std::string ret;
|
||||
|
||||
ret.push_back(char(h.b0));
|
||||
ret.push_back(char(h.b1));
|
||||
ret.append(
|
||||
reinterpret_cast<const char*>(e.bytes),
|
||||
get_header_len(h)-BASIC_HEADER_LENGTH
|
||||
);
|
||||
ret.append(reinterpret_cast<const char *>(e.bytes),
|
||||
get_header_len(h) - BASIC_HEADER_LENGTH);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -513,16 +503,15 @@ inline std::string prepare_header(const basic_header &h, const
|
||||
*
|
||||
* @return The masking key as an integer.
|
||||
*/
|
||||
inline masking_key_type get_masking_key(const basic_header &h, const
|
||||
extended_header &e)
|
||||
{
|
||||
inline masking_key_type get_masking_key(const basic_header &h,
|
||||
const extended_header &e) {
|
||||
masking_key_type temp32;
|
||||
|
||||
if (!get_masked(h)) {
|
||||
temp32.i = 0;
|
||||
} else {
|
||||
unsigned int offset = get_masking_key_offset(h);
|
||||
std::copy(e.bytes+offset,e.bytes+offset+4,temp32.c);
|
||||
std::copy(e.bytes + offset, e.bytes + offset + 4, temp32.c);
|
||||
}
|
||||
|
||||
return temp32;
|
||||
@@ -539,7 +528,7 @@ inline masking_key_type get_masking_key(const basic_header &h, const
|
||||
*/
|
||||
inline uint16_t get_extended_size(const extended_header &e) {
|
||||
uint16_converter temp16;
|
||||
std::copy(e.bytes,e.bytes+2,temp16.c);
|
||||
std::copy(e.bytes, e.bytes + 2, temp16.c);
|
||||
return ntohs(temp16.i);
|
||||
}
|
||||
|
||||
@@ -554,7 +543,7 @@ inline uint16_t get_extended_size(const extended_header &e) {
|
||||
*/
|
||||
inline uint64_t get_jumbo_size(const extended_header &e) {
|
||||
uint64_converter temp64;
|
||||
std::copy(e.bytes,e.bytes+8,temp64.c);
|
||||
std::copy(e.bytes, e.bytes + 8, temp64.c);
|
||||
return lib::net::_ntohll(temp64.i);
|
||||
}
|
||||
|
||||
@@ -570,9 +559,8 @@ inline uint64_t get_jumbo_size(const extended_header &e) {
|
||||
*
|
||||
* @return The size encoded in the combined header in host byte order.
|
||||
*/
|
||||
inline uint64_t get_payload_size(const basic_header &h, const
|
||||
extended_header &e)
|
||||
{
|
||||
inline uint64_t get_payload_size(const basic_header &h,
|
||||
const extended_header &e) {
|
||||
uint8_t val = get_basic_size(h);
|
||||
|
||||
if (val <= limits::payload_size_basic) {
|
||||
@@ -592,7 +580,7 @@ inline uint64_t get_payload_size(const basic_header &h, const
|
||||
*
|
||||
* @return prepared key as a machine word
|
||||
*/
|
||||
inline size_t prepare_masking_key(const masking_key_type& key) {
|
||||
inline size_t prepare_masking_key(const masking_key_type &key) {
|
||||
size_t low_bits = static_cast<size_t>(key.i);
|
||||
|
||||
if (sizeof(size_t) == 8) {
|
||||
@@ -614,11 +602,11 @@ inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
|
||||
return prepared_key;
|
||||
}
|
||||
if (lib::net::is_little_endian()) {
|
||||
size_t temp = prepared_key << (sizeof(size_t)-offset)*8;
|
||||
return (prepared_key >> offset*8) | temp;
|
||||
size_t temp = prepared_key << (sizeof(size_t) - offset) * 8;
|
||||
return (prepared_key >> offset * 8) | temp;
|
||||
} else {
|
||||
size_t temp = prepared_key >> (sizeof(size_t)-offset)*8;
|
||||
return (prepared_key << offset*8) | temp;
|
||||
size_t temp = prepared_key >> (sizeof(size_t) - offset) * 8;
|
||||
return (prepared_key << offset * 8) | temp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,9 +631,8 @@ inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
|
||||
*/
|
||||
template <typename input_iter, typename output_iter>
|
||||
void byte_mask(input_iter first, input_iter last, output_iter result,
|
||||
masking_key_type const & key, size_t key_offset)
|
||||
{
|
||||
size_t key_index = key_offset%4;
|
||||
masking_key_type const &key, size_t key_offset) {
|
||||
size_t key_index = key_offset % 4;
|
||||
while (first != last) {
|
||||
*result = *first ^ key.c[key_index++];
|
||||
key_index %= 4;
|
||||
@@ -672,10 +659,9 @@ void byte_mask(input_iter first, input_iter last, output_iter result,
|
||||
* @param key_offset offset value to start masking at.
|
||||
*/
|
||||
template <typename iter_type>
|
||||
void byte_mask(iter_type b, iter_type e, masking_key_type const & key,
|
||||
size_t key_offset)
|
||||
{
|
||||
byte_mask(b,e,b,key,key_offset);
|
||||
void byte_mask(iter_type b, iter_type e, masking_key_type const &key,
|
||||
size_t key_offset) {
|
||||
byte_mask(b, e, b, key, key_offset);
|
||||
}
|
||||
|
||||
/// Exact word aligned mask/unmask
|
||||
@@ -699,20 +685,19 @@ void byte_mask(iter_type b, iter_type e, masking_key_type const & key,
|
||||
*
|
||||
* @param key Masking key to use
|
||||
*/
|
||||
inline void word_mask_exact(uint8_t* input, uint8_t* output, size_t length,
|
||||
const masking_key_type& key)
|
||||
{
|
||||
inline void word_mask_exact(uint8_t *input, uint8_t *output, size_t length,
|
||||
const masking_key_type &key) {
|
||||
size_t prepared_key = prepare_masking_key(key);
|
||||
size_t n = length/sizeof(size_t);
|
||||
size_t* input_word = reinterpret_cast<size_t*>(input);
|
||||
size_t* output_word = reinterpret_cast<size_t*>(output);
|
||||
size_t n = length / sizeof(size_t);
|
||||
size_t *input_word = reinterpret_cast<size_t *>(input);
|
||||
size_t *output_word = reinterpret_cast<size_t *>(output);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
output_word[i] = input_word[i] ^ prepared_key;
|
||||
}
|
||||
|
||||
for (size_t i = n*sizeof(size_t); i < length; i++) {
|
||||
output[i] = input[i] ^ key.c[i%4];
|
||||
for (size_t i = n * sizeof(size_t); i < length; i++) {
|
||||
output[i] = input[i] ^ key.c[i % 4];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,10 +713,9 @@ inline void word_mask_exact(uint8_t* input, uint8_t* output, size_t length,
|
||||
*
|
||||
* @param key Masking key to use
|
||||
*/
|
||||
inline void word_mask_exact(uint8_t* data, size_t length, const
|
||||
masking_key_type& key)
|
||||
{
|
||||
word_mask_exact(data,data,length,key);
|
||||
inline void word_mask_exact(uint8_t *data, size_t length,
|
||||
const masking_key_type &key) {
|
||||
word_mask_exact(data, data, length, key);
|
||||
}
|
||||
|
||||
/// Circular word aligned mask/unmask
|
||||
@@ -765,13 +749,12 @@ inline void word_mask_exact(uint8_t* data, size_t length, const
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
size_t prepared_key)
|
||||
{
|
||||
inline size_t word_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||
size_t prepared_key) {
|
||||
size_t n = length / sizeof(size_t); // whole words
|
||||
size_t l = length - (n * sizeof(size_t)); // remaining bytes
|
||||
size_t * input_word = reinterpret_cast<size_t *>(input);
|
||||
size_t * output_word = reinterpret_cast<size_t *>(output);
|
||||
size_t *input_word = reinterpret_cast<size_t *>(input);
|
||||
size_t *output_word = reinterpret_cast<size_t *>(output);
|
||||
|
||||
// mask word by word
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
@@ -780,12 +763,12 @@ inline size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
|
||||
// mask partial word at the end
|
||||
size_t start = length - l;
|
||||
uint8_t * byte_key = reinterpret_cast<uint8_t *>(&prepared_key);
|
||||
uint8_t *byte_key = reinterpret_cast<uint8_t *>(&prepared_key);
|
||||
for (size_t i = 0; i < l; ++i) {
|
||||
output[start+i] = input[start+i] ^ byte_key[i];
|
||||
output[start + i] = input[start + i] ^ byte_key[i];
|
||||
}
|
||||
|
||||
return circshift_prepared_key(prepared_key,l);
|
||||
return circshift_prepared_key(prepared_key, l);
|
||||
}
|
||||
|
||||
/// Circular word aligned mask/unmask (in place)
|
||||
@@ -802,8 +785,9 @@ inline size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key){
|
||||
return word_mask_circ(data,data,length,prepared_key);
|
||||
inline size_t word_mask_circ(uint8_t *data, size_t length,
|
||||
size_t prepared_key) {
|
||||
return word_mask_circ(data, data, length, prepared_key);
|
||||
}
|
||||
|
||||
/// Circular byte aligned mask/unmask
|
||||
@@ -827,9 +811,8 @@ inline size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key){
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t byte_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
size_t prepared_key)
|
||||
{
|
||||
inline size_t byte_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||
size_t prepared_key) {
|
||||
uint32_converter key;
|
||||
key.i = prepared_key;
|
||||
|
||||
@@ -837,7 +820,7 @@ inline size_t byte_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
output[i] = input[i] ^ key.c[i % 4];
|
||||
}
|
||||
|
||||
return circshift_prepared_key(prepared_key,length % 4);
|
||||
return circshift_prepared_key(prepared_key, length % 4);
|
||||
}
|
||||
|
||||
/// Circular byte aligned mask/unmask (in place)
|
||||
@@ -854,11 +837,13 @@ inline size_t byte_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t byte_mask_circ(uint8_t* data, size_t length, size_t prepared_key){
|
||||
return byte_mask_circ(data,data,length,prepared_key);
|
||||
inline size_t byte_mask_circ(uint8_t *data, size_t length,
|
||||
size_t prepared_key) {
|
||||
return byte_mask_circ(data, data, length, prepared_key);
|
||||
}
|
||||
|
||||
} // namespace frame
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif //WEBSOCKETPP_FRAME_HPP
|
||||
#endif // WEBSOCKETPP_FRAME_HPP
|
||||
#pragma warning(pop)
|
||||
@@ -24,27 +24,25 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127)
|
||||
|
||||
#ifndef WEBSOCKETPP_PROCESSOR_HYBI13_HPP
|
||||
#define WEBSOCKETPP_PROCESSOR_HYBI13_HPP
|
||||
|
||||
#include <websocketpp/processors/processor.hpp>
|
||||
|
||||
#include <websocketpp/frame.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
|
||||
#include <websocketpp/utf8_validator.hpp>
|
||||
#include <websocketpp/sha1/sha1.hpp>
|
||||
#include <websocketpp/base64/base64.hpp>
|
||||
|
||||
#include <websocketpp/common/network.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <websocketpp/base64/base64.hpp>
|
||||
#include <websocketpp/common/network.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
#include <websocketpp/frame.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
#include <websocketpp/processors/processor.hpp>
|
||||
#include <websocketpp/sha1/sha1.hpp>
|
||||
#include <websocketpp/utf8_validator.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace processor {
|
||||
@@ -52,7 +50,7 @@ namespace processor {
|
||||
/// Processor for Hybi version 13 (RFC6455)
|
||||
template <typename config>
|
||||
class hybi13 : public processor<config> {
|
||||
public:
|
||||
public:
|
||||
typedef processor<config> base;
|
||||
|
||||
typedef typename config::request_type request_type;
|
||||
@@ -67,29 +65,27 @@ public:
|
||||
|
||||
typedef typename config::permessage_deflate_type permessage_deflate_type;
|
||||
|
||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||
typedef std::pair<lib::error_code, std::string> err_str_pair;
|
||||
|
||||
explicit hybi13(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
|
||||
: processor<config>(secure, p_is_server)
|
||||
, m_msg_manager(manager)
|
||||
, m_rng(rng)
|
||||
{
|
||||
explicit hybi13(bool secure, bool p_is_server, msg_manager_ptr manager,
|
||||
rng_type& rng)
|
||||
: processor<config>(secure, p_is_server),
|
||||
m_msg_manager(manager),
|
||||
m_rng(rng) {
|
||||
reset_headers();
|
||||
}
|
||||
|
||||
int get_version() const {
|
||||
return 13;
|
||||
}
|
||||
int get_version() const { return 13; }
|
||||
|
||||
bool has_permessage_deflate() const {
|
||||
return m_permessage_deflate.is_implemented();
|
||||
}
|
||||
|
||||
err_str_pair negotiate_extensions(request_type const & request) {
|
||||
err_str_pair negotiate_extensions(request_type const& request) {
|
||||
return negotiate_extensions_helper(request);
|
||||
}
|
||||
|
||||
err_str_pair negotiate_extensions(response_type const & response) {
|
||||
err_str_pair negotiate_extensions(response_type const& response) {
|
||||
return negotiate_extensions_helper(response);
|
||||
}
|
||||
|
||||
@@ -99,7 +95,7 @@ public:
|
||||
* identical and I can't have virtual template methods.
|
||||
*/
|
||||
template <typename header_type>
|
||||
err_str_pair negotiate_extensions_helper(header_type const & header) {
|
||||
err_str_pair negotiate_extensions_helper(header_type const& header) {
|
||||
err_str_pair ret;
|
||||
|
||||
// Respect blanket disabling of all extensions and don't even parse
|
||||
@@ -111,7 +107,7 @@ public:
|
||||
|
||||
http::parameter_list p;
|
||||
|
||||
bool error = header.get_header_as_plist("Sec-WebSocket-Extensions",p);
|
||||
bool error = header.get_header_as_plist("Sec-WebSocket-Extensions", p);
|
||||
|
||||
if (error) {
|
||||
ret.first = make_error_code(error::extension_parse_error);
|
||||
@@ -182,7 +178,7 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
lib::error_code validate_handshake(request_type const & r) const {
|
||||
lib::error_code validate_handshake(request_type const& r) const {
|
||||
if (r.get_method() != "GET") {
|
||||
return make_error_code(error::invalid_http_method);
|
||||
}
|
||||
@@ -206,9 +202,9 @@ public:
|
||||
* generic struct if other user input parameters to the processed handshake
|
||||
* are found.
|
||||
*/
|
||||
lib::error_code process_handshake(request_type const & request,
|
||||
std::string const & subprotocol, response_type & response) const
|
||||
{
|
||||
lib::error_code process_handshake(request_type const& request,
|
||||
std::string const& subprotocol,
|
||||
response_type& response) const {
|
||||
std::string server_key = request.get_header("Sec-WebSocket-Key");
|
||||
|
||||
lib::error_code ec = process_handshake_key(server_key);
|
||||
@@ -217,12 +213,12 @@ public:
|
||||
return ec;
|
||||
}
|
||||
|
||||
response.replace_header("Sec-WebSocket-Accept",server_key);
|
||||
response.append_header("Upgrade",constants::upgrade_token);
|
||||
response.append_header("Connection",constants::connection_token);
|
||||
response.replace_header("Sec-WebSocket-Accept", server_key);
|
||||
response.append_header("Upgrade", constants::upgrade_token);
|
||||
response.append_header("Connection", constants::connection_token);
|
||||
|
||||
if (!subprotocol.empty()) {
|
||||
response.replace_header("Sec-WebSocket-Protocol",subprotocol);
|
||||
response.replace_header("Sec-WebSocket-Protocol", subprotocol);
|
||||
}
|
||||
|
||||
return lib::error_code();
|
||||
@@ -234,17 +230,17 @@ public:
|
||||
* @param [in] uri The uri being connected to
|
||||
* @param [in] subprotocols The list of subprotocols to request
|
||||
*/
|
||||
lib::error_code client_handshake_request(request_type & req, uri_ptr
|
||||
uri, std::vector<std::string> const & subprotocols) const
|
||||
{
|
||||
lib::error_code client_handshake_request(
|
||||
request_type& req, uri_ptr uri,
|
||||
std::vector<std::string> const& subprotocols) const {
|
||||
req.set_method("GET");
|
||||
req.set_uri(uri->get_resource());
|
||||
req.set_version("HTTP/1.1");
|
||||
|
||||
req.append_header("Upgrade","websocket");
|
||||
req.append_header("Connection","Upgrade");
|
||||
req.replace_header("Sec-WebSocket-Version","13");
|
||||
req.replace_header("Host",uri->get_host_port());
|
||||
req.append_header("Upgrade", "websocket");
|
||||
req.append_header("Connection", "Upgrade");
|
||||
req.replace_header("Sec-WebSocket-Version", "13");
|
||||
req.replace_header("Host", uri->get_host_port());
|
||||
|
||||
if (!subprotocols.empty()) {
|
||||
std::ostringstream result;
|
||||
@@ -254,7 +250,7 @@ public:
|
||||
result << ", " << *it++;
|
||||
}
|
||||
|
||||
req.replace_header("Sec-WebSocket-Protocol",result.str());
|
||||
req.replace_header("Sec-WebSocket-Protocol", result.str());
|
||||
}
|
||||
|
||||
// Generate handshake key
|
||||
@@ -263,15 +259,15 @@ public:
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
conv.i = m_rng();
|
||||
std::copy(conv.c,conv.c+4,&raw_key[i*4]);
|
||||
std::copy(conv.c, conv.c + 4, &raw_key[i * 4]);
|
||||
}
|
||||
|
||||
req.replace_header("Sec-WebSocket-Key",base64_encode(raw_key, 16));
|
||||
req.replace_header("Sec-WebSocket-Key", base64_encode(raw_key, 16));
|
||||
|
||||
if (m_permessage_deflate.is_implemented()) {
|
||||
std::string offer = m_permessage_deflate.generate_offer();
|
||||
if (!offer.empty()) {
|
||||
req.replace_header("Sec-WebSocket-Extensions",offer);
|
||||
req.replace_header("Sec-WebSocket-Extensions", offer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,27 +280,26 @@ public:
|
||||
* @param res The reponse to generate
|
||||
* @return An error code, 0 on success, non-zero for other errors
|
||||
*/
|
||||
lib::error_code validate_server_handshake_response(request_type const & req,
|
||||
response_type& res) const
|
||||
{
|
||||
lib::error_code validate_server_handshake_response(request_type const& req,
|
||||
response_type& res) const {
|
||||
// A valid response has an HTTP 101 switching protocols code
|
||||
if (res.get_status_code() != http::status_code::switching_protocols) {
|
||||
return error::make_error_code(error::invalid_http_status);
|
||||
}
|
||||
|
||||
// And the upgrade token in an upgrade header
|
||||
std::string const & upgrade_header = res.get_header("Upgrade");
|
||||
std::string const& upgrade_header = res.get_header("Upgrade");
|
||||
if (utility::ci_find_substr(upgrade_header, constants::upgrade_token,
|
||||
sizeof(constants::upgrade_token)-1) == upgrade_header.end())
|
||||
{
|
||||
sizeof(constants::upgrade_token) - 1) ==
|
||||
upgrade_header.end()) {
|
||||
return error::make_error_code(error::missing_required_header);
|
||||
}
|
||||
|
||||
// And the websocket token in the connection header
|
||||
std::string const & con_header = res.get_header("Connection");
|
||||
std::string const& con_header = res.get_header("Connection");
|
||||
if (utility::ci_find_substr(con_header, constants::connection_token,
|
||||
sizeof(constants::connection_token)-1) == con_header.end())
|
||||
{
|
||||
sizeof(constants::connection_token) - 1) ==
|
||||
con_header.end()) {
|
||||
return error::make_error_code(error::missing_required_header);
|
||||
}
|
||||
|
||||
@@ -321,21 +316,18 @@ public:
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
std::string get_raw(response_type const & res) const {
|
||||
return res.raw();
|
||||
}
|
||||
std::string get_raw(response_type const& res) const { return res.raw(); }
|
||||
|
||||
std::string const & get_origin(request_type const & r) const {
|
||||
std::string const& get_origin(request_type const& r) const {
|
||||
return r.get_header("Origin");
|
||||
}
|
||||
|
||||
lib::error_code extract_subprotocols(request_type const & req,
|
||||
std::vector<std::string> & subprotocol_list)
|
||||
{
|
||||
lib::error_code extract_subprotocols(
|
||||
request_type const& req, std::vector<std::string>& subprotocol_list) {
|
||||
if (!req.get_header("Sec-WebSocket-Protocol").empty()) {
|
||||
http::parameter_list p;
|
||||
|
||||
if (!req.get_header_as_plist("Sec-WebSocket-Protocol",p)) {
|
||||
if (!req.get_header_as_plist("Sec-WebSocket-Protocol", p)) {
|
||||
http::parameter_list::const_iterator it;
|
||||
|
||||
for (it = p.begin(); it != p.end(); ++it) {
|
||||
@@ -348,8 +340,8 @@ public:
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
uri_ptr get_uri(request_type const & request) const {
|
||||
return get_uri_from_host(request,(base::m_secure ? "wss" : "ws"));
|
||||
uri_ptr get_uri(request_type const& request) const {
|
||||
return get_uri_from_host(request, (base::m_secure ? "wss" : "ws"));
|
||||
}
|
||||
|
||||
/// Process new websocket connection bytes
|
||||
@@ -379,47 +371,51 @@ public:
|
||||
*
|
||||
* @return Number of bytes processed or zero on error
|
||||
*/
|
||||
size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) {
|
||||
size_t consume(uint8_t* buf, size_t len, lib::error_code& ec) {
|
||||
size_t p = 0;
|
||||
|
||||
ec = lib::error_code();
|
||||
|
||||
//std::cout << "consume: " << utility::to_hex(buf,len) << std::endl;
|
||||
// std::cout << "consume: " << utility::to_hex(buf,len) << std::endl;
|
||||
|
||||
// Loop while we don't have a message ready and we still have bytes
|
||||
// left to process.
|
||||
while (m_state != READY && m_state != FATAL_ERROR &&
|
||||
(p < len || m_bytes_needed == 0))
|
||||
{
|
||||
(p < len || m_bytes_needed == 0)) {
|
||||
if (m_state == HEADER_BASIC) {
|
||||
p += this->copy_basic_header_bytes(buf+p,len-p);
|
||||
p += this->copy_basic_header_bytes(buf + p, len - p);
|
||||
|
||||
if (m_bytes_needed > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ec = this->validate_incoming_basic_header(
|
||||
m_basic_header, base::m_server, !m_data_msg.msg_ptr
|
||||
);
|
||||
if (ec) {break;}
|
||||
m_basic_header, base::m_server, !m_data_msg.msg_ptr);
|
||||
if (ec) {
|
||||
break;
|
||||
}
|
||||
|
||||
// extract full header size and adjust consume state accordingly
|
||||
m_state = HEADER_EXTENDED;
|
||||
m_cursor = 0;
|
||||
m_bytes_needed = frame::get_header_len(m_basic_header) -
|
||||
frame::BASIC_HEADER_LENGTH;
|
||||
m_bytes_needed =
|
||||
frame::get_header_len(m_basic_header) - frame::BASIC_HEADER_LENGTH;
|
||||
} else if (m_state == HEADER_EXTENDED) {
|
||||
p += this->copy_extended_header_bytes(buf+p,len-p);
|
||||
p += this->copy_extended_header_bytes(buf + p, len - p);
|
||||
|
||||
if (m_bytes_needed > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ec = validate_incoming_extended_header(m_basic_header,m_extended_header);
|
||||
if (ec){break;}
|
||||
ec = validate_incoming_extended_header(m_basic_header,
|
||||
m_extended_header);
|
||||
if (ec) {
|
||||
break;
|
||||
}
|
||||
|
||||
m_state = APPLICATION;
|
||||
m_bytes_needed = static_cast<size_t>(get_payload_size(m_basic_header,m_extended_header));
|
||||
m_bytes_needed = static_cast<size_t>(
|
||||
get_payload_size(m_basic_header, m_extended_header));
|
||||
|
||||
// check if this frame is the start of a new message and set up
|
||||
// the appropriate message metadata.
|
||||
@@ -429,9 +425,8 @@ public:
|
||||
|
||||
if (frame::opcode::is_control(op)) {
|
||||
m_control_msg = msg_metadata(
|
||||
m_msg_manager->get_message(op,m_bytes_needed),
|
||||
frame::get_masking_key(m_basic_header,m_extended_header)
|
||||
);
|
||||
m_msg_manager->get_message(op, m_bytes_needed),
|
||||
frame::get_masking_key(m_basic_header, m_extended_header));
|
||||
|
||||
m_current_msg = &m_control_msg;
|
||||
} else {
|
||||
@@ -442,17 +437,17 @@ public:
|
||||
}
|
||||
|
||||
m_data_msg = msg_metadata(
|
||||
m_msg_manager->get_message(op,m_bytes_needed),
|
||||
frame::get_masking_key(m_basic_header,m_extended_header)
|
||||
);
|
||||
m_msg_manager->get_message(op, m_bytes_needed),
|
||||
frame::get_masking_key(m_basic_header, m_extended_header));
|
||||
|
||||
if (m_permessage_deflate.is_enabled()) {
|
||||
m_data_msg.msg_ptr->set_compressed(frame::get_rsv1(m_basic_header));
|
||||
m_data_msg.msg_ptr->set_compressed(
|
||||
frame::get_rsv1(m_basic_header));
|
||||
}
|
||||
} else {
|
||||
// Fetch the underlying payload buffer from the data message we
|
||||
// are writing into.
|
||||
std::string & out = m_data_msg.msg_ptr->get_raw_payload();
|
||||
std::string& out = m_data_msg.msg_ptr->get_raw_payload();
|
||||
|
||||
if (out.size() + m_bytes_needed > base::m_max_message_size) {
|
||||
ec = make_error_code(error::message_too_big);
|
||||
@@ -462,11 +457,7 @@ public:
|
||||
// Each frame starts a new masking key. All other state
|
||||
// remains between frames.
|
||||
m_data_msg.prepared_key = prepare_masking_key(
|
||||
frame::get_masking_key(
|
||||
m_basic_header,
|
||||
m_extended_header
|
||||
)
|
||||
);
|
||||
frame::get_masking_key(m_basic_header, m_extended_header));
|
||||
|
||||
out.reserve(out.size() + m_bytes_needed);
|
||||
}
|
||||
@@ -475,12 +466,14 @@ public:
|
||||
} else if (m_state == EXTENSION) {
|
||||
m_state = APPLICATION;
|
||||
} else if (m_state == APPLICATION) {
|
||||
size_t bytes_to_process = (std::min)(m_bytes_needed,len-p);
|
||||
size_t bytes_to_process = (std::min)(m_bytes_needed, len - p);
|
||||
|
||||
if (bytes_to_process > 0) {
|
||||
p += this->process_payload_bytes(buf+p,bytes_to_process,ec);
|
||||
p += this->process_payload_bytes(buf + p, bytes_to_process, ec);
|
||||
|
||||
if (ec) {break;}
|
||||
if (ec) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bytes_needed > 0) {
|
||||
@@ -516,18 +509,17 @@ public:
|
||||
* @return A code indicating errors, if any
|
||||
*/
|
||||
lib::error_code finalize_message() {
|
||||
std::string & out = m_current_msg->msg_ptr->get_raw_payload();
|
||||
std::string& out = m_current_msg->msg_ptr->get_raw_payload();
|
||||
|
||||
// if the frame is compressed, append the compression
|
||||
// trailer and flush the compression buffer.
|
||||
if (m_permessage_deflate.is_enabled()
|
||||
&& m_current_msg->msg_ptr->get_compressed())
|
||||
{
|
||||
if (m_permessage_deflate.is_enabled() &&
|
||||
m_current_msg->msg_ptr->get_compressed()) {
|
||||
uint8_t trailer[4] = {0x00, 0x00, 0xff, 0xff};
|
||||
|
||||
// Decompress current buffer into the message buffer
|
||||
lib::error_code ec;
|
||||
ec = m_permessage_deflate.decompress(trailer,4,out);
|
||||
ec = m_permessage_deflate.decompress(trailer, 4, out);
|
||||
if (ec) {
|
||||
return ec;
|
||||
}
|
||||
@@ -552,17 +544,12 @@ public:
|
||||
m_basic_header.b0 = 0x00;
|
||||
m_basic_header.b1 = 0x00;
|
||||
|
||||
std::fill_n(
|
||||
m_extended_header.bytes,
|
||||
frame::MAX_EXTENDED_HEADER_LENGTH,
|
||||
0x00
|
||||
);
|
||||
std::fill_n(m_extended_header.bytes, frame::MAX_EXTENDED_HEADER_LENGTH,
|
||||
0x00);
|
||||
}
|
||||
|
||||
/// Test whether or not the processor has a message ready
|
||||
bool ready() const {
|
||||
return (m_state == READY);
|
||||
}
|
||||
bool ready() const { return (m_state == READY); }
|
||||
|
||||
message_ptr get_message() {
|
||||
if (!ready()) {
|
||||
@@ -583,13 +570,9 @@ public:
|
||||
}
|
||||
|
||||
/// Test whether or not the processor is in a fatal error state.
|
||||
bool get_error() const {
|
||||
return m_state == FATAL_ERROR;
|
||||
}
|
||||
bool get_error() const { return m_state == FATAL_ERROR; }
|
||||
|
||||
size_t get_bytes_needed() const {
|
||||
return m_bytes_needed;
|
||||
}
|
||||
size_t get_bytes_needed() const { return m_bytes_needed; }
|
||||
|
||||
/// Prepare a user data message for writing
|
||||
/**
|
||||
@@ -602,8 +585,7 @@ public:
|
||||
* @param out A message to be overwritten with the prepared message
|
||||
* @return error code
|
||||
*/
|
||||
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out)
|
||||
{
|
||||
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) {
|
||||
if (!in || !out) {
|
||||
return make_error_code(error::invalid_arguments);
|
||||
}
|
||||
@@ -625,8 +607,7 @@ public:
|
||||
|
||||
frame::masking_key_type key;
|
||||
bool masked = !base::m_server;
|
||||
bool compressed = m_permessage_deflate.is_enabled()
|
||||
&& in->get_compressed();
|
||||
bool compressed = m_permessage_deflate.is_enabled() && in->get_compressed();
|
||||
bool fin = in->get_fin();
|
||||
|
||||
if (masked) {
|
||||
@@ -639,7 +620,7 @@ public:
|
||||
// prepare payload
|
||||
if (compressed) {
|
||||
// compress and store in o after header.
|
||||
m_permessage_deflate.compress(i,o);
|
||||
m_permessage_deflate.compress(i, o);
|
||||
|
||||
if (o.size() < 4) {
|
||||
return make_error_code(error::general);
|
||||
@@ -647,11 +628,11 @@ public:
|
||||
|
||||
// Strip trailing 4 0x00 0x00 0xff 0xff bytes before writing to the
|
||||
// wire
|
||||
o.resize(o.size()-4);
|
||||
o.resize(o.size() - 4);
|
||||
|
||||
// mask in place if necessary
|
||||
if (masked) {
|
||||
this->masked_copy(o,o,key);
|
||||
this->masked_copy(o, o, key);
|
||||
}
|
||||
} else {
|
||||
// no compression, just copy data into the output buffer
|
||||
@@ -661,21 +642,21 @@ public:
|
||||
// buffer directly to avoid another copy. If not masked, copy
|
||||
// directly without masking.
|
||||
if (masked) {
|
||||
this->masked_copy(i,o,key);
|
||||
this->masked_copy(i, o, key);
|
||||
} else {
|
||||
std::copy(i.begin(),i.end(),o.begin());
|
||||
std::copy(i.begin(), i.end(), o.begin());
|
||||
}
|
||||
}
|
||||
|
||||
// generate header
|
||||
frame::basic_header h(op,o.size(),fin,masked,compressed);
|
||||
frame::basic_header h(op, o.size(), fin, masked, compressed);
|
||||
|
||||
if (masked) {
|
||||
frame::extended_header e(o.size(),key.i);
|
||||
out->set_header(frame::prepare_header(h,e));
|
||||
frame::extended_header e(o.size(), key.i);
|
||||
out->set_header(frame::prepare_header(h, e));
|
||||
} else {
|
||||
frame::extended_header e(o.size());
|
||||
out->set_header(frame::prepare_header(h,e));
|
||||
out->set_header(frame::prepare_header(h, e));
|
||||
}
|
||||
|
||||
out->set_prepared(true);
|
||||
@@ -685,17 +666,17 @@ public:
|
||||
}
|
||||
|
||||
/// Get URI
|
||||
lib::error_code prepare_ping(std::string const & in, message_ptr out) const {
|
||||
return this->prepare_control(frame::opcode::PING,in,out);
|
||||
lib::error_code prepare_ping(std::string const& in, message_ptr out) const {
|
||||
return this->prepare_control(frame::opcode::PING, in, out);
|
||||
}
|
||||
|
||||
lib::error_code prepare_pong(std::string const & in, message_ptr out) const {
|
||||
return this->prepare_control(frame::opcode::PONG,in,out);
|
||||
lib::error_code prepare_pong(std::string const& in, message_ptr out) const {
|
||||
return this->prepare_control(frame::opcode::PONG, in, out);
|
||||
}
|
||||
|
||||
virtual lib::error_code prepare_close(close::status::value code,
|
||||
std::string const & reason, message_ptr out) const
|
||||
{
|
||||
std::string const& reason,
|
||||
message_ptr out) const {
|
||||
if (close::status::reserved(code)) {
|
||||
return make_error_code(error::reserved_close_code);
|
||||
}
|
||||
@@ -708,7 +689,7 @@ public:
|
||||
return make_error_code(error::reason_requires_code);
|
||||
}
|
||||
|
||||
if (reason.size() > frame:: limits::payload_size_basic-2) {
|
||||
if (reason.size() > frame::limits::payload_size_basic - 2) {
|
||||
return make_error_code(error::control_too_big);
|
||||
}
|
||||
|
||||
@@ -718,30 +699,31 @@ public:
|
||||
close::code_converter val;
|
||||
val.i = htons(code);
|
||||
|
||||
payload.resize(reason.size()+2);
|
||||
payload.resize(reason.size() + 2);
|
||||
|
||||
payload[0] = val.c[0];
|
||||
payload[1] = val.c[1];
|
||||
|
||||
std::copy(reason.begin(),reason.end(),payload.begin()+2);
|
||||
std::copy(reason.begin(), reason.end(), payload.begin() + 2);
|
||||
}
|
||||
|
||||
return this->prepare_control(frame::opcode::CLOSE,payload,out);
|
||||
return this->prepare_control(frame::opcode::CLOSE, payload, out);
|
||||
}
|
||||
protected:
|
||||
|
||||
protected:
|
||||
/// Convert a client handshake key into a server response key in place
|
||||
lib::error_code process_handshake_key(std::string & key) const {
|
||||
lib::error_code process_handshake_key(std::string& key) const {
|
||||
key.append(constants::handshake_guid);
|
||||
|
||||
unsigned char message_digest[20];
|
||||
sha1::calc(key.c_str(),key.length(),message_digest);
|
||||
key = base64_encode(message_digest,20);
|
||||
sha1::calc(key.c_str(), key.length(), message_digest);
|
||||
key = base64_encode(message_digest, 20);
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
/// Reads bytes from buf into m_basic_header
|
||||
size_t copy_basic_header_bytes(uint8_t const * buf, size_t len) {
|
||||
size_t copy_basic_header_bytes(uint8_t const* buf, size_t len) {
|
||||
if (len == 0 || m_bytes_needed == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -773,10 +755,10 @@ protected:
|
||||
}
|
||||
|
||||
/// Reads bytes from buf into m_extended_header
|
||||
size_t copy_extended_header_bytes(uint8_t const * buf, size_t len) {
|
||||
size_t bytes_to_read = (std::min)(m_bytes_needed,len);
|
||||
size_t copy_extended_header_bytes(uint8_t const* buf, size_t len) {
|
||||
size_t bytes_to_read = (std::min)(m_bytes_needed, len);
|
||||
|
||||
std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor);
|
||||
std::copy(buf, buf + bytes_to_read, m_extended_header.bytes + m_cursor);
|
||||
m_cursor += bytes_to_read;
|
||||
m_bytes_needed -= bytes_to_read;
|
||||
|
||||
@@ -796,35 +778,33 @@ protected:
|
||||
* @param len Length of buf
|
||||
* @return Number of bytes processed or zero in case of an error
|
||||
*/
|
||||
size_t process_payload_bytes(uint8_t * buf, size_t len, lib::error_code& ec)
|
||||
{
|
||||
size_t process_payload_bytes(uint8_t* buf, size_t len, lib::error_code& ec) {
|
||||
// unmask if masked
|
||||
if (frame::get_masked(m_basic_header)) {
|
||||
m_current_msg->prepared_key = frame::byte_mask_circ(
|
||||
buf, len, m_current_msg->prepared_key);
|
||||
m_current_msg->prepared_key =
|
||||
frame::byte_mask_circ(buf, len, m_current_msg->prepared_key);
|
||||
// TODO: SIMD masking
|
||||
}
|
||||
|
||||
std::string & out = m_current_msg->msg_ptr->get_raw_payload();
|
||||
std::string& out = m_current_msg->msg_ptr->get_raw_payload();
|
||||
size_t offset = out.size();
|
||||
|
||||
// decompress message if needed.
|
||||
if (m_permessage_deflate.is_enabled()
|
||||
&& m_current_msg->msg_ptr->get_compressed())
|
||||
{
|
||||
if (m_permessage_deflate.is_enabled() &&
|
||||
m_current_msg->msg_ptr->get_compressed()) {
|
||||
// Decompress current buffer into the message buffer
|
||||
ec = m_permessage_deflate.decompress(buf,len,out);
|
||||
ec = m_permessage_deflate.decompress(buf, len, out);
|
||||
if (ec) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// No compression, straight copy
|
||||
out.append(reinterpret_cast<char *>(buf),len);
|
||||
out.append(reinterpret_cast<char*>(buf), len);
|
||||
}
|
||||
|
||||
// validate unmasked, decompressed values
|
||||
if (m_current_msg->msg_ptr->get_opcode() == frame::opcode::TEXT) {
|
||||
if (!m_current_msg->validator.decode(out.begin()+offset,out.end())) {
|
||||
if (!m_current_msg->validator.decode(out.begin() + offset, out.end())) {
|
||||
ec = make_error_code(error::invalid_utf8);
|
||||
return 0;
|
||||
}
|
||||
@@ -845,15 +825,14 @@ protected:
|
||||
* @param new_msg Whether or not this is the first frame of the message
|
||||
* @return 0 on success or a non-zero error code on failure
|
||||
*/
|
||||
lib::error_code validate_incoming_basic_header(frame::basic_header const & h,
|
||||
bool is_server, bool new_msg) const
|
||||
{
|
||||
lib::error_code validate_incoming_basic_header(frame::basic_header const& h,
|
||||
bool is_server,
|
||||
bool new_msg) const {
|
||||
frame::opcode::value op = frame::get_opcode(h);
|
||||
|
||||
// Check control frame size limit
|
||||
if (frame::opcode::is_control(op) &&
|
||||
frame::get_basic_size(h) > frame::limits::payload_size_basic)
|
||||
{
|
||||
frame::get_basic_size(h) > frame::limits::payload_size_basic) {
|
||||
return make_error_code(error::control_too_big);
|
||||
}
|
||||
|
||||
@@ -863,9 +842,8 @@ protected:
|
||||
// a control message.
|
||||
//
|
||||
// TODO: unit tests for this
|
||||
if (frame::get_rsv1(h) && (!m_permessage_deflate.is_enabled()
|
||||
|| frame::opcode::is_control(op)))
|
||||
{
|
||||
if (frame::get_rsv1(h) &&
|
||||
(!m_permessage_deflate.is_enabled() || frame::opcode::is_control(op))) {
|
||||
return make_error_code(error::invalid_rsv_bit);
|
||||
}
|
||||
|
||||
@@ -896,8 +874,7 @@ protected:
|
||||
|
||||
// Check for new data frame when expecting continuation
|
||||
if (!new_msg && !frame::opcode::is_control(op) &&
|
||||
op != frame::opcode::CONTINUATION)
|
||||
{
|
||||
op != frame::opcode::CONTINUATION) {
|
||||
return make_error_code(error::invalid_continuation);
|
||||
}
|
||||
|
||||
@@ -923,22 +900,19 @@ protected:
|
||||
* @return An error_code, non-zero values indicate why the validation
|
||||
* failed
|
||||
*/
|
||||
lib::error_code validate_incoming_extended_header(frame::basic_header h,
|
||||
frame::extended_header e) const
|
||||
{
|
||||
lib::error_code validate_incoming_extended_header(
|
||||
frame::basic_header h, frame::extended_header e) const {
|
||||
uint8_t basic_size = frame::get_basic_size(h);
|
||||
uint64_t payload_size = frame::get_payload_size(h,e);
|
||||
uint64_t payload_size = frame::get_payload_size(h, e);
|
||||
|
||||
// Check for non-minimally encoded payloads
|
||||
if (basic_size == frame::payload_size_code_16bit &&
|
||||
payload_size <= frame::limits::payload_size_basic)
|
||||
{
|
||||
payload_size <= frame::limits::payload_size_basic) {
|
||||
return make_error_code(error::non_minimal_encoding);
|
||||
}
|
||||
|
||||
if (basic_size == frame::payload_size_code_64bit &&
|
||||
payload_size <= frame::limits::payload_size_extended)
|
||||
{
|
||||
payload_size <= frame::limits::payload_size_extended) {
|
||||
return make_error_code(error::non_minimal_encoding);
|
||||
}
|
||||
|
||||
@@ -958,10 +932,9 @@ protected:
|
||||
* @param [out] o The output string.
|
||||
* @param [in] key The masking key to use for masking/unmasking
|
||||
*/
|
||||
void masked_copy (std::string const & i, std::string & o,
|
||||
frame::masking_key_type key) const
|
||||
{
|
||||
frame::byte_mask(i.begin(),i.end(),o.begin(),key);
|
||||
void masked_copy(std::string const& i, std::string& o,
|
||||
frame::masking_key_type key) const {
|
||||
frame::byte_mask(i.begin(), i.end(), o.begin(), key);
|
||||
// TODO: SIMD masking
|
||||
}
|
||||
|
||||
@@ -975,8 +948,8 @@ protected:
|
||||
* @return Status code, zero on success, non-zero on error
|
||||
*/
|
||||
lib::error_code prepare_control(frame::opcode::value op,
|
||||
std::string const & payload, message_ptr out) const
|
||||
{
|
||||
std::string const& payload,
|
||||
message_ptr out) const {
|
||||
if (!out) {
|
||||
return make_error_code(error::invalid_arguments);
|
||||
}
|
||||
@@ -992,22 +965,22 @@ protected:
|
||||
frame::masking_key_type key;
|
||||
bool masked = !base::m_server;
|
||||
|
||||
frame::basic_header h(op,payload.size(),true,masked);
|
||||
frame::basic_header h(op, payload.size(), true, masked);
|
||||
|
||||
std::string & o = out->get_raw_payload();
|
||||
std::string& o = out->get_raw_payload();
|
||||
o.resize(payload.size());
|
||||
|
||||
if (masked) {
|
||||
// Generate masking key.
|
||||
key.i = m_rng();
|
||||
|
||||
frame::extended_header e(payload.size(),key.i);
|
||||
out->set_header(frame::prepare_header(h,e));
|
||||
this->masked_copy(payload,o,key);
|
||||
frame::extended_header e(payload.size(), key.i);
|
||||
out->set_header(frame::prepare_header(h, e));
|
||||
this->masked_copy(payload, o, key);
|
||||
} else {
|
||||
frame::extended_header e(payload.size());
|
||||
out->set_header(frame::prepare_header(h,e));
|
||||
std::copy(payload.begin(),payload.end(),o.begin());
|
||||
out->set_header(frame::prepare_header(h, e));
|
||||
std::copy(payload.begin(), payload.end(), o.begin());
|
||||
}
|
||||
|
||||
out->set_opcode(op);
|
||||
@@ -1030,10 +1003,9 @@ protected:
|
||||
/// state, and sometimes its compression state.
|
||||
struct msg_metadata {
|
||||
msg_metadata() {}
|
||||
msg_metadata(message_ptr m, size_t p) : msg_ptr(m),prepared_key(p) {}
|
||||
msg_metadata(message_ptr m, size_t p) : msg_ptr(m), prepared_key(p) {}
|
||||
msg_metadata(message_ptr m, frame::masking_key_type p)
|
||||
: msg_ptr(m)
|
||||
, prepared_key(prepare_masking_key(p)) {}
|
||||
: msg_ptr(m), prepared_key(prepare_masking_key(p)) {}
|
||||
|
||||
message_ptr msg_ptr; // pointer to the message data buffer
|
||||
size_t prepared_key; // prepared masking key
|
||||
@@ -1058,12 +1030,12 @@ protected:
|
||||
msg_metadata m_control_msg;
|
||||
|
||||
// Pointer to the metadata associated with the frame being read
|
||||
msg_metadata * m_current_msg;
|
||||
msg_metadata* m_current_msg;
|
||||
|
||||
// Extended header of current frame
|
||||
frame::extended_header m_extended_header;
|
||||
|
||||
rng_type & m_rng;
|
||||
rng_type& m_rng;
|
||||
|
||||
// Overall state of the processor
|
||||
state m_state;
|
||||
@@ -1075,4 +1047,5 @@ protected:
|
||||
} // namespace processor
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif //WEBSOCKETPP_PROCESSOR_HYBI13_HPP
|
||||
#endif // WEBSOCKETPP_PROCESSOR_HYBI13_HPP
|
||||
#pragma warning(pop)
|
||||
@@ -32,6 +32,8 @@ under the same license as the original, which is listed below.
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4267)
|
||||
|
||||
#ifndef SHA1_DEFINED
|
||||
#define SHA1_DEFINED
|
||||
@@ -48,16 +50,13 @@ inline unsigned int rol(unsigned int value, unsigned int steps) {
|
||||
|
||||
// Sets the first 16 integers in the buffert to zero.
|
||||
// Used for clearing the W buffert.
|
||||
inline void clearWBuffert(unsigned int * buffert)
|
||||
{
|
||||
for (int pos = 16; --pos >= 0;)
|
||||
{
|
||||
inline void clearWBuffert(unsigned int *buffert) {
|
||||
for (int pos = 16; --pos >= 0;) {
|
||||
buffert[pos] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void innerHash(unsigned int * result, unsigned int * w)
|
||||
{
|
||||
inline void innerHash(unsigned int *result, unsigned int *w) {
|
||||
unsigned int a = result[0];
|
||||
unsigned int b = result[1];
|
||||
unsigned int c = result[2];
|
||||
@@ -66,7 +65,7 @@ inline void innerHash(unsigned int * result, unsigned int * w)
|
||||
|
||||
int round = 0;
|
||||
|
||||
#define sha1macro(func,val) \
|
||||
#define sha1macro(func, val) \
|
||||
{ \
|
||||
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||
e = d; \
|
||||
@@ -76,37 +75,31 @@ inline void innerHash(unsigned int * result, unsigned int * w)
|
||||
a = t; \
|
||||
}
|
||||
|
||||
while (round < 16)
|
||||
{
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||
++round;
|
||||
while (round < 16) {
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)++ round;
|
||||
}
|
||||
while (round < 20)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||
++round;
|
||||
while (round < 20) {
|
||||
w[round] =
|
||||
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)++ round;
|
||||
}
|
||||
while (round < 40)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
||||
++round;
|
||||
while (round < 40) {
|
||||
w[round] =
|
||||
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)++ round;
|
||||
}
|
||||
while (round < 60)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
||||
++round;
|
||||
while (round < 60) {
|
||||
w[round] =
|
||||
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)++ round;
|
||||
}
|
||||
while (round < 80)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
||||
++round;
|
||||
while (round < 80) {
|
||||
w[round] =
|
||||
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0xca62c1d6)++ round;
|
||||
}
|
||||
|
||||
#undef sha1macro
|
||||
#undef sha1macro
|
||||
|
||||
result[0] += a;
|
||||
result[1] += b;
|
||||
@@ -124,13 +117,13 @@ inline void innerHash(unsigned int * result, unsigned int * w)
|
||||
* @param hash should point to a buffer of at least 20 bytes of size for storing
|
||||
* the sha1 result in.
|
||||
*/
|
||||
inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||
inline void calc(void const *src, size_t bytelength, unsigned char *hash) {
|
||||
// Init the result array.
|
||||
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
|
||||
0x10325476, 0xc3d2e1f0 };
|
||||
unsigned int result[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
|
||||
0xc3d2e1f0};
|
||||
|
||||
// Cast the void src pointer to be the byte array we can work with.
|
||||
unsigned char const * sarray = (unsigned char const *) src;
|
||||
unsigned char const *sarray = (unsigned char const *)src;
|
||||
|
||||
// The reusable round buffer
|
||||
unsigned int w[80];
|
||||
@@ -147,14 +140,14 @@ inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||
endCurrentBlock = currentBlock + 64;
|
||||
|
||||
// Init the round buffer with the 64 byte block data.
|
||||
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
||||
{
|
||||
for (int roundPos = 0; currentBlock < endCurrentBlock;
|
||||
currentBlock += 4) {
|
||||
// This line will swap endian on big endian and keep endian on
|
||||
// little endian.
|
||||
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
||||
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
||||
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
||||
| (((unsigned int) sarray[currentBlock]) << 24);
|
||||
w[roundPos++] = (unsigned int)sarray[currentBlock + 3] |
|
||||
(((unsigned int)sarray[currentBlock + 2]) << 8) |
|
||||
(((unsigned int)sarray[currentBlock + 1]) << 16) |
|
||||
(((unsigned int)sarray[currentBlock]) << 24);
|
||||
}
|
||||
innerHash(result, w);
|
||||
}
|
||||
@@ -164,8 +157,10 @@ inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||
endCurrentBlock = bytelength - currentBlock;
|
||||
clearWBuffert(w);
|
||||
size_t lastBlockBytes = 0;
|
||||
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
||||
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
for (; lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
||||
w[lastBlockBytes >> 2] |=
|
||||
(unsigned int)sarray[lastBlockBytes + currentBlock]
|
||||
<< ((3 - (lastBlockBytes & 3)) << 3);
|
||||
}
|
||||
|
||||
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
@@ -179,7 +174,8 @@ inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||
// Store hash in result pointer, and make sure we get in in the correct
|
||||
// order on both endian models.
|
||||
for (int hashByte = 20; --hashByte >= 0;) {
|
||||
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||
hash[hashByte] =
|
||||
(result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,3 +183,4 @@ inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // SHA1_DEFINED
|
||||
#pragma warning(pop)
|
||||
@@ -24,32 +24,29 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127)
|
||||
|
||||
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
||||
#define WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
||||
|
||||
#include <websocketpp/transport/asio/base.hpp>
|
||||
|
||||
#include <websocketpp/transport/base/connection.hpp>
|
||||
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
|
||||
#include <websocketpp/base64/base64.hpp>
|
||||
#include <websocketpp/error.hpp>
|
||||
#include <websocketpp/uri.hpp>
|
||||
|
||||
#include <websocketpp/common/asio.hpp>
|
||||
#include <websocketpp/common/chrono.hpp>
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
#include <websocketpp/common/connection_hdl.hpp>
|
||||
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <websocketpp/base64/base64.hpp>
|
||||
#include <websocketpp/common/asio.hpp>
|
||||
#include <websocketpp/common/chrono.hpp>
|
||||
#include <websocketpp/common/connection_hdl.hpp>
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/error.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
#include <websocketpp/transport/asio/base.hpp>
|
||||
#include <websocketpp/transport/base/connection.hpp>
|
||||
#include <websocketpp/uri.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace transport {
|
||||
@@ -65,7 +62,7 @@ typedef lib::function<void(connection_hdl)> tcp_init_handler;
|
||||
*/
|
||||
template <typename config>
|
||||
class connection : public config::socket_type::socket_con_type {
|
||||
public:
|
||||
public:
|
||||
/// Type of this connection transport component
|
||||
typedef connection<config> type;
|
||||
/// Type of a shared pointer to this connection transport component
|
||||
@@ -86,7 +83,7 @@ public:
|
||||
typedef typename response_type::ptr response_ptr;
|
||||
|
||||
/// Type of a pointer to the Asio io_service being used
|
||||
typedef lib::asio::io_service * io_service_ptr;
|
||||
typedef lib::asio::io_service* io_service_ptr;
|
||||
/// Type of a pointer to the Asio io_service::strand being used
|
||||
typedef lib::shared_ptr<lib::asio::io_service::strand> strand_ptr;
|
||||
/// Type of a pointer to the Asio timer class
|
||||
@@ -98,12 +95,10 @@ public:
|
||||
friend class endpoint<config>;
|
||||
|
||||
// generate and manage our own io_service
|
||||
explicit connection(bool is_server, const lib::shared_ptr<alog_type> & alog, const lib::shared_ptr<elog_type> & elog)
|
||||
: m_is_server(is_server)
|
||||
, m_alog(alog)
|
||||
, m_elog(elog)
|
||||
{
|
||||
m_alog->write(log::alevel::devel,"asio con transport constructor");
|
||||
explicit connection(bool is_server, const lib::shared_ptr<alog_type>& alog,
|
||||
const lib::shared_ptr<elog_type>& elog)
|
||||
: m_is_server(is_server), m_alog(alog), m_elog(elog) {
|
||||
m_alog->write(log::alevel::devel, "asio con transport constructor");
|
||||
}
|
||||
|
||||
/// Get a shared pointer to this component
|
||||
@@ -111,9 +106,7 @@ public:
|
||||
return lib::static_pointer_cast<type>(socket_con_type::get_shared());
|
||||
}
|
||||
|
||||
bool is_secure() const {
|
||||
return socket_con_type::is_secure();
|
||||
}
|
||||
bool is_secure() const { return socket_con_type::is_secure(); }
|
||||
|
||||
/// Set uri hook
|
||||
/**
|
||||
@@ -127,9 +120,7 @@ public:
|
||||
*
|
||||
* @param u The uri to set
|
||||
*/
|
||||
void set_uri(uri_ptr u) {
|
||||
socket_con_type::set_uri(u);
|
||||
}
|
||||
void set_uri(uri_ptr u) { socket_con_type::set_uri(u); }
|
||||
|
||||
/// Sets the tcp pre init handler
|
||||
/**
|
||||
@@ -155,9 +146,7 @@ public:
|
||||
*
|
||||
* @param h The handler to call on tcp pre init.
|
||||
*/
|
||||
void set_tcp_init_handler(tcp_init_handler h) {
|
||||
set_tcp_pre_init_handler(h);
|
||||
}
|
||||
void set_tcp_init_handler(tcp_init_handler h) { set_tcp_pre_init_handler(h); }
|
||||
|
||||
/// Sets the tcp post init handler
|
||||
/**
|
||||
@@ -186,7 +175,7 @@ public:
|
||||
*
|
||||
* @param ec A status value
|
||||
*/
|
||||
void set_proxy(std::string const & uri, lib::error_code & ec) {
|
||||
void set_proxy(std::string const& uri, lib::error_code& ec) {
|
||||
// TODO: return errors for illegal URIs here?
|
||||
// TODO: should https urls be illegal for the moment?
|
||||
m_proxy = uri;
|
||||
@@ -195,10 +184,12 @@ public:
|
||||
}
|
||||
|
||||
/// Set the proxy to connect through (exception)
|
||||
void set_proxy(std::string const & uri) {
|
||||
void set_proxy(std::string const& uri) {
|
||||
lib::error_code ec;
|
||||
set_proxy(uri,ec);
|
||||
if (ec) { throw exception(ec); }
|
||||
set_proxy(uri, ec);
|
||||
if (ec) {
|
||||
throw exception(ec);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the basic auth credentials to use (exception free)
|
||||
@@ -214,27 +205,27 @@ public:
|
||||
*
|
||||
* @param ec A status value
|
||||
*/
|
||||
void set_proxy_basic_auth(std::string const & username, std::string const &
|
||||
password, lib::error_code & ec)
|
||||
{
|
||||
void set_proxy_basic_auth(std::string const& username,
|
||||
std::string const& password, lib::error_code& ec) {
|
||||
if (!m_proxy_data) {
|
||||
ec = make_error_code(websocketpp::error::invalid_state);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: username can't contain ':'
|
||||
std::string val = "Basic "+base64_encode(username + ":" + password);
|
||||
m_proxy_data->req.replace_header("Proxy-Authorization",val);
|
||||
std::string val = "Basic " + base64_encode(username + ":" + password);
|
||||
m_proxy_data->req.replace_header("Proxy-Authorization", val);
|
||||
ec = lib::error_code();
|
||||
}
|
||||
|
||||
/// Set the basic auth credentials to use (exception)
|
||||
void set_proxy_basic_auth(std::string const & username, std::string const &
|
||||
password)
|
||||
{
|
||||
void set_proxy_basic_auth(std::string const& username,
|
||||
std::string const& password) {
|
||||
lib::error_code ec;
|
||||
set_proxy_basic_auth(username,password,ec);
|
||||
if (ec) { throw exception(ec); }
|
||||
set_proxy_basic_auth(username, password, ec);
|
||||
if (ec) {
|
||||
throw exception(ec);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the proxy timeout duration (exception free)
|
||||
@@ -247,7 +238,7 @@ public:
|
||||
*
|
||||
* @param ec A status value
|
||||
*/
|
||||
void set_proxy_timeout(long duration, lib::error_code & ec) {
|
||||
void set_proxy_timeout(long duration, lib::error_code& ec) {
|
||||
if (!m_proxy_data) {
|
||||
ec = make_error_code(websocketpp::error::invalid_state);
|
||||
return;
|
||||
@@ -260,13 +251,13 @@ public:
|
||||
/// Set the proxy timeout duration (exception)
|
||||
void set_proxy_timeout(long duration) {
|
||||
lib::error_code ec;
|
||||
set_proxy_timeout(duration,ec);
|
||||
if (ec) { throw exception(ec); }
|
||||
set_proxy_timeout(duration, ec);
|
||||
if (ec) {
|
||||
throw exception(ec);
|
||||
}
|
||||
}
|
||||
|
||||
std::string const & get_proxy() const {
|
||||
return m_proxy;
|
||||
}
|
||||
std::string const& get_proxy() const { return m_proxy; }
|
||||
|
||||
/// Get the remote endpoint address
|
||||
/**
|
||||
@@ -284,7 +275,7 @@ public:
|
||||
std::string ret = socket_con_type::get_remote_endpoint(ec);
|
||||
|
||||
if (ec) {
|
||||
m_elog->write(log::elevel::info,ret);
|
||||
m_elog->write(log::elevel::info, ret);
|
||||
return "Unknown";
|
||||
} else {
|
||||
return ret;
|
||||
@@ -292,9 +283,7 @@ public:
|
||||
}
|
||||
|
||||
/// Get the connection handle
|
||||
connection_hdl get_handle() const {
|
||||
return m_connection_hdl;
|
||||
}
|
||||
connection_hdl get_handle() const { return m_connection_hdl; }
|
||||
|
||||
/// Call back a function after a period of time.
|
||||
/**
|
||||
@@ -311,26 +300,17 @@ public:
|
||||
* needed.
|
||||
*/
|
||||
timer_ptr set_timer(long duration, timer_handler callback) {
|
||||
timer_ptr new_timer(
|
||||
new lib::asio::steady_timer(
|
||||
*m_io_service,
|
||||
lib::asio::milliseconds(duration))
|
||||
);
|
||||
timer_ptr new_timer(new lib::asio::steady_timer(
|
||||
*m_io_service, lib::asio::milliseconds(duration)));
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
new_timer->async_wait(m_strand->wrap(lib::bind(
|
||||
&type::handle_timer, get_shared(),
|
||||
new_timer,
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
)));
|
||||
new_timer->async_wait(
|
||||
m_strand->wrap(lib::bind(&type::handle_timer, get_shared(), new_timer,
|
||||
callback, lib::placeholders::_1)));
|
||||
} else {
|
||||
new_timer->async_wait(lib::bind(
|
||||
&type::handle_timer, get_shared(),
|
||||
new_timer,
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
));
|
||||
new_timer->async_wait(lib::bind(&type::handle_timer, get_shared(),
|
||||
new_timer, callback,
|
||||
lib::placeholders::_1));
|
||||
}
|
||||
|
||||
return new_timer;
|
||||
@@ -348,13 +328,12 @@ public:
|
||||
* @param ec The status code
|
||||
*/
|
||||
void handle_timer(timer_ptr, timer_handler callback,
|
||||
lib::asio::error_code const & ec)
|
||||
{
|
||||
lib::asio::error_code const& ec) {
|
||||
if (ec) {
|
||||
if (ec == lib::asio::error::operation_aborted) {
|
||||
callback(make_error_code(transport::error::operation_aborted));
|
||||
} else {
|
||||
log_err(log::elevel::info,"asio handle_timer",ec);
|
||||
log_err(log::elevel::info, "asio handle_timer", ec);
|
||||
callback(make_error_code(error::pass_through));
|
||||
}
|
||||
} else {
|
||||
@@ -363,9 +342,7 @@ public:
|
||||
}
|
||||
|
||||
/// Get a pointer to this connection's strand
|
||||
strand_ptr get_strand() {
|
||||
return m_strand;
|
||||
}
|
||||
strand_ptr get_strand() { return m_strand; }
|
||||
|
||||
/// Get the internal transport error code for a closed/failed connection
|
||||
/**
|
||||
@@ -386,9 +363,7 @@ public:
|
||||
* @return Error code indicating the reason the connection was closed or
|
||||
* failed
|
||||
*/
|
||||
lib::asio::error_code get_transport_ec() const {
|
||||
return m_tec;
|
||||
}
|
||||
lib::asio::error_code get_transport_ec() const { return m_tec; }
|
||||
|
||||
/// Initialize transport for reading
|
||||
/**
|
||||
@@ -407,23 +382,17 @@ public:
|
||||
* read or write the WebSocket handshakes. At this point the original
|
||||
* callback function is called.
|
||||
*/
|
||||
protected:
|
||||
protected:
|
||||
void init(init_handler callback) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,"asio connection init");
|
||||
m_alog->write(log::alevel::devel, "asio connection init");
|
||||
}
|
||||
|
||||
// TODO: pre-init timeout. Right now no implemented socket policies
|
||||
// actually have an asyncronous pre-init
|
||||
|
||||
socket_con_type::pre_init(
|
||||
lib::bind(
|
||||
&type::handle_pre_init,
|
||||
get_shared(),
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
socket_con_type::pre_init(lib::bind(&type::handle_pre_init, get_shared(),
|
||||
callback, lib::placeholders::_1));
|
||||
}
|
||||
|
||||
/// initialize the proxy buffers and http parsers
|
||||
@@ -434,7 +403,7 @@ protected:
|
||||
*
|
||||
* @return Status code indicating what errors occurred, if any
|
||||
*/
|
||||
lib::error_code proxy_init(std::string const & authority) {
|
||||
lib::error_code proxy_init(std::string const& authority) {
|
||||
if (!m_proxy_data) {
|
||||
return websocketpp::error::make_error_code(
|
||||
websocketpp::error::invalid_state);
|
||||
@@ -443,7 +412,7 @@ protected:
|
||||
m_proxy_data->req.set_method("CONNECT");
|
||||
|
||||
m_proxy_data->req.set_uri(authority);
|
||||
m_proxy_data->req.replace_header("Host",authority);
|
||||
m_proxy_data->req.replace_header("Host", authority);
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
@@ -458,22 +427,22 @@ protected:
|
||||
*
|
||||
* @return Status code for the success or failure of the initialization
|
||||
*/
|
||||
lib::error_code init_asio (io_service_ptr io_service) {
|
||||
lib::error_code init_asio(io_service_ptr io_service) {
|
||||
m_io_service = io_service;
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
m_strand.reset(new lib::asio::io_service::strand(*io_service));
|
||||
}
|
||||
|
||||
lib::error_code ec = socket_con_type::init_asio(io_service, m_strand,
|
||||
m_is_server);
|
||||
lib::error_code ec =
|
||||
socket_con_type::init_asio(io_service, m_strand, m_is_server);
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
void handle_pre_init(init_handler callback, lib::error_code const & ec) {
|
||||
void handle_pre_init(init_handler callback, lib::error_code const& ec) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,"asio connection handle pre_init");
|
||||
m_alog->write(log::alevel::devel, "asio connection handle pre_init");
|
||||
}
|
||||
|
||||
if (m_tcp_pre_init_handler) {
|
||||
@@ -495,33 +464,21 @@ protected:
|
||||
|
||||
void post_init(init_handler callback) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,"asio connection post_init");
|
||||
m_alog->write(log::alevel::devel, "asio connection post_init");
|
||||
}
|
||||
|
||||
timer_ptr post_timer;
|
||||
|
||||
if (config::timeout_socket_post_init > 0) {
|
||||
post_timer = set_timer(
|
||||
config::timeout_socket_post_init,
|
||||
lib::bind(
|
||||
&type::handle_post_init_timeout,
|
||||
get_shared(),
|
||||
post_timer,
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
post_timer =
|
||||
set_timer(config::timeout_socket_post_init,
|
||||
lib::bind(&type::handle_post_init_timeout, get_shared(),
|
||||
post_timer, callback, lib::placeholders::_1));
|
||||
}
|
||||
|
||||
socket_con_type::post_init(
|
||||
lib::bind(
|
||||
&type::handle_post_init,
|
||||
get_shared(),
|
||||
post_timer,
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
socket_con_type::post_init(lib::bind(&type::handle_post_init, get_shared(),
|
||||
post_timer, callback,
|
||||
lib::placeholders::_1));
|
||||
}
|
||||
|
||||
/// Post init timeout callback
|
||||
@@ -534,18 +491,16 @@ protected:
|
||||
* @param ec The status code
|
||||
*/
|
||||
void handle_post_init_timeout(timer_ptr, init_handler callback,
|
||||
lib::error_code const & ec)
|
||||
{
|
||||
lib::error_code const& ec) {
|
||||
lib::error_code ret_ec;
|
||||
|
||||
if (ec) {
|
||||
if (ec == transport::error::operation_aborted) {
|
||||
m_alog->write(log::alevel::devel,
|
||||
"asio post init timer cancelled");
|
||||
m_alog->write(log::alevel::devel, "asio post init timer cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
log_err(log::elevel::devel,"asio handle_post_init_timeout",ec);
|
||||
log_err(log::elevel::devel, "asio handle_post_init_timeout", ec);
|
||||
ret_ec = ec;
|
||||
} else {
|
||||
if (socket_con_type::get_ec()) {
|
||||
@@ -570,12 +525,10 @@ protected:
|
||||
* @param ec The status code
|
||||
*/
|
||||
void handle_post_init(timer_ptr post_timer, init_handler callback,
|
||||
lib::error_code const & ec)
|
||||
{
|
||||
lib::error_code const& ec) {
|
||||
if (ec == transport::error::operation_aborted ||
|
||||
(post_timer && lib::asio::is_neg(post_timer->expires_from_now())))
|
||||
{
|
||||
m_alog->write(log::alevel::devel,"post_init cancelled");
|
||||
(post_timer && lib::asio::is_neg(post_timer->expires_from_now()))) {
|
||||
m_alog->write(log::alevel::devel, "post_init cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -584,7 +537,7 @@ protected:
|
||||
}
|
||||
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,"asio connection handle_post_init");
|
||||
m_alog->write(log::alevel::devel, "asio connection handle_post_init");
|
||||
}
|
||||
|
||||
if (m_tcp_post_init_handler) {
|
||||
@@ -596,11 +549,12 @@ protected:
|
||||
|
||||
void proxy_write(init_handler callback) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,"asio connection proxy_write");
|
||||
m_alog->write(log::alevel::devel, "asio connection proxy_write");
|
||||
}
|
||||
|
||||
if (!m_proxy_data) {
|
||||
m_elog->write(log::elevel::library,
|
||||
m_elog->write(
|
||||
log::elevel::library,
|
||||
"assertion failed: !m_proxy_data in asio::connection::proxy_write");
|
||||
callback(make_error_code(error::general));
|
||||
return;
|
||||
@@ -611,51 +565,34 @@ protected:
|
||||
m_bufs.push_back(lib::asio::buffer(m_proxy_data->write_buf.data(),
|
||||
m_proxy_data->write_buf.size()));
|
||||
|
||||
m_alog->write(log::alevel::devel,m_proxy_data->write_buf);
|
||||
m_alog->write(log::alevel::devel, m_proxy_data->write_buf);
|
||||
|
||||
// Set a timer so we don't wait forever for the proxy to respond
|
||||
m_proxy_data->timer = this->set_timer(
|
||||
m_proxy_data->timeout_proxy,
|
||||
lib::bind(
|
||||
&type::handle_proxy_timeout,
|
||||
get_shared(),
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
m_proxy_data->timer =
|
||||
this->set_timer(m_proxy_data->timeout_proxy,
|
||||
lib::bind(&type::handle_proxy_timeout, get_shared(),
|
||||
callback, lib::placeholders::_1));
|
||||
|
||||
// Send proxy request
|
||||
if (config::enable_multithreading) {
|
||||
lib::asio::async_write(
|
||||
socket_con_type::get_next_layer(),
|
||||
m_bufs,
|
||||
m_strand->wrap(lib::bind(
|
||||
&type::handle_proxy_write, get_shared(),
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
))
|
||||
);
|
||||
socket_con_type::get_next_layer(), m_bufs,
|
||||
m_strand->wrap(lib::bind(&type::handle_proxy_write, get_shared(),
|
||||
callback, lib::placeholders::_1)));
|
||||
} else {
|
||||
lib::asio::async_write(
|
||||
socket_con_type::get_next_layer(),
|
||||
m_bufs,
|
||||
lib::bind(
|
||||
&type::handle_proxy_write, get_shared(),
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
lib::asio::async_write(socket_con_type::get_next_layer(), m_bufs,
|
||||
lib::bind(&type::handle_proxy_write, get_shared(),
|
||||
callback, lib::placeholders::_1));
|
||||
}
|
||||
}
|
||||
|
||||
void handle_proxy_timeout(init_handler callback, lib::error_code const & ec)
|
||||
{
|
||||
void handle_proxy_timeout(init_handler callback, lib::error_code const& ec) {
|
||||
if (ec == transport::error::operation_aborted) {
|
||||
m_alog->write(log::alevel::devel,
|
||||
"asio handle_proxy_write timer cancelled");
|
||||
return;
|
||||
} else if (ec) {
|
||||
log_err(log::elevel::devel,"asio handle_proxy_write",ec);
|
||||
log_err(log::elevel::devel, "asio handle_proxy_write", ec);
|
||||
callback(ec);
|
||||
} else {
|
||||
m_alog->write(log::alevel::devel,
|
||||
@@ -666,11 +603,9 @@ protected:
|
||||
}
|
||||
|
||||
void handle_proxy_write(init_handler callback,
|
||||
lib::asio::error_code const & ec)
|
||||
{
|
||||
lib::asio::error_code const& ec) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,
|
||||
"asio connection handle_proxy_write");
|
||||
m_alog->write(log::alevel::devel, "asio connection handle_proxy_write");
|
||||
}
|
||||
|
||||
m_bufs.clear();
|
||||
@@ -679,14 +614,13 @@ protected:
|
||||
// Whatever aborted it will be issuing the callback so we are safe to
|
||||
// return
|
||||
if (ec == lib::asio::error::operation_aborted ||
|
||||
lib::asio::is_neg(m_proxy_data->timer->expires_from_now()))
|
||||
{
|
||||
m_elog->write(log::elevel::devel,"write operation aborted");
|
||||
lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) {
|
||||
m_elog->write(log::elevel::devel, "write operation aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ec) {
|
||||
log_err(log::elevel::info,"asio handle_proxy_write",ec);
|
||||
log_err(log::elevel::info, "asio handle_proxy_write", ec);
|
||||
m_proxy_data->timer->cancel();
|
||||
callback(make_error_code(error::pass_through));
|
||||
return;
|
||||
@@ -697,11 +631,12 @@ protected:
|
||||
|
||||
void proxy_read(init_handler callback) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,"asio connection proxy_read");
|
||||
m_alog->write(log::alevel::devel, "asio connection proxy_read");
|
||||
}
|
||||
|
||||
if (!m_proxy_data) {
|
||||
m_elog->write(log::elevel::library,
|
||||
m_elog->write(
|
||||
log::elevel::library,
|
||||
"assertion failed: !m_proxy_data in asio::connection::proxy_read");
|
||||
m_proxy_data->timer->cancel();
|
||||
callback(make_error_code(error::general));
|
||||
@@ -710,26 +645,15 @@ protected:
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
lib::asio::async_read_until(
|
||||
socket_con_type::get_next_layer(),
|
||||
m_proxy_data->read_buf,
|
||||
"\r\n\r\n",
|
||||
m_strand->wrap(lib::bind(
|
||||
&type::handle_proxy_read, get_shared(),
|
||||
callback,
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
))
|
||||
);
|
||||
socket_con_type::get_next_layer(), m_proxy_data->read_buf, "\r\n\r\n",
|
||||
m_strand->wrap(lib::bind(&type::handle_proxy_read, get_shared(),
|
||||
callback, lib::placeholders::_1,
|
||||
lib::placeholders::_2)));
|
||||
} else {
|
||||
lib::asio::async_read_until(
|
||||
socket_con_type::get_next_layer(),
|
||||
m_proxy_data->read_buf,
|
||||
"\r\n\r\n",
|
||||
lib::bind(
|
||||
&type::handle_proxy_read, get_shared(),
|
||||
callback,
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
)
|
||||
);
|
||||
socket_con_type::get_next_layer(), m_proxy_data->read_buf, "\r\n\r\n",
|
||||
lib::bind(&type::handle_proxy_read, get_shared(), callback,
|
||||
lib::placeholders::_1, lib::placeholders::_2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,21 +663,18 @@ protected:
|
||||
* @param ec The status code
|
||||
* @param bytes_transferred The number of bytes read
|
||||
*/
|
||||
void handle_proxy_read(init_handler callback,
|
||||
lib::asio::error_code const & ec, size_t)
|
||||
{
|
||||
void handle_proxy_read(init_handler callback, lib::asio::error_code const& ec,
|
||||
size_t) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,
|
||||
"asio connection handle_proxy_read");
|
||||
m_alog->write(log::alevel::devel, "asio connection handle_proxy_read");
|
||||
}
|
||||
|
||||
// Timer expired or the operation was aborted for some reason.
|
||||
// Whatever aborted it will be issuing the callback so we are safe to
|
||||
// return
|
||||
if (ec == lib::asio::error::operation_aborted ||
|
||||
lib::asio::is_neg(m_proxy_data->timer->expires_from_now()))
|
||||
{
|
||||
m_elog->write(log::elevel::devel,"read operation aborted");
|
||||
lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) {
|
||||
m_elog->write(log::elevel::devel, "read operation aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -762,12 +683,13 @@ protected:
|
||||
|
||||
if (ec) {
|
||||
m_elog->write(log::elevel::info,
|
||||
"asio handle_proxy_read error: "+ec.message());
|
||||
"asio handle_proxy_read error: " + ec.message());
|
||||
callback(make_error_code(error::pass_through));
|
||||
} else {
|
||||
if (!m_proxy_data) {
|
||||
m_elog->write(log::elevel::library,
|
||||
"assertion failed: !m_proxy_data in asio::connection::handle_proxy_read");
|
||||
"assertion failed: !m_proxy_data in "
|
||||
"asio::connection::handle_proxy_read");
|
||||
callback(make_error_code(error::general));
|
||||
return;
|
||||
}
|
||||
@@ -783,19 +705,16 @@ protected:
|
||||
return;
|
||||
}
|
||||
|
||||
m_alog->write(log::alevel::devel,m_proxy_data->res.raw());
|
||||
m_alog->write(log::alevel::devel, m_proxy_data->res.raw());
|
||||
|
||||
if (m_proxy_data->res.get_status_code() != http::status_code::ok) {
|
||||
// got an error response back
|
||||
// TODO: expose this error in a programmatically accessible way?
|
||||
// if so, see below for an option on how to do this.
|
||||
std::stringstream s;
|
||||
s << "Proxy connection error: "
|
||||
<< m_proxy_data->res.get_status_code()
|
||||
<< " ("
|
||||
<< m_proxy_data->res.get_status_msg()
|
||||
<< ")";
|
||||
m_elog->write(log::elevel::info,s.str());
|
||||
s << "Proxy connection error: " << m_proxy_data->res.get_status_code()
|
||||
<< " (" << m_proxy_data->res.get_status_msg() << ")";
|
||||
m_elog->write(log::elevel::info, s.str());
|
||||
callback(make_error_code(error::proxy_failed));
|
||||
return;
|
||||
}
|
||||
@@ -817,13 +736,12 @@ protected:
|
||||
}
|
||||
|
||||
/// read at least num_bytes bytes into buf and then call handler.
|
||||
void async_read_at_least(size_t num_bytes, char *buf, size_t len,
|
||||
read_handler handler)
|
||||
{
|
||||
void async_read_at_least(size_t num_bytes, char* buf, size_t len,
|
||||
read_handler handler) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
std::stringstream s;
|
||||
s << "asio async_read_at_least: " << num_bytes;
|
||||
m_alog->write(log::alevel::devel,s.str());
|
||||
m_alog->write(log::alevel::devel, s.str());
|
||||
}
|
||||
|
||||
// TODO: safety vs speed ?
|
||||
@@ -838,39 +756,25 @@ protected:
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
lib::asio::async_read(
|
||||
socket_con_type::get_socket(),
|
||||
lib::asio::buffer(buf,len),
|
||||
socket_con_type::get_socket(), lib::asio::buffer(buf, len),
|
||||
lib::asio::transfer_at_least(num_bytes),
|
||||
m_strand->wrap(make_custom_alloc_handler(
|
||||
m_read_handler_allocator,
|
||||
lib::bind(
|
||||
&type::handle_async_read, get_shared(),
|
||||
handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
)
|
||||
))
|
||||
);
|
||||
lib::bind(&type::handle_async_read, get_shared(), handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2))));
|
||||
} else {
|
||||
lib::asio::async_read(
|
||||
socket_con_type::get_socket(),
|
||||
lib::asio::buffer(buf,len),
|
||||
socket_con_type::get_socket(), lib::asio::buffer(buf, len),
|
||||
lib::asio::transfer_at_least(num_bytes),
|
||||
make_custom_alloc_handler(
|
||||
m_read_handler_allocator,
|
||||
lib::bind(
|
||||
&type::handle_async_read, get_shared(),
|
||||
handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
)
|
||||
)
|
||||
);
|
||||
lib::bind(&type::handle_async_read, get_shared(), handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handle_async_read(read_handler handler, lib::asio::error_code const & ec,
|
||||
size_t bytes_transferred)
|
||||
{
|
||||
void handle_async_read(read_handler handler, lib::asio::error_code const& ec,
|
||||
size_t bytes_transferred) {
|
||||
m_alog->write(log::alevel::devel, "asio con handle_async_read");
|
||||
|
||||
// translate asio error codes into more lib::error_codes
|
||||
@@ -884,16 +788,15 @@ protected:
|
||||
m_tec = ec;
|
||||
|
||||
if (tec == transport::error::tls_error ||
|
||||
tec == transport::error::pass_through)
|
||||
{
|
||||
tec == transport::error::pass_through) {
|
||||
// These are aggregate/catch all errors. Log some human readable
|
||||
// information to the info channel to give library users some
|
||||
// more details about why the upstream method may have failed.
|
||||
log_err(log::elevel::info,"asio async_read_at_least",ec);
|
||||
log_err(log::elevel::info, "asio async_read_at_least", ec);
|
||||
}
|
||||
}
|
||||
if (handler) {
|
||||
handler(tec,bytes_transferred);
|
||||
handler(tec, bytes_transferred);
|
||||
} else {
|
||||
// This can happen in cases where the connection is terminated while
|
||||
// the transport is waiting on a read.
|
||||
@@ -904,71 +807,47 @@ protected:
|
||||
|
||||
/// Initiate a potentially asyncronous write of the given buffer
|
||||
void async_write(const char* buf, size_t len, write_handler handler) {
|
||||
m_bufs.push_back(lib::asio::buffer(buf,len));
|
||||
m_bufs.push_back(lib::asio::buffer(buf, len));
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
lib::asio::async_write(
|
||||
socket_con_type::get_socket(),
|
||||
m_bufs,
|
||||
socket_con_type::get_socket(), m_bufs,
|
||||
m_strand->wrap(make_custom_alloc_handler(
|
||||
m_write_handler_allocator,
|
||||
lib::bind(
|
||||
&type::handle_async_write, get_shared(),
|
||||
handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
)
|
||||
))
|
||||
);
|
||||
lib::bind(&type::handle_async_write, get_shared(), handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2))));
|
||||
} else {
|
||||
lib::asio::async_write(
|
||||
socket_con_type::get_socket(),
|
||||
m_bufs,
|
||||
socket_con_type::get_socket(), m_bufs,
|
||||
make_custom_alloc_handler(
|
||||
m_write_handler_allocator,
|
||||
lib::bind(
|
||||
&type::handle_async_write, get_shared(),
|
||||
handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
)
|
||||
)
|
||||
);
|
||||
lib::bind(&type::handle_async_write, get_shared(), handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Initiate a potentially asyncronous write of the given buffers
|
||||
void async_write(std::vector<buffer> const & bufs, write_handler handler) {
|
||||
void async_write(std::vector<buffer> const& bufs, write_handler handler) {
|
||||
std::vector<buffer>::const_iterator it;
|
||||
|
||||
for (it = bufs.begin(); it != bufs.end(); ++it) {
|
||||
m_bufs.push_back(lib::asio::buffer((*it).buf,(*it).len));
|
||||
m_bufs.push_back(lib::asio::buffer((*it).buf, (*it).len));
|
||||
}
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
lib::asio::async_write(
|
||||
socket_con_type::get_socket(),
|
||||
m_bufs,
|
||||
socket_con_type::get_socket(), m_bufs,
|
||||
m_strand->wrap(make_custom_alloc_handler(
|
||||
m_write_handler_allocator,
|
||||
lib::bind(
|
||||
&type::handle_async_write, get_shared(),
|
||||
handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
)
|
||||
))
|
||||
);
|
||||
lib::bind(&type::handle_async_write, get_shared(), handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2))));
|
||||
} else {
|
||||
lib::asio::async_write(
|
||||
socket_con_type::get_socket(),
|
||||
m_bufs,
|
||||
socket_con_type::get_socket(), m_bufs,
|
||||
make_custom_alloc_handler(
|
||||
m_write_handler_allocator,
|
||||
lib::bind(
|
||||
&type::handle_async_write, get_shared(),
|
||||
handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
)
|
||||
)
|
||||
);
|
||||
lib::bind(&type::handle_async_write, get_shared(), handler,
|
||||
lib::placeholders::_1, lib::placeholders::_2)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -977,11 +856,12 @@ protected:
|
||||
* @param ec The status code
|
||||
* @param bytes_transferred The number of bytes read
|
||||
*/
|
||||
void handle_async_write(write_handler handler, lib::asio::error_code const & ec, size_t) {
|
||||
void handle_async_write(write_handler handler,
|
||||
lib::asio::error_code const& ec, size_t) {
|
||||
m_bufs.clear();
|
||||
lib::error_code tec;
|
||||
if (ec) {
|
||||
log_err(log::elevel::info,"asio async_write",ec);
|
||||
log_err(log::elevel::info, "asio async_write", ec);
|
||||
tec = make_error_code(transport::error::pass_through);
|
||||
}
|
||||
if (handler) {
|
||||
@@ -1035,30 +915,18 @@ protected:
|
||||
/// close and clean up the underlying socket
|
||||
void async_shutdown(shutdown_handler callback) {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,"asio connection async_shutdown");
|
||||
m_alog->write(log::alevel::devel, "asio connection async_shutdown");
|
||||
}
|
||||
|
||||
timer_ptr shutdown_timer;
|
||||
shutdown_timer = set_timer(
|
||||
config::timeout_socket_shutdown,
|
||||
lib::bind(
|
||||
&type::handle_async_shutdown_timeout,
|
||||
get_shared(),
|
||||
shutdown_timer,
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
shutdown_timer =
|
||||
set_timer(config::timeout_socket_shutdown,
|
||||
lib::bind(&type::handle_async_shutdown_timeout, get_shared(),
|
||||
shutdown_timer, callback, lib::placeholders::_1));
|
||||
|
||||
socket_con_type::async_shutdown(
|
||||
lib::bind(
|
||||
&type::handle_async_shutdown,
|
||||
get_shared(),
|
||||
shutdown_timer,
|
||||
callback,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
socket_con_type::async_shutdown(lib::bind(&type::handle_async_shutdown,
|
||||
get_shared(), shutdown_timer,
|
||||
callback, lib::placeholders::_1));
|
||||
}
|
||||
|
||||
/// Async shutdown timeout handler
|
||||
@@ -1068,8 +936,7 @@ protected:
|
||||
* @param ec The status code
|
||||
*/
|
||||
void handle_async_shutdown_timeout(timer_ptr, init_handler callback,
|
||||
lib::error_code const & ec)
|
||||
{
|
||||
lib::error_code const& ec) {
|
||||
lib::error_code ret_ec;
|
||||
|
||||
if (ec) {
|
||||
@@ -1079,7 +946,7 @@ protected:
|
||||
return;
|
||||
}
|
||||
|
||||
log_err(log::elevel::devel,"asio handle_async_shutdown_timeout",ec);
|
||||
log_err(log::elevel::devel, "asio handle_async_shutdown_timeout", ec);
|
||||
ret_ec = ec;
|
||||
} else {
|
||||
ret_ec = make_error_code(transport::error::timeout);
|
||||
@@ -1091,13 +958,12 @@ protected:
|
||||
callback(ret_ec);
|
||||
}
|
||||
|
||||
void handle_async_shutdown(timer_ptr shutdown_timer, shutdown_handler
|
||||
callback, lib::asio::error_code const & ec)
|
||||
{
|
||||
void handle_async_shutdown(timer_ptr shutdown_timer,
|
||||
shutdown_handler callback,
|
||||
lib::asio::error_code const& ec) {
|
||||
if (ec == lib::asio::error::operation_aborted ||
|
||||
lib::asio::is_neg(shutdown_timer->expires_from_now()))
|
||||
{
|
||||
m_alog->write(log::alevel::devel,"async_shutdown cancelled");
|
||||
lib::asio::is_neg(shutdown_timer->expires_from_now())) {
|
||||
m_alog->write(log::alevel::devel, "async_shutdown cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1119,12 +985,11 @@ protected:
|
||||
// all other errors are effectively pass through errors of
|
||||
// some sort so print some detail on the info channel for
|
||||
// library users to look up if needed.
|
||||
log_err(log::elevel::info,"asio async_shutdown",ec);
|
||||
log_err(log::elevel::info, "asio async_shutdown", ec);
|
||||
}
|
||||
} else {
|
||||
if (m_alog->static_test(log::alevel::devel)) {
|
||||
m_alog->write(log::alevel::devel,
|
||||
"asio con handle_async_shutdown");
|
||||
m_alog->write(log::alevel::devel, "asio con handle_async_shutdown");
|
||||
}
|
||||
}
|
||||
callback(tec);
|
||||
@@ -1143,13 +1008,13 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
/// Convenience method for logging the code and message for an error_code
|
||||
template <typename error_type>
|
||||
void log_err(log::level l, const char * msg, const error_type & ec) {
|
||||
void log_err(log::level l, const char* msg, const error_type& ec) {
|
||||
std::stringstream s;
|
||||
s << msg << " error: " << ec << " (" << ec.message() << ")";
|
||||
m_elog->write(l,s.str());
|
||||
m_elog->write(l, s.str());
|
||||
}
|
||||
|
||||
// static settings
|
||||
@@ -1189,9 +1054,9 @@ private:
|
||||
handler_allocator m_write_handler_allocator;
|
||||
};
|
||||
|
||||
|
||||
} // namespace asio
|
||||
} // namespace transport
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
||||
#pragma warning(pop)
|
||||
@@ -22,8 +22,7 @@ includes("thirdparty")
|
||||
|
||||
if is_os("windows") then
|
||||
add_defines("_WEBSOCKETPP_CPP11_INTERNAL_")
|
||||
-- add_cxflags("/W4", "/WX")
|
||||
add_cxflags("/W4")
|
||||
add_cxflags("/W4", "/WX")
|
||||
elseif is_os("linux") then
|
||||
add_requires("glib", {system = true})
|
||||
add_packages("glib")
|
||||
@@ -176,8 +175,8 @@ target("media")
|
||||
target("qos")
|
||||
set_kind("object")
|
||||
add_deps("log")
|
||||
add_files("src/qos/kcp/*.c")
|
||||
add_includedirs("src/qos/kcp", {public = true})
|
||||
add_files("src/qos/*.cpp")
|
||||
add_includedirs("src/qos", {public = true})
|
||||
|
||||
target("statistics")
|
||||
set_kind("object")
|
||||
|
||||
Reference in New Issue
Block a user