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;
|
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];
|
buffer_ = new uint8_t[size];
|
||||||
size_ = size;
|
size_ = size;
|
||||||
width_ = width;
|
width_ = width;
|
||||||
@@ -27,8 +27,8 @@ VideoFrame::VideoFrame(const uint8_t *buffer, size_t size) {
|
|||||||
height_ = 0;
|
height_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoFrame::VideoFrame(const uint8_t *buffer, size_t size, size_t width,
|
VideoFrame::VideoFrame(const uint8_t *buffer, size_t size, uint32_t width,
|
||||||
size_t height) {
|
uint32_t height) {
|
||||||
buffer_ = new uint8_t[size];
|
buffer_ = new uint8_t[size];
|
||||||
memcpy(buffer_, buffer, size);
|
memcpy(buffer_, buffer, size);
|
||||||
size_ = size;
|
size_ = size;
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ class VideoFrame {
|
|||||||
public:
|
public:
|
||||||
VideoFrame();
|
VideoFrame();
|
||||||
VideoFrame(size_t size);
|
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);
|
||||||
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(const VideoFrame &video_frame);
|
||||||
VideoFrame(VideoFrame &&video_frame);
|
VideoFrame(VideoFrame &&video_frame);
|
||||||
VideoFrame &operator=(const VideoFrame &video_frame);
|
VideoFrame &operator=(const VideoFrame &video_frame);
|
||||||
@@ -27,18 +28,18 @@ class VideoFrame {
|
|||||||
public:
|
public:
|
||||||
const uint8_t *Buffer() { return buffer_; }
|
const uint8_t *Buffer() { return buffer_; }
|
||||||
size_t Size() { return size_; }
|
size_t Size() { return size_; }
|
||||||
size_t Width() { return width_; }
|
uint32_t Width() { return width_; }
|
||||||
size_t Height() { return height_; }
|
uint32_t Height() { return height_; }
|
||||||
|
|
||||||
void SetSize(size_t size) { size_ = size; }
|
void SetSize(size_t size) { size_ = size; }
|
||||||
void SetWidth(size_t width) { width_ = width; }
|
void SetWidth(uint32_t width) { width_ = width; }
|
||||||
void SetHeight(size_t height) { height_ = height; }
|
void SetHeight(uint32_t height) { height_ = height; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t *buffer_ = nullptr;
|
uint8_t *buffer_ = nullptr;
|
||||||
size_t size_ = 0;
|
size_t size_ = 0;
|
||||||
size_t width_ = 0;
|
uint32_t width_ = 0;
|
||||||
size_t height_ = 0;
|
uint32_t height_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -190,11 +190,10 @@ int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cb_closed(GObject *src, GAsyncResult *res, gpointer data) {
|
void cb_closed(GObject *src, [[maybe_unused]] GAsyncResult *res,
|
||||||
NiceAgent *agent = NICE_AGENT(src);
|
[[maybe_unused]] gpointer data) {
|
||||||
g_debug("test-turn:%s: %p", G_STRFUNC, agent);
|
[[maybe_unused]] NiceAgent *agent = NICE_AGENT(src);
|
||||||
|
LOG_INFO("Nice agent closed");
|
||||||
*((gboolean *)data) = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int IceAgent::DestroyIceAgent() {
|
int IceAgent::DestroyIceAgent() {
|
||||||
@@ -384,11 +383,11 @@ int IceAgent::Send(const char *data, size_t size) {
|
|||||||
// return -1;
|
// 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
|
#ifdef SAVE_IO_STREAM
|
||||||
fwrite(data, 1, size, file_out_);
|
fwrite(data, 1, size, file_out_);
|
||||||
#endif
|
#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 now = std::chrono::system_clock::now() + std::chrono::hours(8);
|
||||||
auto timet = std::chrono::system_clock::to_time_t(now);
|
auto now_time = std::chrono::system_clock::to_time_t(now);
|
||||||
auto localTime = *std::gmtime(&timet);
|
|
||||||
|
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::stringstream ss;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
ss << LOGGER_NAME;
|
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;
|
ss >> filename;
|
||||||
|
|
||||||
std::string path = "logs/" + filename;
|
std::string path = "logs/" + filename;
|
||||||
|
|||||||
@@ -36,11 +36,11 @@ int AudioDecoder::Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoder::Decode(
|
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) {
|
std::function<void(uint8_t*, int)> on_receive_decoded_frame) {
|
||||||
// LOG_ERROR("input opus size = {}", size);
|
// LOG_ERROR("input opus size = {}", size);
|
||||||
auto frame_size =
|
auto frame_size = opus_decode(opus_decoder_, data, (opus_int32)size, out_data,
|
||||||
opus_decode(opus_decoder_, data, size, out_data, MAX_FRAME_SIZE, 0);
|
MAX_FRAME_SIZE, 0);
|
||||||
|
|
||||||
if (frame_size < 0) {
|
if (frame_size < 0) {
|
||||||
LOG_ERROR("Decode opus frame failed");
|
LOG_ERROR("Decode opus frame failed");
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class AudioDecoder {
|
|||||||
public:
|
public:
|
||||||
int Init();
|
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::function<void(uint8_t *, int)> on_receive_decoded_frame);
|
||||||
|
|
||||||
std::string GetDecoderName() { return "Opus"; }
|
std::string GetDecoderName() { return "Opus"; }
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int AudioEncoder::Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int AudioEncoder::Encode(
|
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)>
|
std::function<int(char *encoded_audio_buffer, size_t size)>
|
||||||
on_encoded_audio_buffer) {
|
on_encoded_audio_buffer) {
|
||||||
if (!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);
|
// printf("1 Time cost: %d size: %d\n", now_ts - last_ts, size);
|
||||||
// last_ts = now_ts;
|
// 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);
|
MAX_PACKET_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("opus decode failed, %d\n", ret);
|
printf("opus decode failed, %d\n", ret);
|
||||||
@@ -76,15 +76,7 @@ int AudioEncoder::Encode(
|
|||||||
|
|
||||||
if (on_encoded_audio_buffer_) {
|
if (on_encoded_audio_buffer_) {
|
||||||
on_encoded_audio_buffer_((char *)out_data, ret);
|
on_encoded_audio_buffer_((char *)out_data, ret);
|
||||||
} else {
|
|
||||||
OnEncodedAudioBuffer((char *)out_data, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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:
|
public:
|
||||||
int Init();
|
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)>
|
std::function<int(char* encoded_audio_buffer, size_t size)>
|
||||||
on_encoded_audio_buffer);
|
on_encoded_audio_buffer);
|
||||||
|
|
||||||
int OnEncodedAudioBuffer(char* encoded_audio_buffer, size_t size);
|
|
||||||
|
|
||||||
std::string GetEncoderName() { return "Opus"; }
|
std::string GetEncoderName() { return "Opus"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -27,230 +27,232 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <mutex>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock.h>
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
|
||||||
#pragma comment(lib, "ws2_32.lib")
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
#undef ERROR
|
#undef ERROR
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define SOCKET int
|
#define SOCKET int
|
||||||
#define INVALID_SOCKET -1
|
#define INVALID_SOCKET -1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum LogLevel {
|
enum LogLevel { TRACE, INFO, WARNING, ERROR, FATAL };
|
||||||
TRACE,
|
|
||||||
INFO,
|
|
||||||
WARNING,
|
|
||||||
ERROR,
|
|
||||||
FATAL
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace simplelogger{
|
namespace simplelogger {
|
||||||
class Logger {
|
class Logger {
|
||||||
public:
|
public:
|
||||||
Logger(LogLevel level, bool bPrintTimeStamp) : level(level), bPrintTimeStamp(bPrintTimeStamp) {}
|
Logger(LogLevel level, bool bPrintTimeStamp)
|
||||||
virtual ~Logger() {}
|
: level(level), bPrintTimeStamp(bPrintTimeStamp) {}
|
||||||
virtual std::ostream& GetStream() = 0;
|
virtual ~Logger() {}
|
||||||
virtual void FlushStream() {}
|
virtual std::ostream &GetStream() = 0;
|
||||||
bool ShouldLogFor(LogLevel l) {
|
virtual void FlushStream() {}
|
||||||
return l >= level;
|
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;
|
||||||
}
|
}
|
||||||
char* GetLead(LogLevel l, const char *szFile, int nLine, const char *szFunc) {
|
|
||||||
if (l < TRACE || l > FATAL) {
|
const char *szLevels[] = {"TRACE", "INFO", "WARN", "ERROR", "FATAL"};
|
||||||
sprintf(szLead, "[?????] ");
|
if (bPrintTimeStamp) {
|
||||||
return szLead;
|
time_t t = time(NULL);
|
||||||
}
|
struct tm *ptm = localtime(&t);
|
||||||
const char *szLevels[] = {"TRACE", "INFO", "WARN", "ERROR", "FATAL"};
|
sprintf(szLead, "[%-5s][%02d:%02d:%02d] ", szLevels[l], ptm->tm_hour,
|
||||||
if (bPrintTimeStamp) {
|
ptm->tm_min, ptm->tm_sec);
|
||||||
time_t t = time(NULL);
|
} else {
|
||||||
struct tm *ptm = localtime(&t);
|
sprintf(szLead, "[%-5s] ", szLevels[l]);
|
||||||
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() {
|
return szLead;
|
||||||
mtx.lock();
|
}
|
||||||
}
|
void EnterCriticalSection() { mtx.lock(); }
|
||||||
void LeaveCriticalSection() {
|
void LeaveCriticalSection() { mtx.unlock(); }
|
||||||
mtx.unlock();
|
|
||||||
}
|
private:
|
||||||
private:
|
LogLevel level;
|
||||||
LogLevel level;
|
char szLead[80];
|
||||||
char szLead[80];
|
bool bPrintTimeStamp;
|
||||||
bool bPrintTimeStamp;
|
std::mutex mtx;
|
||||||
std::mutex mtx;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LoggerFactory {
|
class LoggerFactory {
|
||||||
public:
|
public:
|
||||||
static Logger* CreateFileLogger(std::string strFilePath,
|
static Logger *CreateFileLogger(std::string strFilePath,
|
||||||
LogLevel level = INFO, bool bPrintTimeStamp = true) {
|
LogLevel level = INFO,
|
||||||
return new FileLogger(strFilePath, level, bPrintTimeStamp);
|
bool bPrintTimeStamp = true) {
|
||||||
}
|
return new FileLogger(strFilePath, level, bPrintTimeStamp);
|
||||||
static Logger* CreateConsoleLogger(LogLevel level = INFO,
|
}
|
||||||
bool bPrintTimeStamp = true) {
|
static Logger *CreateConsoleLogger(LogLevel level = INFO,
|
||||||
return new ConsoleLogger(level, bPrintTimeStamp);
|
bool bPrintTimeStamp = true) {
|
||||||
}
|
return new ConsoleLogger(level, bPrintTimeStamp);
|
||||||
static Logger* CreateUdpLogger(char *szHost, unsigned uPort, LogLevel level = INFO,
|
}
|
||||||
bool bPrintTimeStamp = true) {
|
static Logger *CreateUdpLogger(char *szHost, unsigned uPort,
|
||||||
return new UdpLogger(szHost, uPort, level, bPrintTimeStamp);
|
LogLevel level = INFO,
|
||||||
}
|
bool bPrintTimeStamp = true) {
|
||||||
private:
|
return new UdpLogger(szHost, uPort, level, bPrintTimeStamp);
|
||||||
LoggerFactory() {}
|
}
|
||||||
|
|
||||||
class FileLogger : public Logger {
|
private:
|
||||||
public:
|
LoggerFactory() {}
|
||||||
FileLogger(std::string strFilePath, LogLevel level, bool bPrintTimeStamp)
|
|
||||||
|
class FileLogger : public Logger {
|
||||||
|
public:
|
||||||
|
FileLogger(std::string strFilePath, LogLevel level, bool bPrintTimeStamp)
|
||||||
: Logger(level, bPrintTimeStamp) {
|
: Logger(level, bPrintTimeStamp) {
|
||||||
pFileOut = new std::ofstream();
|
pFileOut = new std::ofstream();
|
||||||
pFileOut->open(strFilePath.c_str());
|
pFileOut->open(strFilePath.c_str());
|
||||||
}
|
}
|
||||||
~FileLogger() {
|
~FileLogger() { pFileOut->close(); }
|
||||||
pFileOut->close();
|
std::ostream &GetStream() { return *pFileOut; }
|
||||||
}
|
|
||||||
std::ostream& GetStream() {
|
|
||||||
return *pFileOut;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
std::ofstream *pFileOut;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConsoleLogger : public Logger {
|
private:
|
||||||
public:
|
std::ofstream *pFileOut;
|
||||||
ConsoleLogger(LogLevel level, bool bPrintTimeStamp)
|
};
|
||||||
|
|
||||||
|
class ConsoleLogger : public Logger {
|
||||||
|
public:
|
||||||
|
ConsoleLogger(LogLevel level, bool bPrintTimeStamp)
|
||||||
: Logger(level, bPrintTimeStamp) {}
|
: Logger(level, bPrintTimeStamp) {}
|
||||||
std::ostream& GetStream() {
|
std::ostream &GetStream() { return std::cout; }
|
||||||
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) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
WSADATA w;
|
||||||
|
if (WSAStartup(0x0101, &w) != 0) {
|
||||||
|
fprintf(stderr, "WSAStartup() failed.\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (socket == INVALID_SOCKET) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
WSACleanup();
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "socket() failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#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};
|
||||||
|
#else
|
||||||
|
struct in_addr addr = {inet_addr(szHost)};
|
||||||
|
#endif
|
||||||
|
struct sockaddr_in s = {AF_INET, htons(uPort), addr};
|
||||||
|
server = s;
|
||||||
|
}
|
||||||
|
~UdpOstream() throw() {
|
||||||
|
if (socket == INVALID_SOCKET) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket(socket);
|
||||||
|
WSACleanup();
|
||||||
|
#else
|
||||||
|
close(socket);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void Flush() {
|
||||||
|
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("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::stringbuf sb;
|
||||||
|
SOCKET socket;
|
||||||
|
struct sockaddr_in server;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UdpLogger : public Logger {
|
public:
|
||||||
private:
|
UdpLogger(char *szHost, unsigned uPort, LogLevel level,
|
||||||
class UdpOstream : public std::ostream {
|
bool bPrintTimeStamp)
|
||||||
public:
|
: Logger(level, bPrintTimeStamp),
|
||||||
UdpOstream(char *szHost, unsigned short uPort) : std::ostream(&sb), socket(INVALID_SOCKET){
|
udpOut(szHost, (unsigned short)uPort) {}
|
||||||
#ifdef _WIN32
|
UdpOstream &GetStream() { return udpOut; }
|
||||||
WSADATA w;
|
virtual void FlushStream() { udpOut.Flush(); }
|
||||||
if (WSAStartup(0x0101, &w) != 0) {
|
|
||||||
fprintf(stderr, "WSAStartup() failed.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (socket == INVALID_SOCKET) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
WSACleanup();
|
|
||||||
#endif
|
|
||||||
fprintf(stderr, "socket() failed.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#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};
|
|
||||||
#else
|
|
||||||
struct in_addr addr = {inet_addr(szHost)};
|
|
||||||
#endif
|
|
||||||
struct sockaddr_in s = {AF_INET, htons(uPort), addr};
|
|
||||||
server = s;
|
|
||||||
}
|
|
||||||
~UdpOstream() throw() {
|
|
||||||
if (socket == INVALID_SOCKET) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
closesocket(socket);
|
|
||||||
WSACleanup();
|
|
||||||
#else
|
|
||||||
close(socket);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
void Flush() {
|
|
||||||
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("");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::stringbuf sb;
|
UdpOstream udpOut;
|
||||||
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();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
UdpOstream udpOut;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogTransaction {
|
class LogTransaction {
|
||||||
public:
|
public:
|
||||||
LogTransaction(Logger *pLogger, LogLevel level, const char *szFile, const int nLine, const char *szFunc) : pLogger(pLogger), level(level) {
|
LogTransaction(Logger *pLogger, LogLevel level, const char *szFile,
|
||||||
if (!pLogger) {
|
const int nLine, const char *szFunc)
|
||||||
std::cout << "[-----] ";
|
: pLogger(pLogger), level(level) {
|
||||||
return;
|
if (!pLogger) {
|
||||||
}
|
std::cout << "[-----] ";
|
||||||
if (!pLogger->ShouldLogFor(level)) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
pLogger->EnterCriticalSection();
|
|
||||||
pLogger->GetStream() << pLogger->GetLead(level, szFile, nLine, szFunc);
|
|
||||||
}
|
}
|
||||||
~LogTransaction() {
|
if (!pLogger->ShouldLogFor(level)) {
|
||||||
if (!pLogger) {
|
return;
|
||||||
std::cout << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!pLogger->ShouldLogFor(level)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pLogger->GetStream() << std::endl;
|
|
||||||
pLogger->FlushStream();
|
|
||||||
pLogger->LeaveCriticalSection();
|
|
||||||
if (level == FATAL) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std::ostream& GetStream() {
|
pLogger->EnterCriticalSection();
|
||||||
if (!pLogger) {
|
pLogger->GetStream() << pLogger->GetLead(level, szFile, nLine, szFunc);
|
||||||
return std::cout;
|
}
|
||||||
}
|
~LogTransaction() {
|
||||||
if (!pLogger->ShouldLogFor(level)) {
|
if (!pLogger) {
|
||||||
return ossNull;
|
std::cout << std::endl;
|
||||||
}
|
return;
|
||||||
return pLogger->GetStream();
|
|
||||||
}
|
}
|
||||||
private:
|
if (!pLogger->ShouldLogFor(level)) {
|
||||||
Logger *pLogger;
|
return;
|
||||||
LogLevel level;
|
}
|
||||||
std::ostringstream ossNull;
|
pLogger->GetStream() << std::endl;
|
||||||
|
pLogger->FlushStream();
|
||||||
|
pLogger->LeaveCriticalSection();
|
||||||
|
if (level == FATAL) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::ostream &GetStream() {
|
||||||
|
if (!pLogger) {
|
||||||
|
return std::cout;
|
||||||
|
}
|
||||||
|
if (!pLogger->ShouldLogFor(level)) {
|
||||||
|
return ossNull;
|
||||||
|
}
|
||||||
|
return pLogger->GetStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Logger *pLogger;
|
||||||
|
LogLevel level;
|
||||||
|
std::ostringstream ossNull;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace simplelogger
|
||||||
|
|
||||||
extern simplelogger::Logger *logger;
|
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
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
|
||||||
#include "NvDecoder.h"
|
#include "NvDecoder.h"
|
||||||
|
|
||||||
@@ -222,7 +224,7 @@ int NvDecoder::HandleVideoSequence(CUVIDEOFORMAT *pVideoFormat) {
|
|||||||
if (!decodecaps.bIsSupported) {
|
if (!decodecaps.bIsSupported) {
|
||||||
NVDEC_THROW_ERROR("Codec not supported on this GPU",
|
NVDEC_THROW_ERROR("Codec not supported on this GPU",
|
||||||
CUDA_ERROR_NOT_SUPPORTED);
|
CUDA_ERROR_NOT_SUPPORTED);
|
||||||
return nDecodeSurface;
|
// return nDecodeSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pVideoFormat->coded_width > decodecaps.nMaxWidth) ||
|
if ((pVideoFormat->coded_width > decodecaps.nMaxWidth) ||
|
||||||
@@ -237,7 +239,7 @@ int NvDecoder::HandleVideoSequence(CUVIDEOFORMAT *pVideoFormat) {
|
|||||||
|
|
||||||
const std::string cErr = errorString.str();
|
const std::string cErr = errorString.str();
|
||||||
NVDEC_THROW_ERROR(cErr, CUDA_ERROR_NOT_SUPPORTED);
|
NVDEC_THROW_ERROR(cErr, CUDA_ERROR_NOT_SUPPORTED);
|
||||||
return nDecodeSurface;
|
// return nDecodeSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pVideoFormat->coded_width >> 4) * (pVideoFormat->coded_height >> 4) >
|
if ((pVideoFormat->coded_width >> 4) * (pVideoFormat->coded_height >> 4) >
|
||||||
@@ -254,7 +256,7 @@ int NvDecoder::HandleVideoSequence(CUVIDEOFORMAT *pVideoFormat) {
|
|||||||
|
|
||||||
const std::string cErr = errorString.str();
|
const std::string cErr = errorString.str();
|
||||||
NVDEC_THROW_ERROR(cErr, CUDA_ERROR_NOT_SUPPORTED);
|
NVDEC_THROW_ERROR(cErr, CUDA_ERROR_NOT_SUPPORTED);
|
||||||
return nDecodeSurface;
|
// return nDecodeSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_nWidth && m_nLumaHeight && m_nChromaHeight) {
|
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) {
|
int NvDecoder::HandlePictureDecode(CUVIDPICPARAMS *pPicParams) {
|
||||||
if (!m_hDecoder) {
|
if (!m_hDecoder) {
|
||||||
NVDEC_THROW_ERROR("Decoder not initialized.", CUDA_ERROR_NOT_INITIALIZED);
|
NVDEC_THROW_ERROR("Decoder not initialized.", CUDA_ERROR_NOT_INITIALIZED);
|
||||||
return false;
|
// return false;
|
||||||
}
|
}
|
||||||
m_nPicNumInDecodeOrder[pPicParams->CurrPicIdx] = m_nDecodePicCnt++;
|
m_nPicNumInDecodeOrder[pPicParams->CurrPicIdx] = m_nDecodePicCnt++;
|
||||||
CUDA_DRVAPI_CALL(cuCtxPushCurrent(m_cuContext));
|
CUDA_DRVAPI_CALL(cuCtxPushCurrent(m_cuContext));
|
||||||
@@ -921,3 +923,4 @@ void NvDecoder::UnlockFrame(uint8_t **pFrame) {
|
|||||||
uint64_t timestamp[2] = {0};
|
uint64_t timestamp[2] = {0};
|
||||||
m_vTimestamp.insert(m_vTimestamp.end(), ×tamp[0], ×tamp[1]);
|
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;
|
return width * 4;
|
||||||
default:
|
default:
|
||||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t NvEncoder::GetNumChromaPlanes(
|
int32_t NvEncoder::GetNumChromaPlanes(const NV_ENC_BUFFER_FORMAT bufferFormat) {
|
||||||
const NV_ENC_BUFFER_FORMAT bufferFormat) {
|
|
||||||
switch (bufferFormat) {
|
switch (bufferFormat) {
|
||||||
case NV_ENC_BUFFER_FORMAT_NV12:
|
case NV_ENC_BUFFER_FORMAT_NV12:
|
||||||
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
|
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
|
||||||
@@ -792,12 +791,12 @@ uint32_t NvEncoder::GetNumChromaPlanes(
|
|||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
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) {
|
const uint32_t lumaPitch) {
|
||||||
switch (bufferFormat) {
|
switch (bufferFormat) {
|
||||||
case NV_ENC_BUFFER_FORMAT_NV12:
|
case NV_ENC_BUFFER_FORMAT_NV12:
|
||||||
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
|
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
|
||||||
@@ -815,7 +814,7 @@ uint32_t NvEncoder::GetChromaPitch(const NV_ENC_BUFFER_FORMAT bufferFormat,
|
|||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
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;
|
return 0;
|
||||||
default:
|
default:
|
||||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
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;
|
return 0;
|
||||||
default:
|
default:
|
||||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
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();
|
return 4 * GetEncodeWidth() * GetEncodeHeight();
|
||||||
default:
|
default:
|
||||||
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
|
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
|
* @brief This a static function to get the chroma plane pitch for YUV planar
|
||||||
* formats.
|
* 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);
|
const uint32_t lumaPitch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This a static function to get the number of chroma planes for YUV
|
* @brief This a static function to get the number of chroma planes for YUV
|
||||||
* planar formats.
|
* 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
|
* @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"
|
#include "log.h"
|
||||||
|
|
||||||
#define SAVE_RECEIVED_AV1_STREAM 0
|
// #define SAVE_DECODED_NV12_STREAM
|
||||||
#define SAVE_DECODED_NV12_STREAM 0
|
// #define SAVE_RECEIVED_AV1_STREAM
|
||||||
|
|
||||||
AomAv1Decoder::AomAv1Decoder() {}
|
AomAv1Decoder::AomAv1Decoder() {}
|
||||||
|
|
||||||
AomAv1Decoder::~AomAv1Decoder() {
|
AomAv1Decoder::~AomAv1Decoder() {
|
||||||
if (SAVE_RECEIVED_AV1_STREAM && file_av1_) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
fflush(file_av1_);
|
if (file_nv12_) {
|
||||||
fclose(file_av1_);
|
|
||||||
file_av1_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SAVE_DECODED_NV12_STREAM && file_nv12_) {
|
|
||||||
fflush(file_nv12_);
|
fflush(file_nv12_);
|
||||||
fclose(file_nv12_);
|
fclose(file_nv12_);
|
||||||
file_nv12_ = nullptr;
|
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_) {
|
if (nv12_frame_) {
|
||||||
delete nv12_frame_;
|
delete nv12_frame_;
|
||||||
@@ -43,29 +47,29 @@ int AomAv1Decoder::Init() {
|
|||||||
aom_codec_control(&aom_av1_decoder_ctx_, AV1D_GET_IMG_FORMAT,
|
aom_codec_control(&aom_av1_decoder_ctx_, AV1D_GET_IMG_FORMAT,
|
||||||
AOM_IMG_FMT_NV12);
|
AOM_IMG_FMT_NV12);
|
||||||
|
|
||||||
if (SAVE_RECEIVED_AV1_STREAM) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
file_av1_ = fopen("received_av1_stream.ivf", "w+b");
|
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
||||||
if (!file_av1_) {
|
if (!file_nv12_) {
|
||||||
LOG_WARN("Fail to open received_av1_stream.ivf");
|
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SAVE_DECODED_NV12_STREAM) {
|
#ifdef SAVE_RECEIVED_AV1_STREAM
|
||||||
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
file_av1_ = fopen("received_av1_stream.ivf", "w+b");
|
||||||
if (!file_nv12_) {
|
if (!file_av1_) {
|
||||||
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
LOG_WARN("Fail to open received_av1_stream.ivf");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AomAv1Decoder::Decode(
|
int AomAv1Decoder::Decode(
|
||||||
const uint8_t *data, int size,
|
const uint8_t *data, size_t size,
|
||||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
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_);
|
fwrite((unsigned char *)data, 1, size, file_av1_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
aom_codec_iter_t iter = nullptr;
|
aom_codec_iter_t iter = nullptr;
|
||||||
aom_codec_err_t ret =
|
aom_codec_err_t ret =
|
||||||
@@ -105,8 +109,8 @@ int AomAv1Decoder::Decode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int corrupted = 0;
|
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);
|
&corrupted);
|
||||||
if (ret != AOM_CODEC_OK) {
|
if (ret != AOM_CODEC_OK) {
|
||||||
LOG_ERROR("Failed to get frame corrupted");
|
LOG_ERROR("Failed to get frame corrupted");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -140,10 +144,10 @@ int AomAv1Decoder::Decode(
|
|||||||
|
|
||||||
on_receive_decoded_frame(*nv12_frame_);
|
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(),
|
fwrite((unsigned char *)nv12_frame_->Buffer(), 1, nv12_frame_->Size(),
|
||||||
file_nv12_);
|
file_nv12_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class AomAv1Decoder : public VideoDecoder {
|
|||||||
public:
|
public:
|
||||||
int Init();
|
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::function<void(VideoFrame)> on_receive_decoded_frame);
|
||||||
|
|
||||||
std::string GetDecoderName() { return "AomAv1"; }
|
std::string GetDecoderName() { return "AomAv1"; }
|
||||||
@@ -32,8 +32,8 @@ class AomAv1Decoder : public VideoDecoder {
|
|||||||
int nv12_frame_capacity_ = 0;
|
int nv12_frame_capacity_ = 0;
|
||||||
int nv12_frame_size_ = 0;
|
int nv12_frame_size_ = 0;
|
||||||
|
|
||||||
int frame_width_ = 0;
|
uint32_t frame_width_ = 0;
|
||||||
int frame_height_ = 0;
|
uint32_t frame_height_ = 0;
|
||||||
|
|
||||||
FILE *file_av1_ = nullptr;
|
FILE *file_av1_ = nullptr;
|
||||||
FILE *file_nv12_ = nullptr;
|
FILE *file_nv12_ = nullptr;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#define SAVE_RECEIVED_AV1_STREAM 0
|
// #define SAVE_DECODED_NV12_STREAM
|
||||||
#define SAVE_DECODED_NV12_STREAM 0
|
// #define SAVE_RECEIVED_AV1_STREAM
|
||||||
|
|
||||||
#include "libyuv.h"
|
#include "libyuv.h"
|
||||||
|
|
||||||
@@ -28,7 +28,8 @@ class ScopedDav1dData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Calling `dav1d_data_wrap` requires a `free_callback` to be registered.
|
// 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,
|
void Yuv420pToNv12(unsigned char *SrcY, unsigned char *SrcU,
|
||||||
unsigned char *SrcV, int y_stride, int uv_stride,
|
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() {}
|
||||||
|
|
||||||
Dav1dAv1Decoder::~Dav1dAv1Decoder() {
|
Dav1dAv1Decoder::~Dav1dAv1Decoder() {
|
||||||
if (SAVE_RECEIVED_AV1_STREAM && file_av1_) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
fflush(file_av1_);
|
if (file_nv12_) {
|
||||||
fclose(file_av1_);
|
|
||||||
file_av1_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SAVE_DECODED_NV12_STREAM && file_nv12_) {
|
|
||||||
fflush(file_nv12_);
|
fflush(file_nv12_);
|
||||||
fclose(file_nv12_);
|
fclose(file_nv12_);
|
||||||
file_nv12_ = nullptr;
|
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_) {
|
if (nv12_frame_) {
|
||||||
delete nv12_frame_;
|
delete nv12_frame_;
|
||||||
@@ -83,29 +88,29 @@ int Dav1dAv1Decoder::Init() {
|
|||||||
LOG_ERROR("Dav1d AV1 decoder open failed");
|
LOG_ERROR("Dav1d AV1 decoder open failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SAVE_RECEIVED_AV1_STREAM) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
file_av1_ = fopen("received_av1_stream.ivf", "w+b");
|
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
||||||
if (!file_av1_) {
|
if (!file_nv12_) {
|
||||||
LOG_WARN("Fail to open received_av1_stream.ivf");
|
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SAVE_DECODED_NV12_STREAM) {
|
#ifdef SAVE_RECEIVED_AV1_STREAM
|
||||||
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
file_av1_ = fopen("received_av1_stream.ivf", "w+b");
|
||||||
if (!file_nv12_) {
|
if (!file_av1_) {
|
||||||
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
LOG_WARN("Fail to open received_av1_stream.ivf");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Dav1dAv1Decoder::Decode(
|
int Dav1dAv1Decoder::Decode(
|
||||||
const uint8_t *data, int size,
|
const uint8_t *data, size_t size,
|
||||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
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_);
|
fwrite((unsigned char *)data, 1, size, file_av1_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
ScopedDav1dData scoped_dav1d_data;
|
ScopedDav1dData scoped_dav1d_data;
|
||||||
Dav1dData &dav1d_data = scoped_dav1d_data.Data();
|
Dav1dData &dav1d_data = scoped_dav1d_data.Data();
|
||||||
@@ -176,14 +181,14 @@ int Dav1dAv1Decoder::Decode(
|
|||||||
Yuv420pToNv12((unsigned char *)dav1d_picture.data[0],
|
Yuv420pToNv12((unsigned char *)dav1d_picture.data[0],
|
||||||
(unsigned char *)dav1d_picture.data[1],
|
(unsigned char *)dav1d_picture.data[1],
|
||||||
(unsigned char *)dav1d_picture.data[2],
|
(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_,
|
(unsigned char *)nv12_frame_->Buffer(), frame_width_,
|
||||||
frame_height_);
|
frame_height_);
|
||||||
} else {
|
} else {
|
||||||
libyuv::I420ToNV12(
|
libyuv::I420ToNV12(
|
||||||
(const uint8_t *)dav1d_picture.data[0], dav1d_picture.stride[0],
|
(const uint8_t *)dav1d_picture.data[0], (int)dav1d_picture.stride[0],
|
||||||
(const uint8_t *)dav1d_picture.data[1], dav1d_picture.stride[1],
|
(const uint8_t *)dav1d_picture.data[1], (int)dav1d_picture.stride[1],
|
||||||
(const uint8_t *)dav1d_picture.data[2], 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_,
|
||||||
(uint8_t *)nv12_frame_->Buffer() + frame_width_ * frame_height_,
|
(uint8_t *)nv12_frame_->Buffer() + frame_width_ * frame_height_,
|
||||||
frame_width_, frame_width_, frame_height_);
|
frame_width_, frame_width_, frame_height_);
|
||||||
@@ -191,10 +196,10 @@ int Dav1dAv1Decoder::Decode(
|
|||||||
|
|
||||||
on_receive_decoded_frame(*nv12_frame_);
|
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(),
|
fwrite((unsigned char *)nv12_frame_->Buffer(), 1, nv12_frame_->Size(),
|
||||||
file_nv12_);
|
file_nv12_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -20,18 +20,18 @@ class Dav1dAv1Decoder : public VideoDecoder {
|
|||||||
public:
|
public:
|
||||||
int Init();
|
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::function<void(VideoFrame)> on_receive_decoded_frame);
|
||||||
|
|
||||||
std::string GetDecoderName() { return "Dav1dAv1"; }
|
std::string GetDecoderName() { return "Dav1dAv1"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VideoFrame *nv12_frame_ = 0;
|
VideoFrame *nv12_frame_ = 0;
|
||||||
int nv12_frame_capacity_ = 0;
|
size_t nv12_frame_capacity_ = 0;
|
||||||
int nv12_frame_size_ = 0;
|
size_t nv12_frame_size_ = 0;
|
||||||
|
|
||||||
int frame_width_ = 0;
|
uint32_t frame_width_ = 0;
|
||||||
int frame_height_ = 0;
|
uint32_t frame_height_ = 0;
|
||||||
|
|
||||||
FILE *file_av1_ = nullptr;
|
FILE *file_av1_ = nullptr;
|
||||||
FILE *file_nv12_ = nullptr;
|
FILE *file_nv12_ = nullptr;
|
||||||
|
|||||||
@@ -3,22 +3,26 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "nvcodec_api.h"
|
#include "nvcodec_api.h"
|
||||||
|
|
||||||
#define SAVE_RECEIVED_H264_STREAM 0
|
// #define SAVE_DECODED_NV12_STREAM
|
||||||
#define SAVE_DECODED_NV12_STREAM 0
|
// #define SAVE_RECEIVED_H264_STREAM
|
||||||
|
|
||||||
NvidiaVideoDecoder::NvidiaVideoDecoder() {}
|
NvidiaVideoDecoder::NvidiaVideoDecoder() {}
|
||||||
NvidiaVideoDecoder::~NvidiaVideoDecoder() {
|
NvidiaVideoDecoder::~NvidiaVideoDecoder() {
|
||||||
if (SAVE_RECEIVED_H264_STREAM && file_h264_) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
fflush(file_h264_);
|
if (file_nv12_) {
|
||||||
fclose(file_h264_);
|
|
||||||
file_h264_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SAVE_DECODED_NV12_STREAM && file_nv12_) {
|
|
||||||
fflush(file_nv12_);
|
fflush(file_nv12_);
|
||||||
fclose(file_nv12_);
|
fclose(file_nv12_);
|
||||||
file_nv12_ = nullptr;
|
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() {
|
int NvidiaVideoDecoder::Init() {
|
||||||
@@ -42,55 +46,55 @@ int NvidiaVideoDecoder::Init() {
|
|||||||
|
|
||||||
decoder = new NvDecoder(cuContext, false, cudaVideoCodec_H264, true);
|
decoder = new NvDecoder(cuContext, false, cudaVideoCodec_H264, true);
|
||||||
|
|
||||||
if (SAVE_RECEIVED_H264_STREAM) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
file_h264_ = fopen("received_h264_stream.h264", "w+b");
|
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
||||||
if (!file_h264_) {
|
if (!file_nv12_) {
|
||||||
LOG_WARN("Fail to open received_h264_stream.h264");
|
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SAVE_DECODED_NV12_STREAM) {
|
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||||
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
file_h264_ = fopen("received_h264_stream.h264", "w+b");
|
||||||
if (!file_nv12_) {
|
if (!file_h264_) {
|
||||||
LOG_WARN("Fail to open decoded_nv12_stream.yuv");
|
LOG_WARN("Fail to open received_h264_stream.h264");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NvidiaVideoDecoder::Decode(
|
int NvidiaVideoDecoder::Decode(
|
||||||
const uint8_t *data, int size,
|
const uint8_t *data, size_t size,
|
||||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
||||||
if (!decoder) {
|
if (!decoder) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SAVE_RECEIVED_H264_STREAM) {
|
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||||
fwrite((unsigned char *)data, 1, size, file_h264_);
|
fwrite((unsigned char *)data, 1, size, file_h264_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
if ((*(data + 4) & 0x1f) == 0x07) {
|
if ((*(data + 4) & 0x1f) == 0x07) {
|
||||||
// LOG_WARN("Receive key frame");
|
// 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) {
|
for (size_t i = 0; i < num_frame_returned; ++i) {
|
||||||
cudaVideoSurfaceFormat format = decoder->GetOutputFormat();
|
cudaVideoSurfaceFormat format = decoder->GetOutputFormat();
|
||||||
if (format == cudaVideoSurfaceFormat_NV12) {
|
if (format == cudaVideoSurfaceFormat_NV12) {
|
||||||
uint8_t *data = nullptr;
|
uint8_t *decoded_frame_buffer = nullptr;
|
||||||
data = decoder->GetFrame();
|
decoded_frame_buffer = decoder->GetFrame();
|
||||||
if (data) {
|
if (decoded_frame_buffer) {
|
||||||
if (on_receive_decoded_frame) {
|
if (on_receive_decoded_frame) {
|
||||||
VideoFrame 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());
|
decoder->GetWidth(), decoder->GetHeight());
|
||||||
on_receive_decoded_frame(decoded_frame);
|
on_receive_decoded_frame(decoded_frame);
|
||||||
if (SAVE_DECODED_NV12_STREAM) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
fwrite((unsigned char *)decoded_frame.Buffer(), 1,
|
fwrite((unsigned char *)decoded_frame.Buffer(), 1,
|
||||||
decoded_frame.Size(), file_nv12_);
|
decoded_frame.Size(), file_nv12_);
|
||||||
}
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class NvidiaVideoDecoder : public VideoDecoder {
|
|||||||
public:
|
public:
|
||||||
int Init();
|
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::function<void(VideoFrame)> on_receive_decoded_frame);
|
||||||
|
|
||||||
std::string GetDecoderName() { return "NvidiaH264"; }
|
std::string GetDecoderName() { return "NvidiaH264"; }
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
#include "libyuv.h"
|
#include "libyuv.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#define SAVE_NV12_STREAM 0
|
// #define SAVE_DECODED_NV12_STREAM
|
||||||
#define SAVE_H264_STREAM 0
|
// #define SAVE_RECEIVED_H264_STREAM
|
||||||
|
|
||||||
void CopyYuvWithStride(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v,
|
void CopyYuvWithStride(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v,
|
||||||
int width, int height, int stride_y, int stride_u,
|
int width, int height, int stride_y, int stride_u,
|
||||||
@@ -65,31 +65,35 @@ OpenH264Decoder::~OpenH264Decoder() {
|
|||||||
delete[] yuv420p_frame_;
|
delete[] yuv420p_frame_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SAVE_H264_STREAM && h264_stream_) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
fflush(h264_stream_);
|
if (nv12_stream_) {
|
||||||
h264_stream_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SAVE_NV12_STREAM && nv12_stream_) {
|
|
||||||
fflush(nv12_stream_);
|
fflush(nv12_stream_);
|
||||||
nv12_stream_ = nullptr;
|
nv12_stream_ = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||||
|
if (h264_stream_) {
|
||||||
|
fflush(h264_stream_);
|
||||||
|
h264_stream_ = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int OpenH264Decoder::Init() {
|
int OpenH264Decoder::Init() {
|
||||||
if (SAVE_NV12_STREAM) {
|
#ifdef SAVE_DECODED_NV12_STREAM
|
||||||
nv12_stream_ = fopen("nv12_receive_.yuv", "w+b");
|
nv12_stream_ = fopen("nv12_receive_.yuv", "w+b");
|
||||||
if (!nv12_stream_) {
|
if (!nv12_stream_) {
|
||||||
LOG_WARN("Fail to open nv12_receive_.yuv");
|
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");
|
h264_stream_ = fopen("h264_receive.h264", "w+b");
|
||||||
if (!h264_stream_) {
|
if (!h264_stream_) {
|
||||||
LOG_WARN("Fail to open h264_receive.h264");
|
LOG_WARN("Fail to open h264_receive.h264");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
frame_width_ = 1280;
|
frame_width_ = 1280;
|
||||||
frame_height_ = 720;
|
frame_height_ = 720;
|
||||||
@@ -115,15 +119,15 @@ int OpenH264Decoder::Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int OpenH264Decoder::Decode(
|
int OpenH264Decoder::Decode(
|
||||||
const uint8_t *data, int size,
|
const uint8_t *data, size_t size,
|
||||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
||||||
if (!openh264_decoder_) {
|
if (!openh264_decoder_) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SAVE_H264_STREAM) {
|
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||||
fwrite((unsigned char *)data, 1, size, h264_stream_);
|
fwrite((unsigned char *)data, 1, size, h264_stream_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
if ((*(data + 4) & 0x1f) == 0x07) {
|
if ((*(data + 4) & 0x1f) == 0x07) {
|
||||||
// LOG_WARN("Receive key frame");
|
// LOG_WARN("Receive key frame");
|
||||||
@@ -132,7 +136,7 @@ int OpenH264Decoder::Decode(
|
|||||||
SBufferInfo sDstBufInfo;
|
SBufferInfo sDstBufInfo;
|
||||||
memset(&sDstBufInfo, 0, sizeof(SBufferInfo));
|
memset(&sDstBufInfo, 0, sizeof(SBufferInfo));
|
||||||
|
|
||||||
openh264_decoder_->DecodeFrameNoDelay(data, size, yuv420p_planes_,
|
openh264_decoder_->DecodeFrameNoDelay(data, (int)size, yuv420p_planes_,
|
||||||
&sDstBufInfo);
|
&sDstBufInfo);
|
||||||
|
|
||||||
frame_width_ = sDstBufInfo.UsrData.sSystemBuffer.iWidth;
|
frame_width_ = sDstBufInfo.UsrData.sSystemBuffer.iWidth;
|
||||||
@@ -200,10 +204,10 @@ int OpenH264Decoder::Decode(
|
|||||||
|
|
||||||
on_receive_decoded_frame(*nv12_frame_);
|
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(),
|
fwrite((unsigned char *)nv12_frame_->Buffer(), 1, nv12_frame_->Size(),
|
||||||
nv12_stream_);
|
nv12_stream_);
|
||||||
}
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class OpenH264Decoder : public VideoDecoder {
|
|||||||
public:
|
public:
|
||||||
int Init();
|
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::function<void(VideoFrame)> on_receive_decoded_frame);
|
||||||
|
|
||||||
std::string GetDecoderName() { return "OpenH264"; }
|
std::string GetDecoderName() { return "OpenH264"; }
|
||||||
@@ -37,8 +37,8 @@ class OpenH264Decoder : public VideoDecoder {
|
|||||||
FILE* h264_stream_ = nullptr;
|
FILE* h264_stream_ = nullptr;
|
||||||
uint8_t* decoded_frame_ = nullptr;
|
uint8_t* decoded_frame_ = nullptr;
|
||||||
int decoded_frame_size_ = 0;
|
int decoded_frame_size_ = 0;
|
||||||
int frame_width_ = 1280;
|
uint32_t frame_width_ = 1280;
|
||||||
int frame_height_ = 720;
|
uint32_t frame_height_ = 720;
|
||||||
|
|
||||||
unsigned char* yuv420p_planes_[3] = {nullptr, nullptr, nullptr};
|
unsigned char* yuv420p_planes_[3] = {nullptr, nullptr, nullptr};
|
||||||
unsigned char* yuv420p_frame_ = nullptr;
|
unsigned char* yuv420p_frame_ = nullptr;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class VideoDecoder {
|
|||||||
virtual int Init() = 0;
|
virtual int Init() = 0;
|
||||||
|
|
||||||
virtual int Decode(
|
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;
|
std::function<void(VideoFrame)> on_receive_decoded_frame) = 0;
|
||||||
|
|
||||||
virtual std::string GetDecoderName() = 0;
|
virtual std::string GetDecoderName() = 0;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#define SAVE_RECEIVED_NV12_STREAM 0
|
// #define SAVE_RECEIVED_NV12_STREAM
|
||||||
#define SAVE_ENCODED_AV1_STREAM 0
|
// #define SAVE_ENCODED_AV1_STREAM
|
||||||
|
|
||||||
#define SET_ENCODER_PARAM_OR_RETURN_ERROR(param_id, param_value) \
|
#define SET_ENCODER_PARAM_OR_RETURN_ERROR(param_id, param_value) \
|
||||||
do { \
|
do { \
|
||||||
@@ -104,17 +104,21 @@ int AomAv1Encoder::ResetEncodeResolution(unsigned int width,
|
|||||||
AomAv1Encoder::AomAv1Encoder() {}
|
AomAv1Encoder::AomAv1Encoder() {}
|
||||||
|
|
||||||
AomAv1Encoder::~AomAv1Encoder() {
|
AomAv1Encoder::~AomAv1Encoder() {
|
||||||
if (SAVE_RECEIVED_NV12_STREAM && file_nv12_) {
|
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||||
|
if (file_nv12_) {
|
||||||
fflush(file_nv12_);
|
fflush(file_nv12_);
|
||||||
fclose(file_nv12_);
|
fclose(file_nv12_);
|
||||||
file_nv12_ = nullptr;
|
file_nv12_ = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SAVE_ENCODED_AV1_STREAM && file_av1_) {
|
#ifdef SAVE_ENCODED_AV1_STREAM
|
||||||
|
if (file_av1_) {
|
||||||
fflush(file_av1_);
|
fflush(file_av1_);
|
||||||
fclose(file_av1_);
|
fclose(file_av1_);
|
||||||
file_av1_ = nullptr;
|
file_av1_ = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
delete[] encoded_frame_;
|
delete[] encoded_frame_;
|
||||||
encoded_frame_ = nullptr;
|
encoded_frame_ = nullptr;
|
||||||
@@ -245,19 +249,19 @@ int AomAv1Encoder::Init() {
|
|||||||
frame_for_encode_ = aom_img_wrap(nullptr, AOM_IMG_FMT_NV12, frame_width_,
|
frame_for_encode_ = aom_img_wrap(nullptr, AOM_IMG_FMT_NV12, frame_width_,
|
||||||
frame_height_, 1, nullptr);
|
frame_height_, 1, nullptr);
|
||||||
|
|
||||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||||
file_nv12_ = fopen("received_nv12_stream.yuv", "w+b");
|
file_nv12_ = fopen("received_nv12_stream.yuv", "w+b");
|
||||||
if (!file_nv12_) {
|
if (!file_nv12_) {
|
||||||
LOG_ERROR("Fail to open received_nv12_stream.yuv");
|
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");
|
file_av1_ = fopen("encoded_av1_stream.ivf", "w+b");
|
||||||
if (!file_av1_) {
|
if (!file_av1_) {
|
||||||
LOG_ERROR("Fail to open encoded_av1_stream.ivf");
|
LOG_ERROR("Fail to open encoded_av1_stream.ivf");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -266,9 +270,9 @@ int AomAv1Encoder::Encode(const XVideoFrame *video_frame,
|
|||||||
std::function<int(char *encoded_packets, size_t size,
|
std::function<int(char *encoded_packets, size_t size,
|
||||||
VideoFrameType frame_type)>
|
VideoFrameType frame_type)>
|
||||||
on_encoded_image) {
|
on_encoded_image) {
|
||||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||||
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
aom_codec_err_t ret = AOM_CODEC_OK;
|
aom_codec_err_t ret = AOM_CODEC_OK;
|
||||||
|
|
||||||
@@ -293,7 +297,7 @@ int AomAv1Encoder::Encode(const XVideoFrame *video_frame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t duration =
|
const uint32_t duration =
|
||||||
kRtpTicksPerSecond / static_cast<float>(max_frame_rate_);
|
(uint32_t)(kRtpTicksPerSecond / static_cast<float>(max_frame_rate_));
|
||||||
timestamp_ += duration;
|
timestamp_ += duration;
|
||||||
|
|
||||||
frame_for_encode_->planes[AOM_PLANE_Y] = (unsigned char *)(video_frame->data);
|
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;
|
aom_codec_iter_t iter = nullptr;
|
||||||
int data_pkt_count = 0;
|
|
||||||
while (const aom_codec_cx_pkt_t *pkt =
|
while (const aom_codec_cx_pkt_t *pkt =
|
||||||
aom_codec_get_cx_data(&aom_av1_encoder_ctx_, &iter)) {
|
aom_codec_get_cx_data(&aom_av1_encoder_ctx_, &iter)) {
|
||||||
if (pkt->kind == AOM_CODEC_CX_FRAME_PKT && pkt->data.frame.sz > 0) {
|
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) {
|
if (on_encoded_image) {
|
||||||
on_encoded_image((char *)encoded_frame_, encoded_frame_size_,
|
on_encoded_image((char *)encoded_frame_, encoded_frame_size_,
|
||||||
frame_type);
|
frame_type);
|
||||||
if (SAVE_ENCODED_AV1_STREAM) {
|
#ifdef SAVE_ENCODED_AV1_STREAM
|
||||||
fwrite(encoded_frame_, 1, encoded_frame_size_, file_av1_);
|
fwrite(encoded_frame_, 1, encoded_frame_size_, file_av1_);
|
||||||
}
|
#endif
|
||||||
} else {
|
|
||||||
OnEncodedImage((char *)encoded_frame_, encoded_frame_size_);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,11 +354,6 @@ int AomAv1Encoder::Encode(const XVideoFrame *video_frame,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AomAv1Encoder::OnEncodedImage(char *encoded_packets, size_t size) {
|
|
||||||
LOG_INFO("OnEncodedImage not implemented");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AomAv1Encoder::ForceIdr() {
|
int AomAv1Encoder::ForceIdr() {
|
||||||
force_i_frame_flags_ = AOM_EFLAG_FORCE_KF;
|
force_i_frame_flags_ = AOM_EFLAG_FORCE_KF;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -36,20 +36,12 @@ class AomAv1Encoder : public VideoEncoder {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
int Init();
|
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,
|
int Encode(const XVideoFrame* video_frame,
|
||||||
std::function<int(char* encoded_packets, size_t size,
|
std::function<int(char* encoded_packets, size_t size,
|
||||||
VideoFrameType frame_type)>
|
VideoFrameType frame_type)>
|
||||||
on_encoded_image);
|
on_encoded_image);
|
||||||
|
|
||||||
int OnEncodedImage(char* encoded_packets, size_t size);
|
|
||||||
|
|
||||||
int ForceIdr();
|
int ForceIdr();
|
||||||
|
|
||||||
std::string GetEncoderName() { return "AomAV1"; }
|
std::string GetEncoderName() { return "AomAV1"; }
|
||||||
@@ -65,8 +57,8 @@ class AomAv1Encoder : public VideoEncoder {
|
|||||||
int Release();
|
int Release();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int frame_width_ = 1280;
|
uint32_t frame_width_ = 1280;
|
||||||
int frame_height_ = 720;
|
uint32_t frame_height_ = 720;
|
||||||
int key_frame_interval_ = 300;
|
int key_frame_interval_ = 300;
|
||||||
int target_bitrate_ = 1000;
|
int target_bitrate_ = 1000;
|
||||||
int max_bitrate_ = 2500000;
|
int max_bitrate_ = 2500000;
|
||||||
@@ -91,7 +83,7 @@ class AomAv1Encoder : public VideoEncoder {
|
|||||||
aom_enc_frame_flags_t force_i_frame_flags_ = 0;
|
aom_enc_frame_flags_t force_i_frame_flags_ = 0;
|
||||||
uint8_t* encoded_frame_ = nullptr;
|
uint8_t* encoded_frame_ = nullptr;
|
||||||
size_t encoded_frame_capacity_ = 0;
|
size_t encoded_frame_capacity_ = 0;
|
||||||
int encoded_frame_size_ = 0;
|
size_t encoded_frame_size_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -6,22 +6,26 @@
|
|||||||
#include "nvcodec_api.h"
|
#include "nvcodec_api.h"
|
||||||
#include "nvcodec_common.h"
|
#include "nvcodec_common.h"
|
||||||
|
|
||||||
#define SAVE_RECEIVED_NV12_STREAM 0
|
// #define SAVE_RECEIVED_NV12_STREAM
|
||||||
#define SAVE_ENCODED_H264_STREAM 0
|
// #define SAVE_ENCODED_H264_STREAM
|
||||||
|
|
||||||
NvidiaVideoEncoder::NvidiaVideoEncoder() {}
|
NvidiaVideoEncoder::NvidiaVideoEncoder() {}
|
||||||
NvidiaVideoEncoder::~NvidiaVideoEncoder() {
|
NvidiaVideoEncoder::~NvidiaVideoEncoder() {
|
||||||
if (SAVE_RECEIVED_NV12_STREAM && file_nv12_) {
|
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||||
|
if (file_nv12_) {
|
||||||
fflush(file_nv12_);
|
fflush(file_nv12_);
|
||||||
fclose(file_nv12_);
|
fclose(file_nv12_);
|
||||||
file_nv12_ = nullptr;
|
file_nv12_ = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SAVE_ENCODED_H264_STREAM && file_h264_) {
|
#ifdef SAVE_ENCODED_H264_STREAM
|
||||||
|
if (file_h264_) {
|
||||||
fflush(file_h264_);
|
fflush(file_h264_);
|
||||||
fclose(file_h264_);
|
fclose(file_h264_);
|
||||||
file_h264_ = nullptr;
|
file_h264_ = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (nv12_data_) {
|
if (nv12_data_) {
|
||||||
free(nv12_data_);
|
free(nv12_data_);
|
||||||
@@ -106,19 +110,20 @@ int NvidiaVideoEncoder::Init() {
|
|||||||
|
|
||||||
encoder_->CreateEncoder(&init_params);
|
encoder_->CreateEncoder(&init_params);
|
||||||
|
|
||||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||||
file_nv12_ = fopen("received_nv12_stream.yuv", "w+b");
|
file_nv12_ = fopen("received_nv12_stream.yuv", "w+b");
|
||||||
if (!file_nv12_) {
|
if (!file_nv12_) {
|
||||||
LOG_WARN("Fail to open received_nv12_stream.yuv");
|
LOG_WARN("Fail to open received_nv12_stream.yuv");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SAVE_ENCODED_H264_STREAM) {
|
#endif
|
||||||
file_h264_ = fopen("encoded_h264_stream.h264", "w+b");
|
|
||||||
if (!file_h264_) {
|
#ifdef SAVE_ENCODED_H264_STREAM
|
||||||
LOG_WARN("Fail to open encoded_h264_stream.h264");
|
file_h264_ = fopen("encoded_h264_stream.h264", "w+b");
|
||||||
}
|
if (!file_h264_) {
|
||||||
|
LOG_WARN("Fail to open encoded_h264_stream.h264");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -133,9 +138,9 @@ int NvidiaVideoEncoder::Encode(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||||
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
if (video_frame->width != frame_width_ ||
|
if (video_frame->width != frame_width_ ||
|
||||||
video_frame->height != frame_height_) {
|
video_frame->height != frame_height_) {
|
||||||
@@ -178,11 +183,9 @@ int NvidiaVideoEncoder::Encode(
|
|||||||
for (const auto &packet : encoded_packets_) {
|
for (const auto &packet : encoded_packets_) {
|
||||||
if (on_encoded_image) {
|
if (on_encoded_image) {
|
||||||
on_encoded_image((char *)packet.data(), packet.size(), frame_type);
|
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_);
|
fwrite((unsigned char *)packet.data(), 1, packet.size(), file_h264_);
|
||||||
}
|
#endif
|
||||||
} else {
|
|
||||||
OnEncodedImage((char *)packet.data(), packet.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,11 +199,6 @@ int NvidiaVideoEncoder::Encode(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NvidiaVideoEncoder::OnEncodedImage(char *encoded_packets, size_t size) {
|
|
||||||
LOG_INFO("OnEncodedImage not implemented");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NvidiaVideoEncoder::ForceIdr() {
|
int NvidiaVideoEncoder::ForceIdr() {
|
||||||
if (!encoder_) {
|
if (!encoder_) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -12,20 +12,12 @@ class NvidiaVideoEncoder : public VideoEncoder {
|
|||||||
virtual ~NvidiaVideoEncoder();
|
virtual ~NvidiaVideoEncoder();
|
||||||
|
|
||||||
int Init();
|
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,
|
int Encode(const XVideoFrame* video_frame,
|
||||||
std::function<int(char* encoded_packets, size_t size,
|
std::function<int(char* encoded_packets, size_t size,
|
||||||
VideoFrameType frame_type)>
|
VideoFrameType frame_type)>
|
||||||
on_encoded_image);
|
on_encoded_image);
|
||||||
|
|
||||||
virtual int OnEncodedImage(char* encoded_packets, size_t size);
|
|
||||||
|
|
||||||
int ForceIdr();
|
int ForceIdr();
|
||||||
|
|
||||||
std::string GetEncoderName() { return "NvidiaH264"; }
|
std::string GetEncoderName() { return "NvidiaH264"; }
|
||||||
|
|||||||
@@ -5,17 +5,15 @@
|
|||||||
#include "libyuv.h"
|
#include "libyuv.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#define SAVE_RECEIVED_NV12_STREAM 0
|
// #define SAVE_RECEIVED_NV12_STREAM
|
||||||
#define SAVE_ENCODED_H264_STREAM 0
|
// #define SAVE_ENCODED_H264_STREAM
|
||||||
|
|
||||||
void Nv12ToI420(unsigned char *Src_data, int src_width, int src_height,
|
void Nv12ToI420(unsigned char *Src_data, int src_width, int src_height,
|
||||||
unsigned char *Dst_data) {
|
unsigned char *Dst_data) {
|
||||||
// NV12 video size
|
// NV12
|
||||||
int NV12_Size = src_width * src_height * 3 / 2;
|
|
||||||
int NV12_Y_Size = src_width * src_height;
|
int NV12_Y_Size = src_width * src_height;
|
||||||
|
|
||||||
// YUV420 video size
|
// YUV420
|
||||||
int I420_Size = src_width * src_height * 3 / 2;
|
|
||||||
int I420_Y_Size = src_width * src_height;
|
int I420_Y_Size = src_width * src_height;
|
||||||
int I420_U_Size = (src_width >> 1) * (src_height >> 1);
|
int I420_U_Size = (src_width >> 1) * (src_height >> 1);
|
||||||
int I420_V_Size = I420_U_Size;
|
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
|
// dst: buffer address of Y channel、U channel and V channel
|
||||||
unsigned char *Y_data_Dst = Dst_data;
|
unsigned char *Y_data_Dst = Dst_data;
|
||||||
unsigned char *U_data_Dst = Dst_data + I420_Y_Size;
|
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_Y = src_width;
|
||||||
int Dst_Stride_U = src_width >> 1;
|
int Dst_Stride_U = src_width >> 1;
|
||||||
int Dst_Stride_V = Dst_Stride_U;
|
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() {}
|
||||||
|
|
||||||
OpenH264Encoder::~OpenH264Encoder() {
|
OpenH264Encoder::~OpenH264Encoder() {
|
||||||
if (SAVE_RECEIVED_NV12_STREAM && file_nv12_) {
|
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||||
|
if (file_nv12_) {
|
||||||
fflush(file_nv12_);
|
fflush(file_nv12_);
|
||||||
fclose(file_nv12_);
|
fclose(file_nv12_);
|
||||||
file_nv12_ = nullptr;
|
file_nv12_ = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SAVE_ENCODED_H264_STREAM && file_h264_) {
|
#ifdef SAVE_ENCODED_H264_STREAM
|
||||||
|
if (file_h264_) {
|
||||||
fflush(file_h264_);
|
fflush(file_h264_);
|
||||||
fclose(file_h264_);
|
fclose(file_h264_);
|
||||||
file_h264_ = nullptr;
|
file_h264_ = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (yuv420p_frame_) {
|
if (yuv420p_frame_) {
|
||||||
delete[] yuv420p_frame_;
|
delete[] yuv420p_frame_;
|
||||||
@@ -160,19 +162,19 @@ int OpenH264Encoder::Init() {
|
|||||||
video_format_ = EVideoFormatType::videoFormatI420;
|
video_format_ = EVideoFormatType::videoFormatI420;
|
||||||
openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT, &video_format_);
|
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");
|
file_nv12_ = fopen("received_nv12_stream.yuv", "w+b");
|
||||||
if (!file_nv12_) {
|
if (!file_nv12_) {
|
||||||
LOG_WARN("Fail to open received_nv12_stream.yuv");
|
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");
|
file_h264_ = fopen("encoded_h264_stream.h264", "w+b");
|
||||||
if (!file_h264_) {
|
if (!file_h264_) {
|
||||||
LOG_WARN("Fail to open encoded_h264_stream.h264");
|
LOG_WARN("Fail to open encoded_h264_stream.h264");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,9 +189,9 @@ int OpenH264Encoder::Encode(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SAVE_RECEIVED_NV12_STREAM) {
|
#ifdef SAVE_RECEIVED_NV12_STREAM
|
||||||
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
fwrite(video_frame->data, 1, video_frame->size, file_nv12_);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
if (!yuv420p_frame_) {
|
if (!yuv420p_frame_) {
|
||||||
yuv420p_frame_capacity_ = video_frame->size;
|
yuv420p_frame_capacity_ = video_frame->size;
|
||||||
@@ -267,7 +269,7 @@ int OpenH264Encoder::Encode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t frag = 0;
|
size_t frag = 0;
|
||||||
int encoded_frame_size = 0;
|
size_t encoded_frame_size = 0;
|
||||||
for (int layer = 0; layer < info.iLayerNum; ++layer) {
|
for (int layer = 0; layer < info.iLayerNum; ++layer) {
|
||||||
const SLayerBSInfo &layerInfo = info.sLayerInfo[layer];
|
const SLayerBSInfo &layerInfo = info.sLayerInfo[layer];
|
||||||
size_t layer_len = 0;
|
size_t layer_len = 0;
|
||||||
@@ -281,11 +283,9 @@ int OpenH264Encoder::Encode(
|
|||||||
|
|
||||||
if (on_encoded_image) {
|
if (on_encoded_image) {
|
||||||
on_encoded_image((char *)encoded_frame_, encoded_frame_size_, frame_type);
|
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_);
|
fwrite(encoded_frame_, 1, encoded_frame_size_, file_h264_);
|
||||||
}
|
#endif
|
||||||
} else {
|
|
||||||
OnEncodedImage((char *)encoded_frame_, encoded_frame_size_);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (info.eFrameType == videoFrameTypeInvalid) {
|
if (info.eFrameType == videoFrameTypeInvalid) {
|
||||||
@@ -327,11 +327,9 @@ int OpenH264Encoder::Encode(
|
|||||||
|
|
||||||
if (on_encoded_image) {
|
if (on_encoded_image) {
|
||||||
on_encoded_image((char *)encoded_frame_, frame_type);
|
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_);
|
fwrite(encoded_frame_, 1, encoded_frame_size_, file_h264_);
|
||||||
}
|
#endif
|
||||||
} else {
|
|
||||||
OnEncodedImage((char *)encoded_frame_, encoded_frame_size_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EVideoFrameType ft_temp = info.eFrameType;
|
EVideoFrameType ft_temp = info.eFrameType;
|
||||||
@@ -353,11 +351,6 @@ int OpenH264Encoder::Encode(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OpenH264Encoder::OnEncodedImage(char *encoded_packets, size_t size) {
|
|
||||||
LOG_INFO("OnEncodedImage not implemented");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int OpenH264Encoder::ForceIdr() {
|
int OpenH264Encoder::ForceIdr() {
|
||||||
if (openh264_encoder_) {
|
if (openh264_encoder_) {
|
||||||
return openh264_encoder_->ForceIntraFrame(true);
|
return openh264_encoder_->ForceIntraFrame(true);
|
||||||
|
|||||||
@@ -23,20 +23,12 @@ class OpenH264Encoder : public VideoEncoder {
|
|||||||
virtual ~OpenH264Encoder();
|
virtual ~OpenH264Encoder();
|
||||||
|
|
||||||
int Init();
|
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,
|
int Encode(const XVideoFrame* video_frame,
|
||||||
std::function<int(char* encoded_packets, size_t size,
|
std::function<int(char* encoded_packets, size_t size,
|
||||||
VideoFrameType frame_type)>
|
VideoFrameType frame_type)>
|
||||||
on_encoded_image);
|
on_encoded_image);
|
||||||
|
|
||||||
int OnEncodedImage(char* encoded_packets, size_t size);
|
|
||||||
|
|
||||||
int ForceIdr();
|
int ForceIdr();
|
||||||
|
|
||||||
std::string GetEncoderName() { return "OpenH264"; }
|
std::string GetEncoderName() { return "OpenH264"; }
|
||||||
@@ -48,8 +40,8 @@ class OpenH264Encoder : public VideoEncoder {
|
|||||||
int Release();
|
int Release();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int frame_width_ = 1280;
|
uint32_t frame_width_ = 1280;
|
||||||
int frame_height_ = 720;
|
uint32_t frame_height_ = 720;
|
||||||
int key_frame_interval_ = 300;
|
int key_frame_interval_ = 300;
|
||||||
int target_bitrate_ = 10000000;
|
int target_bitrate_ = 10000000;
|
||||||
int max_bitrate_ = 10000000;
|
int max_bitrate_ = 10000000;
|
||||||
@@ -68,10 +60,10 @@ class OpenH264Encoder : public VideoEncoder {
|
|||||||
int video_format_;
|
int video_format_;
|
||||||
SSourcePicture raw_frame_;
|
SSourcePicture raw_frame_;
|
||||||
unsigned char* yuv420p_frame_ = nullptr;
|
unsigned char* yuv420p_frame_ = nullptr;
|
||||||
int yuv420p_frame_capacity_ = 0;
|
size_t yuv420p_frame_capacity_ = 0;
|
||||||
uint8_t* encoded_frame_ = nullptr;
|
uint8_t* encoded_frame_ = nullptr;
|
||||||
int encoded_frame_capacity_ = 0;
|
size_t encoded_frame_capacity_ = 0;
|
||||||
int encoded_frame_size_ = 0;
|
size_t encoded_frame_size_ = 0;
|
||||||
bool got_output = false;
|
bool got_output = false;
|
||||||
bool is_keyframe = false;
|
bool is_keyframe = false;
|
||||||
int temporal_ = 1;
|
int temporal_ = 1;
|
||||||
|
|||||||
@@ -20,18 +20,11 @@ class VideoEncoder {
|
|||||||
public:
|
public:
|
||||||
virtual int Init() = 0;
|
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,
|
virtual int Encode(const XVideoFrame* video_frame,
|
||||||
std::function<int(char* encoded_packets, size_t size,
|
std::function<int(char* encoded_packets, size_t size,
|
||||||
VideoFrameType frame_type)>
|
VideoFrameType frame_type)>
|
||||||
on_encoded_image) = 0;
|
on_encoded_image) = 0;
|
||||||
|
|
||||||
virtual int OnEncodedImage(char* encoded_packets, size_t size) = 0;
|
|
||||||
|
|
||||||
virtual int ForceIdr() = 0;
|
virtual int ForceIdr() = 0;
|
||||||
|
|
||||||
virtual std::string GetEncoderName() = 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 <thread>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "ikcp.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
#else
|
#else
|
||||||
@@ -49,7 +48,7 @@ int IceTransmission::SetLocalCapabilities(
|
|||||||
hardware_acceleration_ = hardware_acceleration;
|
hardware_acceleration_ = hardware_acceleration;
|
||||||
use_trickle_ice_ = use_trickle_ice;
|
use_trickle_ice_ = use_trickle_ice;
|
||||||
use_reliable_ice_ = use_reliable_ice;
|
use_reliable_ice_ = use_reliable_ice;
|
||||||
enable_turn_ = force_turn;
|
enable_turn_ = enable_turn;
|
||||||
force_turn_ = force_turn;
|
force_turn_ = force_turn;
|
||||||
support_video_payload_types_ = video_payload_types;
|
support_video_payload_types_ = video_payload_types;
|
||||||
support_audio_payload_types_ = audio_payload_types;
|
support_audio_payload_types_ = audio_payload_types;
|
||||||
@@ -105,10 +104,9 @@ int IceTransmission::InitIceTransmission(
|
|||||||
});
|
});
|
||||||
rtp_video_receiver_->SetOnReceiveCompleteFrame(
|
rtp_video_receiver_->SetOnReceiveCompleteFrame(
|
||||||
[this](VideoFrame &video_frame) -> void {
|
[this](VideoFrame &video_frame) -> void {
|
||||||
// LOG_ERROR("OnReceiveCompleteFrame {}", video_frame.Size());
|
ice_io_statistics_->UpdateVideoInboundBytes(
|
||||||
ice_io_statistics_->UpdateVideoInboundBytes(video_frame.Size());
|
(uint32_t)video_frame.Size());
|
||||||
|
[[maybe_unused]] int num_frame_returned = video_decoder_->Decode(
|
||||||
int num_frame_returned = video_decoder_->Decode(
|
|
||||||
(uint8_t *)video_frame.Buffer(), video_frame.Size(),
|
(uint8_t *)video_frame.Buffer(), video_frame.Size(),
|
||||||
[this](VideoFrame video_frame) {
|
[this](VideoFrame video_frame) {
|
||||||
if (on_receive_video_) {
|
if (on_receive_video_) {
|
||||||
@@ -140,7 +138,7 @@ int IceTransmission::InitIceTransmission(
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ice_io_statistics_->UpdateVideoOutboundBytes(size);
|
ice_io_statistics_->UpdateVideoOutboundBytes((uint32_t)size);
|
||||||
return ice_agent_->Send(data, size);
|
return ice_agent_->Send(data, size);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -166,9 +164,9 @@ int IceTransmission::InitIceTransmission(
|
|||||||
});
|
});
|
||||||
rtp_audio_receiver_->SetOnReceiveData([this](const char *data,
|
rtp_audio_receiver_->SetOnReceiveData([this](const char *data,
|
||||||
size_t size) -> void {
|
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) {
|
(uint8_t *)data, size, [this](uint8_t *data, int size) {
|
||||||
if (on_receive_audio_) {
|
if (on_receive_audio_) {
|
||||||
on_receive_audio_((const char *)data, size, remote_user_id_.data(),
|
on_receive_audio_((const char *)data, size, remote_user_id_.data(),
|
||||||
@@ -192,7 +190,7 @@ int IceTransmission::InitIceTransmission(
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ice_io_statistics_->UpdateAudioOutboundBytes(size);
|
ice_io_statistics_->UpdateAudioOutboundBytes((uint32_t)size);
|
||||||
return ice_agent_->Send(data, size);
|
return ice_agent_->Send(data, size);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -218,7 +216,7 @@ int IceTransmission::InitIceTransmission(
|
|||||||
});
|
});
|
||||||
rtp_data_receiver_->SetOnReceiveData(
|
rtp_data_receiver_->SetOnReceiveData(
|
||||||
[this](const char *data, size_t size) -> void {
|
[this](const char *data, size_t size) -> void {
|
||||||
ice_io_statistics_->UpdateDataInboundBytes(size);
|
ice_io_statistics_->UpdateDataInboundBytes((uint32_t)size);
|
||||||
|
|
||||||
if (on_receive_data_) {
|
if (on_receive_data_) {
|
||||||
on_receive_data_(data, size, remote_user_id_.data(),
|
on_receive_data_(data, size, remote_user_id_.data(),
|
||||||
@@ -241,7 +239,7 @@ int IceTransmission::InitIceTransmission(
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ice_io_statistics_->UpdateDataOutboundBytes(size);
|
ice_io_statistics_->UpdateDataOutboundBytes((uint32_t)size);
|
||||||
return ice_agent_->Send(data, size);
|
return ice_agent_->Send(data, size);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -253,8 +251,9 @@ int IceTransmission::InitIceTransmission(
|
|||||||
turn_password);
|
turn_password);
|
||||||
|
|
||||||
ice_agent_->CreateIceAgent(
|
ice_agent_->CreateIceAgent(
|
||||||
[](NiceAgent *agent, guint stream_id, guint component_id,
|
[]([[maybe_unused]] NiceAgent *agent, [[maybe_unused]] guint stream_id,
|
||||||
NiceComponentState state, gpointer user_ptr) {
|
[[maybe_unused]] guint component_id, NiceComponentState state,
|
||||||
|
gpointer user_ptr) {
|
||||||
if (user_ptr) {
|
if (user_ptr) {
|
||||||
IceTransmission *ice_transmission_obj =
|
IceTransmission *ice_transmission_obj =
|
||||||
static_cast<IceTransmission *>(user_ptr);
|
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
|
// non-trickle
|
||||||
if (user_ptr) {
|
if (user_ptr) {
|
||||||
IceTransmission *ice_transmission_obj =
|
IceTransmission *ice_transmission_obj =
|
||||||
@@ -365,8 +365,9 @@ int IceTransmission::InitIceTransmission(
|
|||||||
&net_traffic_stats, ice_transmission_obj->user_data_);
|
&net_traffic_stats, ice_transmission_obj->user_data_);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[](NiceAgent *agent, guint stream_id, guint component_id, guint size,
|
[]([[maybe_unused]] NiceAgent *agent, [[maybe_unused]] guint stream_id,
|
||||||
gchar *buffer, gpointer user_ptr) {
|
[[maybe_unused]] guint component_id, guint size, gchar *buffer,
|
||||||
|
gpointer user_ptr) {
|
||||||
if (user_ptr) {
|
if (user_ptr) {
|
||||||
IceTransmission *ice_transmission_obj =
|
IceTransmission *ice_transmission_obj =
|
||||||
static_cast<IceTransmission *>(user_ptr);
|
static_cast<IceTransmission *>(user_ptr);
|
||||||
@@ -977,7 +978,7 @@ int IceTransmission::SendVideoFrame(const XVideoFrame *video_frame) {
|
|||||||
if (video_rtp_codec_) {
|
if (video_rtp_codec_) {
|
||||||
video_rtp_codec_->Encode(
|
video_rtp_codec_->Encode(
|
||||||
static_cast<RtpCodec::VideoFrameType>(frame_type),
|
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);
|
rtp_video_sender_->Enqueue(packets);
|
||||||
}
|
}
|
||||||
@@ -1007,15 +1008,15 @@ int IceTransmission::SendAudioFrame(const char *data, size_t size) {
|
|||||||
if (rtp_audio_sender_) {
|
if (rtp_audio_sender_) {
|
||||||
if (audio_rtp_codec_) {
|
if (audio_rtp_codec_) {
|
||||||
std::vector<RtpPacket> packets;
|
std::vector<RtpPacket> packets;
|
||||||
audio_rtp_codec_->Encode((uint8_t *)encoded_audio_buffer, size,
|
audio_rtp_codec_->Encode((uint8_t *)encoded_audio_buffer,
|
||||||
packets);
|
(uint32_t)size, packets);
|
||||||
rtp_audio_sender_->Enqueue(packets);
|
rtp_audio_sender_->Enqueue(packets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IceTransmission::SendDataFrame(const char *data, size_t size) {
|
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 (rtp_data_sender_) {
|
||||||
if (data_rtp_codec_) {
|
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);
|
rtp_data_sender_->Enqueue(packets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,7 +136,8 @@ void WsClient::Ping(websocketpp::connection_hdl hdl) {
|
|||||||
|
|
||||||
WsStatus WsClient::GetStatus() { return ws_status_; }
|
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;
|
ws_status_ = WsStatus::WsOpened;
|
||||||
on_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;
|
ws_status_ = WsStatus::WsFailed;
|
||||||
on_ws_status_(WsStatus::WsFailed);
|
on_ws_status_(WsStatus::WsFailed);
|
||||||
Connect(uri_);
|
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;
|
ws_status_ = WsStatus::WsServerClosed;
|
||||||
on_ws_status_(WsStatus::WsServerClosed);
|
on_ws_status_(WsStatus::WsServerClosed);
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,8 @@
|
|||||||
Purschke <purschke@bnl.gov>.
|
Purschke <purschke@bnl.gov>.
|
||||||
1999-05-03 lpd Original version.
|
1999-05-03 lpd Original version.
|
||||||
*/
|
*/
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4267)
|
||||||
|
|
||||||
#ifndef WEBSOCKETPP_COMMON_MD5_HPP
|
#ifndef WEBSOCKETPP_COMMON_MD5_HPP
|
||||||
#define WEBSOCKETPP_COMMON_MD5_HPP
|
#define WEBSOCKETPP_COMMON_MD5_HPP
|
||||||
@@ -68,120 +70,121 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
/// Provides MD5 hashing functionality
|
/// Provides MD5 hashing functionality
|
||||||
namespace md5 {
|
namespace md5 {
|
||||||
|
|
||||||
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
||||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||||
|
|
||||||
/* Define the state of the MD5 Algorithm. */
|
/* Define the state of the MD5 Algorithm. */
|
||||||
typedef struct md5_state_s {
|
typedef struct md5_state_s {
|
||||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||||
md5_word_t abcd[4]; /* digest buffer */
|
md5_word_t abcd[4]; /* digest buffer */
|
||||||
md5_byte_t buf[64]; /* accumulate block */
|
md5_byte_t buf[64]; /* accumulate block */
|
||||||
} md5_state_t;
|
} md5_state_t;
|
||||||
|
|
||||||
/* Initialize the algorithm. */
|
/* Initialize the algorithm. */
|
||||||
inline void md5_init(md5_state_t *pms);
|
inline void md5_init(md5_state_t *pms);
|
||||||
|
|
||||||
/* Append a string to the message. */
|
/* 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. */
|
/* Finish the message and return the digest. */
|
||||||
inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
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
|
#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
|
#else
|
||||||
# define ZSW_MD5_BYTE_ORDER 0
|
#define ZSW_MD5_BYTE_ORDER 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZSW_MD5_T_MASK ((md5_word_t)~0)
|
#define ZSW_MD5_T_MASK ((md5_word_t)~0)
|
||||||
#define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87)
|
#define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87)
|
||||||
#define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9)
|
#define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9)
|
||||||
#define ZSW_MD5_T3 0x242070db
|
#define ZSW_MD5_T3 0x242070db
|
||||||
#define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111)
|
#define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111)
|
||||||
#define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050)
|
#define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050)
|
||||||
#define ZSW_MD5_T6 0x4787c62a
|
#define ZSW_MD5_T6 0x4787c62a
|
||||||
#define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec)
|
#define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec)
|
||||||
#define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe)
|
#define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe)
|
||||||
#define ZSW_MD5_T9 0x698098d8
|
#define ZSW_MD5_T9 0x698098d8
|
||||||
#define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850)
|
#define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850)
|
||||||
#define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e)
|
#define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e)
|
||||||
#define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841)
|
#define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841)
|
||||||
#define ZSW_MD5_T13 0x6b901122
|
#define ZSW_MD5_T13 0x6b901122
|
||||||
#define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c)
|
#define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c)
|
||||||
#define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71)
|
#define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71)
|
||||||
#define ZSW_MD5_T16 0x49b40821
|
#define ZSW_MD5_T16 0x49b40821
|
||||||
#define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d)
|
#define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d)
|
||||||
#define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf)
|
#define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf)
|
||||||
#define ZSW_MD5_T19 0x265e5a51
|
#define ZSW_MD5_T19 0x265e5a51
|
||||||
#define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855)
|
#define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855)
|
||||||
#define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2)
|
#define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2)
|
||||||
#define ZSW_MD5_T22 0x02441453
|
#define ZSW_MD5_T22 0x02441453
|
||||||
#define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e)
|
#define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e)
|
||||||
#define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437)
|
#define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437)
|
||||||
#define ZSW_MD5_T25 0x21e1cde6
|
#define ZSW_MD5_T25 0x21e1cde6
|
||||||
#define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829)
|
#define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829)
|
||||||
#define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278)
|
#define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278)
|
||||||
#define ZSW_MD5_T28 0x455a14ed
|
#define ZSW_MD5_T28 0x455a14ed
|
||||||
#define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa)
|
#define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa)
|
||||||
#define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07)
|
#define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07)
|
||||||
#define ZSW_MD5_T31 0x676f02d9
|
#define ZSW_MD5_T31 0x676f02d9
|
||||||
#define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375)
|
#define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375)
|
||||||
#define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd)
|
#define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd)
|
||||||
#define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e)
|
#define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e)
|
||||||
#define ZSW_MD5_T35 0x6d9d6122
|
#define ZSW_MD5_T35 0x6d9d6122
|
||||||
#define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3)
|
#define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3)
|
||||||
#define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb)
|
#define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb)
|
||||||
#define ZSW_MD5_T38 0x4bdecfa9
|
#define ZSW_MD5_T38 0x4bdecfa9
|
||||||
#define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f)
|
#define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f)
|
||||||
#define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f)
|
#define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f)
|
||||||
#define ZSW_MD5_T41 0x289b7ec6
|
#define ZSW_MD5_T41 0x289b7ec6
|
||||||
#define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805)
|
#define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805)
|
||||||
#define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a)
|
#define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a)
|
||||||
#define ZSW_MD5_T44 0x04881d05
|
#define ZSW_MD5_T44 0x04881d05
|
||||||
#define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6)
|
#define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6)
|
||||||
#define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a)
|
#define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a)
|
||||||
#define ZSW_MD5_T47 0x1fa27cf8
|
#define ZSW_MD5_T47 0x1fa27cf8
|
||||||
#define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a)
|
#define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a)
|
||||||
#define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb)
|
#define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb)
|
||||||
#define ZSW_MD5_T50 0x432aff97
|
#define ZSW_MD5_T50 0x432aff97
|
||||||
#define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58)
|
#define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58)
|
||||||
#define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6)
|
#define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6)
|
||||||
#define ZSW_MD5_T53 0x655b59c3
|
#define ZSW_MD5_T53 0x655b59c3
|
||||||
#define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d)
|
#define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d)
|
||||||
#define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82)
|
#define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82)
|
||||||
#define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e)
|
#define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e)
|
||||||
#define ZSW_MD5_T57 0x6fa87e4f
|
#define ZSW_MD5_T57 0x6fa87e4f
|
||||||
#define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f)
|
#define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f)
|
||||||
#define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb)
|
#define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb)
|
||||||
#define ZSW_MD5_T60 0x4e0811a1
|
#define ZSW_MD5_T60 0x4e0811a1
|
||||||
#define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d)
|
#define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d)
|
||||||
#define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca)
|
#define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca)
|
||||||
#define ZSW_MD5_T63 0x2ad7d2bb
|
#define ZSW_MD5_T63 0x2ad7d2bb
|
||||||
#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e)
|
#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e)
|
||||||
|
|
||||||
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
static void md5_process(md5_state_t *pms, md5_byte_t const *data /*[64]*/) {
|
||||||
md5_word_t
|
md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2],
|
||||||
a = pms->abcd[0], b = pms->abcd[1],
|
d = pms->abcd[3];
|
||||||
c = pms->abcd[2], d = pms->abcd[3];
|
md5_word_t t;
|
||||||
md5_word_t t;
|
|
||||||
#if ZSW_MD5_BYTE_ORDER > 0
|
#if ZSW_MD5_BYTE_ORDER > 0
|
||||||
/* Define storage only for big-endian CPUs. */
|
/* Define storage only for big-endian CPUs. */
|
||||||
md5_word_t X[16];
|
md5_word_t X[16];
|
||||||
#else
|
#else
|
||||||
/* Define storage for little-endian or both types of CPUs. */
|
/* Define storage for little-endian or both types of CPUs. */
|
||||||
md5_word_t xbuf[16];
|
md5_word_t xbuf[16];
|
||||||
md5_word_t const * X;
|
md5_word_t const *X;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
#if ZSW_MD5_BYTE_ORDER == 0
|
#if ZSW_MD5_BYTE_ORDER == 0
|
||||||
/*
|
/*
|
||||||
* Determine dynamically whether this is a big-endian or
|
* Determine dynamically whether this is a big-endian or
|
||||||
@@ -192,257 +195,252 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
|||||||
|
|
||||||
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
||||||
#endif
|
#endif
|
||||||
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* On little-endian machines, we can process properly aligned
|
* On little-endian machines, we can process properly aligned
|
||||||
* data without copying it.
|
* data without copying it.
|
||||||
*/
|
*/
|
||||||
if (!((data - (md5_byte_t const *)0) & 3)) {
|
if (!((data - (md5_byte_t const *)0) & 3)) {
|
||||||
/* data are properly aligned */
|
/* data are properly aligned */
|
||||||
X = (md5_word_t const *)data;
|
X = (md5_word_t const *)data;
|
||||||
} else {
|
} else {
|
||||||
/* not aligned */
|
/* not aligned */
|
||||||
std::memcpy(xbuf, data, 64);
|
std::memcpy(xbuf, data, 64);
|
||||||
X = xbuf;
|
X = xbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if ZSW_MD5_BYTE_ORDER == 0
|
#if ZSW_MD5_BYTE_ORDER == 0
|
||||||
else /* dynamic big-endian */
|
else /* dynamic big-endian */
|
||||||
#endif
|
#endif
|
||||||
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* On big-endian machines, we must arrange the bytes in the
|
* On big-endian machines, we must arrange the bytes in the
|
||||||
* right order.
|
* right order.
|
||||||
*/
|
*/
|
||||||
const md5_byte_t *xp = data;
|
const md5_byte_t *xp = data;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
# if ZSW_MD5_BYTE_ORDER == 0
|
#if ZSW_MD5_BYTE_ORDER == 0
|
||||||
X = xbuf; /* (dynamic only) */
|
X = xbuf; /* (dynamic only) */
|
||||||
# else
|
#else
|
||||||
# define xbuf X /* (static only) */
|
#define xbuf X /* (static only) */
|
||||||
# endif
|
#endif
|
||||||
for (i = 0; i < 16; ++i, xp += 4)
|
for (i = 0; i < 16; ++i, xp += 4)
|
||||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||||
|
|
||||||
/* Round 1. */
|
/* Round 1. */
|
||||||
/* Let [abcd k s i] denote the operation
|
/* Let [abcd k s i] denote the operation
|
||||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||||
#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||||
#define SET(a, b, c, d, k, s, Ti)\
|
#define SET(a, b, c, d, k, s, Ti) \
|
||||||
t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\
|
t = a + ZSW_MD5_F(b, c, d) + X[k] + Ti; \
|
||||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||||
/* Do the following 16 operations. */
|
/* Do the following 16 operations. */
|
||||||
SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
|
SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
|
||||||
SET(d, a, b, c, 1, 12, ZSW_MD5_T2);
|
SET(d, a, b, c, 1, 12, ZSW_MD5_T2);
|
||||||
SET(c, d, a, b, 2, 17, ZSW_MD5_T3);
|
SET(c, d, a, b, 2, 17, ZSW_MD5_T3);
|
||||||
SET(b, c, d, a, 3, 22, ZSW_MD5_T4);
|
SET(b, c, d, a, 3, 22, ZSW_MD5_T4);
|
||||||
SET(a, b, c, d, 4, 7, ZSW_MD5_T5);
|
SET(a, b, c, d, 4, 7, ZSW_MD5_T5);
|
||||||
SET(d, a, b, c, 5, 12, ZSW_MD5_T6);
|
SET(d, a, b, c, 5, 12, ZSW_MD5_T6);
|
||||||
SET(c, d, a, b, 6, 17, ZSW_MD5_T7);
|
SET(c, d, a, b, 6, 17, ZSW_MD5_T7);
|
||||||
SET(b, c, d, a, 7, 22, ZSW_MD5_T8);
|
SET(b, c, d, a, 7, 22, ZSW_MD5_T8);
|
||||||
SET(a, b, c, d, 8, 7, ZSW_MD5_T9);
|
SET(a, b, c, d, 8, 7, ZSW_MD5_T9);
|
||||||
SET(d, a, b, c, 9, 12, ZSW_MD5_T10);
|
SET(d, a, b, c, 9, 12, ZSW_MD5_T10);
|
||||||
SET(c, d, a, b, 10, 17, ZSW_MD5_T11);
|
SET(c, d, a, b, 10, 17, ZSW_MD5_T11);
|
||||||
SET(b, c, d, a, 11, 22, ZSW_MD5_T12);
|
SET(b, c, d, a, 11, 22, ZSW_MD5_T12);
|
||||||
SET(a, b, c, d, 12, 7, ZSW_MD5_T13);
|
SET(a, b, c, d, 12, 7, ZSW_MD5_T13);
|
||||||
SET(d, a, b, c, 13, 12, ZSW_MD5_T14);
|
SET(d, a, b, c, 13, 12, ZSW_MD5_T14);
|
||||||
SET(c, d, a, b, 14, 17, ZSW_MD5_T15);
|
SET(c, d, a, b, 14, 17, ZSW_MD5_T15);
|
||||||
SET(b, c, d, a, 15, 22, ZSW_MD5_T16);
|
SET(b, c, d, a, 15, 22, ZSW_MD5_T16);
|
||||||
#undef SET
|
#undef SET
|
||||||
|
|
||||||
/* Round 2. */
|
/* Round 2. */
|
||||||
/* Let [abcd k s i] denote the operation
|
/* Let [abcd k s i] denote the operation
|
||||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||||
#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||||
#define SET(a, b, c, d, k, s, Ti)\
|
#define SET(a, b, c, d, k, s, Ti) \
|
||||||
t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\
|
t = a + ZSW_MD5_G(b, c, d) + X[k] + Ti; \
|
||||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||||
/* Do the following 16 operations. */
|
/* Do the following 16 operations. */
|
||||||
SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
|
SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
|
||||||
SET(d, a, b, c, 6, 9, ZSW_MD5_T18);
|
SET(d, a, b, c, 6, 9, ZSW_MD5_T18);
|
||||||
SET(c, d, a, b, 11, 14, ZSW_MD5_T19);
|
SET(c, d, a, b, 11, 14, ZSW_MD5_T19);
|
||||||
SET(b, c, d, a, 0, 20, ZSW_MD5_T20);
|
SET(b, c, d, a, 0, 20, ZSW_MD5_T20);
|
||||||
SET(a, b, c, d, 5, 5, ZSW_MD5_T21);
|
SET(a, b, c, d, 5, 5, ZSW_MD5_T21);
|
||||||
SET(d, a, b, c, 10, 9, ZSW_MD5_T22);
|
SET(d, a, b, c, 10, 9, ZSW_MD5_T22);
|
||||||
SET(c, d, a, b, 15, 14, ZSW_MD5_T23);
|
SET(c, d, a, b, 15, 14, ZSW_MD5_T23);
|
||||||
SET(b, c, d, a, 4, 20, ZSW_MD5_T24);
|
SET(b, c, d, a, 4, 20, ZSW_MD5_T24);
|
||||||
SET(a, b, c, d, 9, 5, ZSW_MD5_T25);
|
SET(a, b, c, d, 9, 5, ZSW_MD5_T25);
|
||||||
SET(d, a, b, c, 14, 9, ZSW_MD5_T26);
|
SET(d, a, b, c, 14, 9, ZSW_MD5_T26);
|
||||||
SET(c, d, a, b, 3, 14, ZSW_MD5_T27);
|
SET(c, d, a, b, 3, 14, ZSW_MD5_T27);
|
||||||
SET(b, c, d, a, 8, 20, ZSW_MD5_T28);
|
SET(b, c, d, a, 8, 20, ZSW_MD5_T28);
|
||||||
SET(a, b, c, d, 13, 5, ZSW_MD5_T29);
|
SET(a, b, c, d, 13, 5, ZSW_MD5_T29);
|
||||||
SET(d, a, b, c, 2, 9, ZSW_MD5_T30);
|
SET(d, a, b, c, 2, 9, ZSW_MD5_T30);
|
||||||
SET(c, d, a, b, 7, 14, ZSW_MD5_T31);
|
SET(c, d, a, b, 7, 14, ZSW_MD5_T31);
|
||||||
SET(b, c, d, a, 12, 20, ZSW_MD5_T32);
|
SET(b, c, d, a, 12, 20, ZSW_MD5_T32);
|
||||||
#undef SET
|
#undef SET
|
||||||
|
|
||||||
/* Round 3. */
|
/* Round 3. */
|
||||||
/* Let [abcd k s t] denote the operation
|
/* Let [abcd k s t] denote the operation
|
||||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||||
#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
|
#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
#define SET(a, b, c, d, k, s, Ti)\
|
#define SET(a, b, c, d, k, s, Ti) \
|
||||||
t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\
|
t = a + ZSW_MD5_H(b, c, d) + X[k] + Ti; \
|
||||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||||
/* Do the following 16 operations. */
|
/* Do the following 16 operations. */
|
||||||
SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
|
SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
|
||||||
SET(d, a, b, c, 8, 11, ZSW_MD5_T34);
|
SET(d, a, b, c, 8, 11, ZSW_MD5_T34);
|
||||||
SET(c, d, a, b, 11, 16, ZSW_MD5_T35);
|
SET(c, d, a, b, 11, 16, ZSW_MD5_T35);
|
||||||
SET(b, c, d, a, 14, 23, ZSW_MD5_T36);
|
SET(b, c, d, a, 14, 23, ZSW_MD5_T36);
|
||||||
SET(a, b, c, d, 1, 4, ZSW_MD5_T37);
|
SET(a, b, c, d, 1, 4, ZSW_MD5_T37);
|
||||||
SET(d, a, b, c, 4, 11, ZSW_MD5_T38);
|
SET(d, a, b, c, 4, 11, ZSW_MD5_T38);
|
||||||
SET(c, d, a, b, 7, 16, ZSW_MD5_T39);
|
SET(c, d, a, b, 7, 16, ZSW_MD5_T39);
|
||||||
SET(b, c, d, a, 10, 23, ZSW_MD5_T40);
|
SET(b, c, d, a, 10, 23, ZSW_MD5_T40);
|
||||||
SET(a, b, c, d, 13, 4, ZSW_MD5_T41);
|
SET(a, b, c, d, 13, 4, ZSW_MD5_T41);
|
||||||
SET(d, a, b, c, 0, 11, ZSW_MD5_T42);
|
SET(d, a, b, c, 0, 11, ZSW_MD5_T42);
|
||||||
SET(c, d, a, b, 3, 16, ZSW_MD5_T43);
|
SET(c, d, a, b, 3, 16, ZSW_MD5_T43);
|
||||||
SET(b, c, d, a, 6, 23, ZSW_MD5_T44);
|
SET(b, c, d, a, 6, 23, ZSW_MD5_T44);
|
||||||
SET(a, b, c, d, 9, 4, ZSW_MD5_T45);
|
SET(a, b, c, d, 9, 4, ZSW_MD5_T45);
|
||||||
SET(d, a, b, c, 12, 11, ZSW_MD5_T46);
|
SET(d, a, b, c, 12, 11, ZSW_MD5_T46);
|
||||||
SET(c, d, a, b, 15, 16, ZSW_MD5_T47);
|
SET(c, d, a, b, 15, 16, ZSW_MD5_T47);
|
||||||
SET(b, c, d, a, 2, 23, ZSW_MD5_T48);
|
SET(b, c, d, a, 2, 23, ZSW_MD5_T48);
|
||||||
#undef SET
|
#undef SET
|
||||||
|
|
||||||
/* Round 4. */
|
/* Round 4. */
|
||||||
/* Let [abcd k s t] denote the operation
|
/* Let [abcd k s t] denote the operation
|
||||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||||
#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
|
#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||||
#define SET(a, b, c, d, k, s, Ti)\
|
#define SET(a, b, c, d, k, s, Ti) \
|
||||||
t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\
|
t = a + ZSW_MD5_I(b, c, d) + X[k] + Ti; \
|
||||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||||
/* Do the following 16 operations. */
|
/* Do the following 16 operations. */
|
||||||
SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
|
SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
|
||||||
SET(d, a, b, c, 7, 10, ZSW_MD5_T50);
|
SET(d, a, b, c, 7, 10, ZSW_MD5_T50);
|
||||||
SET(c, d, a, b, 14, 15, ZSW_MD5_T51);
|
SET(c, d, a, b, 14, 15, ZSW_MD5_T51);
|
||||||
SET(b, c, d, a, 5, 21, ZSW_MD5_T52);
|
SET(b, c, d, a, 5, 21, ZSW_MD5_T52);
|
||||||
SET(a, b, c, d, 12, 6, ZSW_MD5_T53);
|
SET(a, b, c, d, 12, 6, ZSW_MD5_T53);
|
||||||
SET(d, a, b, c, 3, 10, ZSW_MD5_T54);
|
SET(d, a, b, c, 3, 10, ZSW_MD5_T54);
|
||||||
SET(c, d, a, b, 10, 15, ZSW_MD5_T55);
|
SET(c, d, a, b, 10, 15, ZSW_MD5_T55);
|
||||||
SET(b, c, d, a, 1, 21, ZSW_MD5_T56);
|
SET(b, c, d, a, 1, 21, ZSW_MD5_T56);
|
||||||
SET(a, b, c, d, 8, 6, ZSW_MD5_T57);
|
SET(a, b, c, d, 8, 6, ZSW_MD5_T57);
|
||||||
SET(d, a, b, c, 15, 10, ZSW_MD5_T58);
|
SET(d, a, b, c, 15, 10, ZSW_MD5_T58);
|
||||||
SET(c, d, a, b, 6, 15, ZSW_MD5_T59);
|
SET(c, d, a, b, 6, 15, ZSW_MD5_T59);
|
||||||
SET(b, c, d, a, 13, 21, ZSW_MD5_T60);
|
SET(b, c, d, a, 13, 21, ZSW_MD5_T60);
|
||||||
SET(a, b, c, d, 4, 6, ZSW_MD5_T61);
|
SET(a, b, c, d, 4, 6, ZSW_MD5_T61);
|
||||||
SET(d, a, b, c, 11, 10, ZSW_MD5_T62);
|
SET(d, a, b, c, 11, 10, ZSW_MD5_T62);
|
||||||
SET(c, d, a, b, 2, 15, ZSW_MD5_T63);
|
SET(c, d, a, b, 2, 15, ZSW_MD5_T63);
|
||||||
SET(b, c, d, a, 9, 21, ZSW_MD5_T64);
|
SET(b, c, d, a, 9, 21, ZSW_MD5_T64);
|
||||||
#undef SET
|
#undef SET
|
||||||
|
|
||||||
/* Then perform the following additions. (That is increment each
|
/* Then perform the following additions. (That is increment each
|
||||||
of the four registers by the value it had before this block
|
of the four registers by the value it had before this block
|
||||||
was started.) */
|
was started.) */
|
||||||
pms->abcd[0] += a;
|
pms->abcd[0] += a;
|
||||||
pms->abcd[1] += b;
|
pms->abcd[1] += b;
|
||||||
pms->abcd[2] += c;
|
pms->abcd[2] += c;
|
||||||
pms->abcd[3] += d;
|
pms->abcd[3] += d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void md5_init(md5_state_t *pms) {
|
void md5_init(md5_state_t *pms) {
|
||||||
pms->count[0] = pms->count[1] = 0;
|
pms->count[0] = pms->count[1] = 0;
|
||||||
pms->abcd[0] = 0x67452301;
|
pms->abcd[0] = 0x67452301;
|
||||||
pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476;
|
pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476;
|
||||||
pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301;
|
pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301;
|
||||||
pms->abcd[3] = 0x10325476;
|
pms->abcd[3] = 0x10325476;
|
||||||
}
|
}
|
||||||
|
|
||||||
void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) {
|
void md5_append(md5_state_t *pms, md5_byte_t const *data, size_t nbytes) {
|
||||||
md5_byte_t const * p = data;
|
md5_byte_t const *p = data;
|
||||||
size_t left = nbytes;
|
size_t left = nbytes;
|
||||||
int offset = (pms->count[0] >> 3) & 63;
|
int offset = (pms->count[0] >> 3) & 63;
|
||||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||||
|
|
||||||
if (nbytes <= 0)
|
if (nbytes <= 0) return;
|
||||||
return;
|
|
||||||
|
|
||||||
/* Update the message length. */
|
/* Update the message length. */
|
||||||
pms->count[1] += nbytes >> 29;
|
pms->count[1] += nbytes >> 29;
|
||||||
pms->count[0] += nbits;
|
pms->count[0] += nbits;
|
||||||
if (pms->count[0] < nbits)
|
if (pms->count[0] < nbits) pms->count[1]++;
|
||||||
pms->count[1]++;
|
|
||||||
|
|
||||||
/* Process an initial partial block. */
|
/* Process an initial partial block. */
|
||||||
if (offset) {
|
if (offset) {
|
||||||
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
|
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
|
||||||
|
|
||||||
std::memcpy(pms->buf + offset, p, copy);
|
std::memcpy(pms->buf + offset, p, copy);
|
||||||
if (offset + copy < 64)
|
if (offset + copy < 64) return;
|
||||||
return;
|
|
||||||
p += copy;
|
p += copy;
|
||||||
left -= copy;
|
left -= copy;
|
||||||
md5_process(pms, pms->buf);
|
md5_process(pms, pms->buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process full blocks. */
|
/* Process full blocks. */
|
||||||
for (; left >= 64; p += 64, left -= 64)
|
for (; left >= 64; p += 64, left -= 64) md5_process(pms, p);
|
||||||
md5_process(pms, p);
|
|
||||||
|
|
||||||
/* Process a final partial block. */
|
/* Process a final partial block. */
|
||||||
if (left)
|
if (left) std::memcpy(pms->buf, p, left);
|
||||||
std::memcpy(pms->buf, p, left);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
|
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
|
||||||
static md5_byte_t const pad[64] = {
|
static md5_byte_t const pad[64] = {
|
||||||
0x80, 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, 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;
|
||||||
md5_byte_t data[8];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Save the length before padding. */
|
/* Save the length before padding. */
|
||||||
for (i = 0; i < 8; ++i)
|
for (i = 0; i < 8; ++i)
|
||||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||||
/* Pad to 56 bytes mod 64. */
|
/* Pad to 56 bytes mod 64. */
|
||||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||||
/* Append the length. */
|
/* Append the length. */
|
||||||
md5_append(pms, data, 8);
|
md5_append(pms, data, 8);
|
||||||
for (i = 0; i < 16; ++i)
|
for (i = 0; i < 16; ++i)
|
||||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
// some convenience c++ functions
|
// 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];
|
char digest[16];
|
||||||
|
|
||||||
md5_state_t state;
|
md5_state_t state;
|
||||||
|
|
||||||
md5_init(&state);
|
md5_init(&state);
|
||||||
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
||||||
md5_finish(&state, (md5_byte_t *)digest);
|
md5_finish(&state, (md5_byte_t *)digest);
|
||||||
|
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.resize(16);
|
ret.resize(16);
|
||||||
std::copy(digest,digest+16,ret.begin());
|
std::copy(digest, digest + 16, ret.begin());
|
||||||
|
|
||||||
return ret;
|
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 hash = md5_hash_string(input);
|
||||||
std::string hex;
|
std::string hex;
|
||||||
|
|
||||||
for (size_t i = 0; i < hash.size(); i++) {
|
for (size_t i = 0; i < hash.size(); i++) {
|
||||||
hex.push_back(hexval[((hash[i] >> 4) & 0xF)]);
|
hex.push_back(hexval[((hash[i] >> 4) & 0xF)]);
|
||||||
hex.push_back(hexval[(hash[i]) & 0x0F]);
|
hex.push_back(hexval[(hash[i]) & 0x0F]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // md5
|
} // namespace md5
|
||||||
} // websocketpp
|
} // namespace websocketpp
|
||||||
|
|
||||||
#endif // WEBSOCKETPP_COMMON_MD5_HPP
|
#endif // WEBSOCKETPP_COMMON_MD5_HPP
|
||||||
|
#pragma warning(pop)
|
||||||
651
thirdparty/websocketpp/include/websocketpp/frame.hpp
vendored
651
thirdparty/websocketpp/include/websocketpp/frame.hpp
vendored
@@ -24,16 +24,17 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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
|
#ifndef WEBSOCKETPP_FRAME_HPP
|
||||||
#define WEBSOCKETPP_FRAME_HPP
|
#define WEBSOCKETPP_FRAME_HPP
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <websocketpp/common/system_error.hpp>
|
|
||||||
#include <websocketpp/common/network.hpp>
|
#include <websocketpp/common/network.hpp>
|
||||||
|
#include <websocketpp/common/system_error.hpp>
|
||||||
#include <websocketpp/utilities.hpp>
|
#include <websocketpp/utilities.hpp>
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
@@ -53,20 +54,20 @@ static unsigned int const MAX_EXTENDED_HEADER_LENGTH = 12;
|
|||||||
|
|
||||||
/// Two byte conversion union
|
/// Two byte conversion union
|
||||||
union uint16_converter {
|
union uint16_converter {
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint8_t c[2];
|
uint8_t c[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Four byte conversion union
|
/// Four byte conversion union
|
||||||
union uint32_converter {
|
union uint32_converter {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t c[4];
|
uint8_t c[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Eight byte conversion union
|
/// Eight byte conversion union
|
||||||
union uint64_converter {
|
union uint64_converter {
|
||||||
uint64_t i;
|
uint64_t i;
|
||||||
uint8_t c[8];
|
uint8_t c[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Constants and utility functions related to WebSocket opcodes
|
/// Constants and utility functions related to WebSocket opcodes
|
||||||
@@ -74,101 +75,95 @@ union uint64_converter {
|
|||||||
* WebSocket Opcodes are 4 bits. See RFC6455 section 5.2.
|
* WebSocket Opcodes are 4 bits. See RFC6455 section 5.2.
|
||||||
*/
|
*/
|
||||||
namespace opcode {
|
namespace opcode {
|
||||||
enum value {
|
enum value {
|
||||||
continuation = 0x0,
|
continuation = 0x0,
|
||||||
text = 0x1,
|
text = 0x1,
|
||||||
binary = 0x2,
|
binary = 0x2,
|
||||||
rsv3 = 0x3,
|
rsv3 = 0x3,
|
||||||
rsv4 = 0x4,
|
rsv4 = 0x4,
|
||||||
rsv5 = 0x5,
|
rsv5 = 0x5,
|
||||||
rsv6 = 0x6,
|
rsv6 = 0x6,
|
||||||
rsv7 = 0x7,
|
rsv7 = 0x7,
|
||||||
close = 0x8,
|
close = 0x8,
|
||||||
ping = 0x9,
|
ping = 0x9,
|
||||||
pong = 0xA,
|
pong = 0xA,
|
||||||
control_rsvb = 0xB,
|
control_rsvb = 0xB,
|
||||||
control_rsvc = 0xC,
|
control_rsvc = 0xC,
|
||||||
control_rsvd = 0xD,
|
control_rsvd = 0xD,
|
||||||
control_rsve = 0xE,
|
control_rsve = 0xE,
|
||||||
control_rsvf = 0xF,
|
control_rsvf = 0xF,
|
||||||
|
|
||||||
CONTINUATION = 0x0,
|
CONTINUATION = 0x0,
|
||||||
TEXT = 0x1,
|
TEXT = 0x1,
|
||||||
BINARY = 0x2,
|
BINARY = 0x2,
|
||||||
RSV3 = 0x3,
|
RSV3 = 0x3,
|
||||||
RSV4 = 0x4,
|
RSV4 = 0x4,
|
||||||
RSV5 = 0x5,
|
RSV5 = 0x5,
|
||||||
RSV6 = 0x6,
|
RSV6 = 0x6,
|
||||||
RSV7 = 0x7,
|
RSV7 = 0x7,
|
||||||
CLOSE = 0x8,
|
CLOSE = 0x8,
|
||||||
PING = 0x9,
|
PING = 0x9,
|
||||||
PONG = 0xA,
|
PONG = 0xA,
|
||||||
CONTROL_RSVB = 0xB,
|
CONTROL_RSVB = 0xB,
|
||||||
CONTROL_RSVC = 0xC,
|
CONTROL_RSVC = 0xC,
|
||||||
CONTROL_RSVD = 0xD,
|
CONTROL_RSVD = 0xD,
|
||||||
CONTROL_RSVE = 0xE,
|
CONTROL_RSVE = 0xE,
|
||||||
CONTROL_RSVF = 0xF
|
CONTROL_RSVF = 0xF
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Check if an opcode is reserved
|
/// Check if an opcode is reserved
|
||||||
/**
|
/**
|
||||||
* @param v The opcode to test.
|
* @param v The opcode to test.
|
||||||
* @return Whether or not the opcode is reserved.
|
* @return Whether or not the opcode is reserved.
|
||||||
*/
|
*/
|
||||||
inline bool reserved(value v) {
|
inline bool reserved(value v) {
|
||||||
return (v >= rsv3 && v <= rsv7) ||
|
return (v >= rsv3 && v <= rsv7) || (v >= control_rsvb && v <= control_rsvf);
|
||||||
(v >= control_rsvb && v <= control_rsvf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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); }
|
||||||
|
|
||||||
|
/// 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; }
|
||||||
|
} // namespace opcode
|
||||||
|
|
||||||
/// Constants related to frame and payload limits
|
/// Constants related to frame and payload limits
|
||||||
namespace limits {
|
namespace limits {
|
||||||
/// Minimum length of a WebSocket frame header.
|
/// Minimum length of a WebSocket frame header.
|
||||||
static unsigned int const basic_header_length = 2;
|
static unsigned int const basic_header_length = 2;
|
||||||
|
|
||||||
/// Maximum length of a WebSocket header
|
/// Maximum length of a WebSocket header
|
||||||
static unsigned int const max_header_length = 14;
|
static unsigned int const max_header_length = 14;
|
||||||
|
|
||||||
/// Maximum length of the variable portion of the WebSocket header
|
/// Maximum length of the variable portion of the WebSocket header
|
||||||
static unsigned int const max_extended_header_length = 12;
|
static unsigned int const max_extended_header_length = 12;
|
||||||
|
|
||||||
/// Maximum size of a basic WebSocket payload
|
/// Maximum size of a basic WebSocket payload
|
||||||
static uint8_t const payload_size_basic = 125;
|
static uint8_t const payload_size_basic = 125;
|
||||||
|
|
||||||
/// Maximum size of an extended WebSocket payload (basic payload = 126)
|
/// Maximum size of an extended WebSocket payload (basic payload = 126)
|
||||||
static uint16_t const payload_size_extended = 0xFFFF; // 2^16, 65535
|
static uint16_t const payload_size_extended = 0xFFFF; // 2^16, 65535
|
||||||
|
|
||||||
/// Maximum size of a jumbo WebSocket payload (basic payload = 127)
|
/// Maximum size of a jumbo WebSocket payload (basic payload = 127)
|
||||||
static uint64_t const payload_size_jumbo = 0x7FFFFFFFFFFFFFFFLL;//2^63
|
static uint64_t const payload_size_jumbo = 0x7FFFFFFFFFFFFFFFLL; // 2^63
|
||||||
|
|
||||||
/// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// 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;
|
||||||
|
} // namespace limits
|
||||||
|
|
||||||
// masks for fields in the basic header
|
// masks for fields in the basic header
|
||||||
static uint8_t const BHB0_OPCODE = 0x0F;
|
static uint8_t const BHB0_OPCODE = 0x0F;
|
||||||
@@ -180,98 +175,97 @@ static uint8_t const BHB0_FIN = 0x80;
|
|||||||
static uint8_t const BHB1_PAYLOAD = 0x7F;
|
static uint8_t const BHB1_PAYLOAD = 0x7F;
|
||||||
static uint8_t const BHB1_MASK = 0x80;
|
static uint8_t const BHB1_MASK = 0x80;
|
||||||
|
|
||||||
static uint8_t const payload_size_code_16bit = 0x7E; // 126
|
static uint8_t const payload_size_code_16bit = 0x7E; // 126
|
||||||
static uint8_t const payload_size_code_64bit = 0x7F; // 127
|
static uint8_t const payload_size_code_64bit = 0x7F; // 127
|
||||||
|
|
||||||
typedef uint32_converter masking_key_type;
|
typedef uint32_converter masking_key_type;
|
||||||
|
|
||||||
/// The constant size component of a WebSocket frame header
|
/// The constant size component of a WebSocket frame header
|
||||||
struct basic_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(uint8_t p0, uint8_t p1) : b0(p0), b1(p1) {}
|
||||||
|
|
||||||
basic_header(opcode::value op, uint64_t size, bool fin, bool mask,
|
basic_header(opcode::value op, uint64_t size, bool fin, bool mask,
|
||||||
bool rsv1 = false, bool rsv2 = false, bool rsv3 = false) : b0(0x00),
|
bool rsv1 = false, bool rsv2 = false, bool rsv3 = false)
|
||||||
b1(0x00)
|
: b0(0x00), b1(0x00) {
|
||||||
{
|
if (fin) {
|
||||||
if (fin) {
|
b0 |= BHB0_FIN;
|
||||||
b0 |= BHB0_FIN;
|
}
|
||||||
}
|
if (rsv1) {
|
||||||
if (rsv1) {
|
b0 |= BHB0_RSV1;
|
||||||
b0 |= BHB0_RSV1;
|
}
|
||||||
}
|
if (rsv2) {
|
||||||
if (rsv2) {
|
b0 |= BHB0_RSV2;
|
||||||
b0 |= BHB0_RSV2;
|
}
|
||||||
}
|
if (rsv3) {
|
||||||
if (rsv3) {
|
b0 |= BHB0_RSV3;
|
||||||
b0 |= BHB0_RSV3;
|
}
|
||||||
}
|
b0 |= (op & BHB0_OPCODE);
|
||||||
b0 |= (op & BHB0_OPCODE);
|
|
||||||
|
|
||||||
if (mask) {
|
if (mask) {
|
||||||
b1 |= BHB1_MASK;
|
b1 |= BHB1_MASK;
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t basic_value;
|
|
||||||
|
|
||||||
if (size <= limits::payload_size_basic) {
|
|
||||||
basic_value = static_cast<uint8_t>(size);
|
|
||||||
} else if (size <= limits::payload_size_extended) {
|
|
||||||
basic_value = payload_size_code_16bit;
|
|
||||||
} else {
|
|
||||||
basic_value = payload_size_code_64bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
b1 |= basic_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t b0;
|
uint8_t basic_value;
|
||||||
uint8_t b1;
|
|
||||||
|
if (size <= limits::payload_size_basic) {
|
||||||
|
basic_value = static_cast<uint8_t>(size);
|
||||||
|
} else if (size <= limits::payload_size_extended) {
|
||||||
|
basic_value = payload_size_code_16bit;
|
||||||
|
} else {
|
||||||
|
basic_value = payload_size_code_64bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
b1 |= basic_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t b0;
|
||||||
|
uint8_t b1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The variable size component of a WebSocket frame header
|
/// The variable size component of a WebSocket frame header
|
||||||
struct extended_header {
|
struct extended_header {
|
||||||
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);
|
||||||
|
|
||||||
|
copy_payload(payload_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_header(uint64_t payload_size, uint32_t masking_key) {
|
||||||
|
std::fill_n(this->bytes, MAX_EXTENDED_HEADER_LENGTH, 0x00);
|
||||||
|
|
||||||
|
// Copy payload size
|
||||||
|
int offset = copy_payload(payload_size);
|
||||||
|
|
||||||
|
// Copy Masking Key
|
||||||
|
uint32_converter temp32;
|
||||||
|
temp32.i = masking_key;
|
||||||
|
std::copy(temp32.c, temp32.c + 4, bytes + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t bytes[MAX_EXTENDED_HEADER_LENGTH];
|
||||||
|
|
||||||
|
private:
|
||||||
|
int copy_payload(uint64_t payload_size) {
|
||||||
|
int payload_offset = 0;
|
||||||
|
|
||||||
|
if (payload_size <= limits::payload_size_basic) {
|
||||||
|
payload_offset = 8;
|
||||||
|
} else if (payload_size <= limits::payload_size_extended) {
|
||||||
|
payload_offset = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
extended_header(uint64_t payload_size) {
|
uint64_converter temp64;
|
||||||
std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
|
temp64.i = lib::net::_htonll(payload_size);
|
||||||
|
std::copy(temp64.c + payload_offset, temp64.c + 8, bytes);
|
||||||
|
|
||||||
copy_payload(payload_size);
|
return 8 - payload_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
extended_header(uint64_t payload_size, uint32_t masking_key) {
|
|
||||||
std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
|
|
||||||
|
|
||||||
// Copy payload size
|
|
||||||
int offset = copy_payload(payload_size);
|
|
||||||
|
|
||||||
// Copy Masking Key
|
|
||||||
uint32_converter temp32;
|
|
||||||
temp32.i = masking_key;
|
|
||||||
std::copy(temp32.c,temp32.c+4,bytes+offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t bytes[MAX_EXTENDED_HEADER_LENGTH];
|
|
||||||
private:
|
|
||||||
int copy_payload(uint64_t payload_size) {
|
|
||||||
int payload_offset = 0;
|
|
||||||
|
|
||||||
if (payload_size <= limits::payload_size_basic) {
|
|
||||||
payload_offset = 8;
|
|
||||||
} else if (payload_size <= limits::payload_size_extended) {
|
|
||||||
payload_offset = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_converter temp64;
|
|
||||||
temp64.i = lib::net::_htonll(payload_size);
|
|
||||||
std::copy(temp64.c+payload_offset,temp64.c+8,bytes);
|
|
||||||
|
|
||||||
return 8-payload_offset;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool get_fin(basic_header const &h);
|
bool get_fin(basic_header const &h);
|
||||||
@@ -295,31 +289,30 @@ uint16_t get_extended_size(extended_header const &);
|
|||||||
uint64_t get_jumbo_size(extended_header const &);
|
uint64_t get_jumbo_size(extended_header const &);
|
||||||
uint64_t get_payload_size(basic_header const &, 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);
|
size_t circshift_prepared_key(size_t prepared_key, size_t offset);
|
||||||
|
|
||||||
// Functions for performing xor based masking and unmasking
|
// Functions for performing xor based masking and unmasking
|
||||||
template <typename input_iter, typename output_iter>
|
template <typename input_iter, typename output_iter>
|
||||||
void byte_mask(input_iter b, input_iter e, output_iter o, masking_key_type
|
void byte_mask(input_iter b, input_iter e, output_iter o,
|
||||||
const & key, size_t key_offset = 0);
|
masking_key_type const &key, size_t key_offset = 0);
|
||||||
template <typename iter_type>
|
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);
|
size_t key_offset = 0);
|
||||||
void word_mask_exact(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);
|
masking_key_type const &key);
|
||||||
void word_mask_exact(uint8_t * data, size_t length, masking_key_type const &
|
void word_mask_exact(uint8_t *data, size_t length, masking_key_type const &key);
|
||||||
key);
|
size_t word_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||||
size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
size_t prepared_key);
|
||||||
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.
|
/// Check whether the frame's FIN bit is set.
|
||||||
/**
|
/**
|
||||||
* @param [in] h The basic header to extract from.
|
* @param [in] h The basic header to extract from.
|
||||||
* @return True if the header's fin bit is set.
|
* @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);
|
return ((h.b0 & BHB0_FIN) == BHB0_FIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the frame's FIN bit
|
/// Set the frame's FIN bit
|
||||||
@@ -327,8 +320,8 @@ inline bool get_fin(basic_header const & h) {
|
|||||||
* @param [out] h Header to set.
|
* @param [out] h Header to set.
|
||||||
* @param [in] value Value to set it to.
|
* @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);
|
h.b0 = (value ? h.b0 | BHB0_FIN : h.b0 & ~BHB0_FIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check whether the frame's RSV1 bit is set
|
/// check whether the frame's RSV1 bit is set
|
||||||
@@ -337,7 +330,7 @@ inline void set_fin(basic_header & h, bool value) {
|
|||||||
* @return True if the header's RSV1 bit is set.
|
* @return True if the header's RSV1 bit is set.
|
||||||
*/
|
*/
|
||||||
inline bool get_rsv1(const basic_header &h) {
|
inline bool get_rsv1(const basic_header &h) {
|
||||||
return ((h.b0 & BHB0_RSV1) == BHB0_RSV1);
|
return ((h.b0 & BHB0_RSV1) == BHB0_RSV1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the frame's RSV1 bit
|
/// Set the frame's RSV1 bit
|
||||||
@@ -346,7 +339,7 @@ inline bool get_rsv1(const basic_header &h) {
|
|||||||
* @param [in] value Value to set it to.
|
* @param [in] value Value to set it to.
|
||||||
*/
|
*/
|
||||||
inline void set_rsv1(basic_header &h, bool value) {
|
inline void set_rsv1(basic_header &h, bool value) {
|
||||||
h.b0 = (value ? h.b0 | BHB0_RSV1 : h.b0 & ~BHB0_RSV1);
|
h.b0 = (value ? h.b0 | BHB0_RSV1 : h.b0 & ~BHB0_RSV1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check whether the frame's RSV2 bit is set
|
/// check whether the frame's RSV2 bit is set
|
||||||
@@ -355,7 +348,7 @@ inline void set_rsv1(basic_header &h, bool value) {
|
|||||||
* @return True if the header's RSV2 bit is set.
|
* @return True if the header's RSV2 bit is set.
|
||||||
*/
|
*/
|
||||||
inline bool get_rsv2(const basic_header &h) {
|
inline bool get_rsv2(const basic_header &h) {
|
||||||
return ((h.b0 & BHB0_RSV2) == BHB0_RSV2);
|
return ((h.b0 & BHB0_RSV2) == BHB0_RSV2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the frame's RSV2 bit
|
/// Set the frame's RSV2 bit
|
||||||
@@ -364,7 +357,7 @@ inline bool get_rsv2(const basic_header &h) {
|
|||||||
* @param [in] value Value to set it to.
|
* @param [in] value Value to set it to.
|
||||||
*/
|
*/
|
||||||
inline void set_rsv2(basic_header &h, bool value) {
|
inline void set_rsv2(basic_header &h, bool value) {
|
||||||
h.b0 = (value ? h.b0 | BHB0_RSV2 : h.b0 & ~BHB0_RSV2);
|
h.b0 = (value ? h.b0 | BHB0_RSV2 : h.b0 & ~BHB0_RSV2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check whether the frame's RSV3 bit is set
|
/// check whether the frame's RSV3 bit is set
|
||||||
@@ -373,7 +366,7 @@ inline void set_rsv2(basic_header &h, bool value) {
|
|||||||
* @return True if the header's RSV3 bit is set.
|
* @return True if the header's RSV3 bit is set.
|
||||||
*/
|
*/
|
||||||
inline bool get_rsv3(const basic_header &h) {
|
inline bool get_rsv3(const basic_header &h) {
|
||||||
return ((h.b0 & BHB0_RSV3) == BHB0_RSV3);
|
return ((h.b0 & BHB0_RSV3) == BHB0_RSV3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the frame's RSV3 bit
|
/// Set the frame's RSV3 bit
|
||||||
@@ -382,7 +375,7 @@ inline bool get_rsv3(const basic_header &h) {
|
|||||||
* @param [in] value Value to set it to.
|
* @param [in] value Value to set it to.
|
||||||
*/
|
*/
|
||||||
inline void set_rsv3(basic_header &h, bool value) {
|
inline void set_rsv3(basic_header &h, bool value) {
|
||||||
h.b0 = (value ? h.b0 | BHB0_RSV3 : h.b0 & ~BHB0_RSV3);
|
h.b0 = (value ? h.b0 | BHB0_RSV3 : h.b0 & ~BHB0_RSV3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract opcode from basic header
|
/// Extract opcode from basic header
|
||||||
@@ -391,7 +384,7 @@ inline void set_rsv3(basic_header &h, bool value) {
|
|||||||
* @return The opcode value of the header.
|
* @return The opcode value of the header.
|
||||||
*/
|
*/
|
||||||
inline opcode::value get_opcode(const basic_header &h) {
|
inline opcode::value get_opcode(const basic_header &h) {
|
||||||
return opcode::value(h.b0 & BHB0_OPCODE);
|
return opcode::value(h.b0 & BHB0_OPCODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check whether the frame is masked
|
/// check whether the frame is masked
|
||||||
@@ -399,8 +392,8 @@ inline opcode::value get_opcode(const basic_header &h) {
|
|||||||
* @param [in] h The basic header to extract from.
|
* @param [in] h The basic header to extract from.
|
||||||
* @return True if the header mask bit is set.
|
* @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);
|
return ((h.b1 & BHB1_MASK) == BHB1_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the frame's MASK bit
|
/// Set the frame's MASK bit
|
||||||
@@ -408,8 +401,8 @@ inline bool get_masked(basic_header const & h) {
|
|||||||
* @param [out] h Header to set.
|
* @param [out] h Header to set.
|
||||||
* @param value Value to set it to.
|
* @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);
|
h.b1 = (value ? h.b1 | BHB1_MASK : h.b1 & ~BHB1_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts the raw payload length specified in the basic header
|
/// Extracts the raw payload length specified in the basic header
|
||||||
@@ -429,7 +422,7 @@ inline void set_masked(basic_header & h, bool value) {
|
|||||||
* @return The exact size encoded in h.
|
* @return The exact size encoded in h.
|
||||||
*/
|
*/
|
||||||
inline uint8_t get_basic_size(const basic_header &h) {
|
inline uint8_t get_basic_size(const basic_header &h) {
|
||||||
return h.b1 & BHB1_PAYLOAD;
|
return h.b1 & BHB1_PAYLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the full length of the header based on the first bytes.
|
/// Calculates the full length of the header based on the first bytes.
|
||||||
@@ -442,19 +435,19 @@ inline uint8_t get_basic_size(const basic_header &h) {
|
|||||||
* @param h Basic frame header to extract size from.
|
* @param h Basic frame header to extract size from.
|
||||||
* @return Full length of the extended header.
|
* @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?
|
// TODO: check extensions?
|
||||||
|
|
||||||
// masking key offset represents the space used for the extended length
|
// masking key offset represents the space used for the extended length
|
||||||
// fields
|
// fields
|
||||||
size_t size = BASIC_HEADER_LENGTH + get_masking_key_offset(h);
|
size_t size = BASIC_HEADER_LENGTH + get_masking_key_offset(h);
|
||||||
|
|
||||||
// If the header is masked there is a 4 byte masking key
|
// If the header is masked there is a 4 byte masking key
|
||||||
if (get_masked(h)) {
|
if (get_masked(h)) {
|
||||||
size += 4;
|
size += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the offset location of the masking key within the extended header
|
/// Calculate the offset location of the masking key within the extended header
|
||||||
@@ -467,13 +460,13 @@ inline size_t get_header_len(basic_header const & h) {
|
|||||||
* @return byte offset of the first byte of the masking key
|
* @return byte offset of the first byte of the masking key
|
||||||
*/
|
*/
|
||||||
inline unsigned int get_masking_key_offset(const basic_header &h) {
|
inline unsigned int get_masking_key_offset(const basic_header &h) {
|
||||||
if (get_basic_size(h) == payload_size_code_16bit) {
|
if (get_basic_size(h) == payload_size_code_16bit) {
|
||||||
return 2;
|
return 2;
|
||||||
} else if (get_basic_size(h) == payload_size_code_64bit) {
|
} else if (get_basic_size(h) == payload_size_code_64bit) {
|
||||||
return 8;
|
return 8;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a properly sized contiguous string that encodes a full frame header
|
/// Generate a properly sized contiguous string that encodes a full frame header
|
||||||
@@ -486,19 +479,16 @@ inline unsigned int get_masking_key_offset(const basic_header &h) {
|
|||||||
*
|
*
|
||||||
* @return A contiguous string containing h and e
|
* @return A contiguous string containing h and e
|
||||||
*/
|
*/
|
||||||
inline std::string prepare_header(const basic_header &h, const
|
inline std::string prepare_header(const basic_header &h,
|
||||||
extended_header &e)
|
const extended_header &e) {
|
||||||
{
|
std::string ret;
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
ret.push_back(char(h.b0));
|
ret.push_back(char(h.b0));
|
||||||
ret.push_back(char(h.b1));
|
ret.push_back(char(h.b1));
|
||||||
ret.append(
|
ret.append(reinterpret_cast<const char *>(e.bytes),
|
||||||
reinterpret_cast<const char*>(e.bytes),
|
get_header_len(h) - BASIC_HEADER_LENGTH);
|
||||||
get_header_len(h)-BASIC_HEADER_LENGTH
|
|
||||||
);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the masking key from a frame header
|
/// Extract the masking key from a frame header
|
||||||
@@ -513,19 +503,18 @@ inline std::string prepare_header(const basic_header &h, const
|
|||||||
*
|
*
|
||||||
* @return The masking key as an integer.
|
* @return The masking key as an integer.
|
||||||
*/
|
*/
|
||||||
inline masking_key_type get_masking_key(const basic_header &h, const
|
inline masking_key_type get_masking_key(const basic_header &h,
|
||||||
extended_header &e)
|
const extended_header &e) {
|
||||||
{
|
masking_key_type temp32;
|
||||||
masking_key_type temp32;
|
|
||||||
|
|
||||||
if (!get_masked(h)) {
|
if (!get_masked(h)) {
|
||||||
temp32.i = 0;
|
temp32.i = 0;
|
||||||
} else {
|
} else {
|
||||||
unsigned int offset = get_masking_key_offset(h);
|
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;
|
return temp32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the extended size field from an extended header
|
/// Extract the extended size field from an extended header
|
||||||
@@ -538,9 +527,9 @@ inline masking_key_type get_masking_key(const basic_header &h, const
|
|||||||
* @return The size encoded in the extended header in host byte order
|
* @return The size encoded in the extended header in host byte order
|
||||||
*/
|
*/
|
||||||
inline uint16_t get_extended_size(const extended_header &e) {
|
inline uint16_t get_extended_size(const extended_header &e) {
|
||||||
uint16_converter temp16;
|
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);
|
return ntohs(temp16.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the jumbo size field from an extended header
|
/// Extract the jumbo size field from an extended header
|
||||||
@@ -553,9 +542,9 @@ inline uint16_t get_extended_size(const extended_header &e) {
|
|||||||
* @return The size encoded in the extended header in host byte order
|
* @return The size encoded in the extended header in host byte order
|
||||||
*/
|
*/
|
||||||
inline uint64_t get_jumbo_size(const extended_header &e) {
|
inline uint64_t get_jumbo_size(const extended_header &e) {
|
||||||
uint64_converter temp64;
|
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);
|
return lib::net::_ntohll(temp64.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the full payload size field from a WebSocket header
|
/// Extract the full payload size field from a WebSocket header
|
||||||
@@ -570,18 +559,17 @@ inline uint64_t get_jumbo_size(const extended_header &e) {
|
|||||||
*
|
*
|
||||||
* @return The size encoded in the combined header in host byte order.
|
* @return The size encoded in the combined header in host byte order.
|
||||||
*/
|
*/
|
||||||
inline uint64_t get_payload_size(const basic_header &h, const
|
inline uint64_t get_payload_size(const basic_header &h,
|
||||||
extended_header &e)
|
const extended_header &e) {
|
||||||
{
|
uint8_t val = get_basic_size(h);
|
||||||
uint8_t val = get_basic_size(h);
|
|
||||||
|
|
||||||
if (val <= limits::payload_size_basic) {
|
if (val <= limits::payload_size_basic) {
|
||||||
return val;
|
return val;
|
||||||
} else if (val == payload_size_code_16bit) {
|
} else if (val == payload_size_code_16bit) {
|
||||||
return get_extended_size(e);
|
return get_extended_size(e);
|
||||||
} else {
|
} else {
|
||||||
return get_jumbo_size(e);
|
return get_jumbo_size(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract a masking key into a value the size of a machine word.
|
/// Extract a masking key into a value the size of a machine word.
|
||||||
@@ -592,15 +580,15 @@ inline uint64_t get_payload_size(const basic_header &h, const
|
|||||||
*
|
*
|
||||||
* @return prepared key as a machine word
|
* @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);
|
size_t low_bits = static_cast<size_t>(key.i);
|
||||||
|
|
||||||
if (sizeof(size_t) == 8) {
|
if (sizeof(size_t) == 8) {
|
||||||
uint64_t high_bits = static_cast<size_t>(key.i);
|
uint64_t high_bits = static_cast<size_t>(key.i);
|
||||||
return static_cast<size_t>((high_bits << 32) | low_bits);
|
return static_cast<size_t>((high_bits << 32) | low_bits);
|
||||||
} else {
|
} else {
|
||||||
return low_bits;
|
return low_bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// circularly shifts the supplied prepared masking key by offset bytes
|
/// circularly shifts the supplied prepared masking key by offset bytes
|
||||||
@@ -610,16 +598,16 @@ inline size_t prepare_masking_key(const masking_key_type& key) {
|
|||||||
* to zero and less than sizeof(size_t).
|
* to zero and less than sizeof(size_t).
|
||||||
*/
|
*/
|
||||||
inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
|
inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
return prepared_key;
|
return prepared_key;
|
||||||
}
|
}
|
||||||
if (lib::net::is_little_endian()) {
|
if (lib::net::is_little_endian()) {
|
||||||
size_t temp = prepared_key << (sizeof(size_t)-offset)*8;
|
size_t temp = prepared_key << (sizeof(size_t) - offset) * 8;
|
||||||
return (prepared_key >> offset*8) | temp;
|
return (prepared_key >> offset * 8) | temp;
|
||||||
} else {
|
} else {
|
||||||
size_t temp = prepared_key >> (sizeof(size_t)-offset)*8;
|
size_t temp = prepared_key >> (sizeof(size_t) - offset) * 8;
|
||||||
return (prepared_key << offset*8) | temp;
|
return (prepared_key << offset * 8) | temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Byte by byte mask/unmask
|
/// Byte by byte mask/unmask
|
||||||
@@ -643,15 +631,14 @@ inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
|
|||||||
*/
|
*/
|
||||||
template <typename input_iter, typename output_iter>
|
template <typename input_iter, typename output_iter>
|
||||||
void byte_mask(input_iter first, input_iter last, output_iter result,
|
void byte_mask(input_iter first, input_iter last, output_iter result,
|
||||||
masking_key_type const & key, size_t key_offset)
|
masking_key_type const &key, size_t key_offset) {
|
||||||
{
|
size_t key_index = key_offset % 4;
|
||||||
size_t key_index = key_offset%4;
|
while (first != last) {
|
||||||
while (first != last) {
|
*result = *first ^ key.c[key_index++];
|
||||||
*result = *first ^ key.c[key_index++];
|
key_index %= 4;
|
||||||
key_index %= 4;
|
++result;
|
||||||
++result;
|
++first;
|
||||||
++first;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Byte by byte mask/unmask (in place)
|
/// Byte by byte mask/unmask (in place)
|
||||||
@@ -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.
|
* @param key_offset offset value to start masking at.
|
||||||
*/
|
*/
|
||||||
template <typename iter_type>
|
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)
|
size_t key_offset) {
|
||||||
{
|
byte_mask(b, e, b, key, key_offset);
|
||||||
byte_mask(b,e,b,key,key_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exact word aligned mask/unmask
|
/// Exact word aligned mask/unmask
|
||||||
@@ -699,21 +685,20 @@ void byte_mask(iter_type b, iter_type e, masking_key_type const & key,
|
|||||||
*
|
*
|
||||||
* @param key Masking key to use
|
* @param key Masking key to use
|
||||||
*/
|
*/
|
||||||
inline void word_mask_exact(uint8_t* input, uint8_t* output, size_t length,
|
inline void word_mask_exact(uint8_t *input, uint8_t *output, size_t length,
|
||||||
const masking_key_type& key)
|
const masking_key_type &key) {
|
||||||
{
|
size_t prepared_key = prepare_masking_key(key);
|
||||||
size_t prepared_key = prepare_masking_key(key);
|
size_t n = length / sizeof(size_t);
|
||||||
size_t n = length/sizeof(size_t);
|
size_t *input_word = reinterpret_cast<size_t *>(input);
|
||||||
size_t* input_word = reinterpret_cast<size_t*>(input);
|
size_t *output_word = reinterpret_cast<size_t *>(output);
|
||||||
size_t* output_word = reinterpret_cast<size_t*>(output);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
output_word[i] = input_word[i] ^ prepared_key;
|
output_word[i] = input_word[i] ^ prepared_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = n*sizeof(size_t); i < length; i++) {
|
for (size_t i = n * sizeof(size_t); i < length; i++) {
|
||||||
output[i] = input[i] ^ key.c[i%4];
|
output[i] = input[i] ^ key.c[i % 4];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exact word aligned mask/unmask (in place)
|
/// Exact word aligned mask/unmask (in place)
|
||||||
@@ -728,10 +713,9 @@ inline void word_mask_exact(uint8_t* input, uint8_t* output, size_t length,
|
|||||||
*
|
*
|
||||||
* @param key Masking key to use
|
* @param key Masking key to use
|
||||||
*/
|
*/
|
||||||
inline void word_mask_exact(uint8_t* data, size_t length, const
|
inline void word_mask_exact(uint8_t *data, size_t length,
|
||||||
masking_key_type& key)
|
const masking_key_type &key) {
|
||||||
{
|
word_mask_exact(data, data, length, key);
|
||||||
word_mask_exact(data,data,length,key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Circular word aligned mask/unmask
|
/// Circular word aligned mask/unmask
|
||||||
@@ -765,27 +749,26 @@ inline void word_mask_exact(uint8_t* data, size_t length, const
|
|||||||
*
|
*
|
||||||
* @return the prepared_key shifted to account for the input length
|
* @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,
|
inline size_t word_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||||
size_t prepared_key)
|
size_t prepared_key) {
|
||||||
{
|
size_t n = length / sizeof(size_t); // whole words
|
||||||
size_t n = length / sizeof(size_t); // whole words
|
size_t l = length - (n * sizeof(size_t)); // remaining bytes
|
||||||
size_t l = length - (n * sizeof(size_t)); // remaining bytes
|
size_t *input_word = reinterpret_cast<size_t *>(input);
|
||||||
size_t * input_word = reinterpret_cast<size_t *>(input);
|
size_t *output_word = reinterpret_cast<size_t *>(output);
|
||||||
size_t * output_word = reinterpret_cast<size_t *>(output);
|
|
||||||
|
|
||||||
// mask word by word
|
// mask word by word
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
output_word[i] = input_word[i] ^ prepared_key;
|
output_word[i] = input_word[i] ^ prepared_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mask partial word at the end
|
// mask partial word at the end
|
||||||
size_t start = length - l;
|
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) {
|
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)
|
/// 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
|
* @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){
|
inline size_t word_mask_circ(uint8_t *data, size_t length,
|
||||||
return word_mask_circ(data,data,length,prepared_key);
|
size_t prepared_key) {
|
||||||
|
return word_mask_circ(data, data, length, prepared_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Circular byte aligned mask/unmask
|
/// Circular byte aligned mask/unmask
|
||||||
@@ -827,17 +811,16 @@ 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
|
* @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,
|
inline size_t byte_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||||
size_t prepared_key)
|
size_t prepared_key) {
|
||||||
{
|
uint32_converter key;
|
||||||
uint32_converter key;
|
key.i = prepared_key;
|
||||||
key.i = prepared_key;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < length; ++i) {
|
for (size_t i = 0; i < length; ++i) {
|
||||||
output[i] = input[i] ^ key.c[i % 4];
|
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)
|
/// 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
|
* @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){
|
inline size_t byte_mask_circ(uint8_t *data, size_t length,
|
||||||
return byte_mask_circ(data,data,length,prepared_key);
|
size_t prepared_key) {
|
||||||
|
return byte_mask_circ(data, data, length, prepared_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace frame
|
} // namespace frame
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|
||||||
#endif //WEBSOCKETPP_FRAME_HPP
|
#endif // WEBSOCKETPP_FRAME_HPP
|
||||||
|
#pragma warning(pop)
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4267)
|
||||||
|
|
||||||
#ifndef SHA1_DEFINED
|
#ifndef SHA1_DEFINED
|
||||||
#define SHA1_DEFINED
|
#define SHA1_DEFINED
|
||||||
@@ -39,83 +41,74 @@ under the same license as the original, which is listed below.
|
|||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace sha1 {
|
namespace sha1 {
|
||||||
|
|
||||||
namespace { // local
|
namespace { // local
|
||||||
|
|
||||||
// Rotate an integer value to left.
|
// Rotate an integer value to left.
|
||||||
inline unsigned int rol(unsigned int value, unsigned int steps) {
|
inline unsigned int rol(unsigned int value, unsigned int steps) {
|
||||||
return ((value << steps) | (value >> (32 - steps)));
|
return ((value << steps) | (value >> (32 - steps)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the first 16 integers in the buffert to zero.
|
// Sets the first 16 integers in the buffert to zero.
|
||||||
// Used for clearing the W buffert.
|
// Used for clearing the W buffert.
|
||||||
inline void clearWBuffert(unsigned int * buffert)
|
inline void clearWBuffert(unsigned int *buffert) {
|
||||||
{
|
for (int pos = 16; --pos >= 0;) {
|
||||||
for (int pos = 16; --pos >= 0;)
|
buffert[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 a = result[0];
|
unsigned int b = result[1];
|
||||||
unsigned int b = result[1];
|
unsigned int c = result[2];
|
||||||
unsigned int c = result[2];
|
unsigned int d = result[3];
|
||||||
unsigned int d = result[3];
|
unsigned int e = result[4];
|
||||||
unsigned int e = result[4];
|
|
||||||
|
|
||||||
int round = 0;
|
int round = 0;
|
||||||
|
|
||||||
#define sha1macro(func,val) \
|
#define sha1macro(func, val) \
|
||||||
{ \
|
{ \
|
||||||
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||||
e = d; \
|
e = d; \
|
||||||
d = c; \
|
d = c; \
|
||||||
c = rol(b, 30); \
|
c = rol(b, 30); \
|
||||||
b = a; \
|
b = a; \
|
||||||
a = t; \
|
a = t; \
|
||||||
}
|
}
|
||||||
|
|
||||||
while (round < 16)
|
while (round < 16) {
|
||||||
{
|
sha1macro((b & c) | (~b & d), 0x5a827999)++ round;
|
||||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
}
|
||||||
++round;
|
while (round < 20) {
|
||||||
}
|
w[round] =
|
||||||
while (round < 20)
|
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
{
|
sha1macro((b & c) | (~b & d), 0x5a827999)++ round;
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
}
|
||||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
while (round < 40) {
|
||||||
++round;
|
w[round] =
|
||||||
}
|
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
while (round < 40)
|
sha1macro(b ^ c ^ d, 0x6ed9eba1)++ round;
|
||||||
{
|
}
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
while (round < 60) {
|
||||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
w[round] =
|
||||||
++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)
|
}
|
||||||
{
|
while (round < 80) {
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
w[round] =
|
||||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
++round;
|
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[0] += a;
|
||||||
result[1] += b;
|
result[1] += b;
|
||||||
result[2] += c;
|
result[2] += c;
|
||||||
result[3] += d;
|
result[3] += d;
|
||||||
result[4] += e;
|
result[4] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
/// Calculate a SHA1 hash
|
/// Calculate a SHA1 hash
|
||||||
/**
|
/**
|
||||||
@@ -124,66 +117,70 @@ 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
|
* @param hash should point to a buffer of at least 20 bytes of size for storing
|
||||||
* the sha1 result in.
|
* 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.
|
// Init the result array.
|
||||||
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
|
unsigned int result[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
|
||||||
0x10325476, 0xc3d2e1f0 };
|
0xc3d2e1f0};
|
||||||
|
|
||||||
// Cast the void src pointer to be the byte array we can work with.
|
// 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
|
// The reusable round buffer
|
||||||
unsigned int w[80];
|
unsigned int w[80];
|
||||||
|
|
||||||
// Loop through all complete 64byte blocks.
|
// Loop through all complete 64byte blocks.
|
||||||
|
|
||||||
size_t endCurrentBlock;
|
size_t endCurrentBlock;
|
||||||
size_t currentBlock = 0;
|
size_t currentBlock = 0;
|
||||||
|
|
||||||
if (bytelength >= 64) {
|
if (bytelength >= 64) {
|
||||||
size_t const endOfFullBlocks = bytelength - 64;
|
size_t const endOfFullBlocks = bytelength - 64;
|
||||||
|
|
||||||
while (currentBlock <= endOfFullBlocks) {
|
while (currentBlock <= endOfFullBlocks) {
|
||||||
endCurrentBlock = currentBlock + 64;
|
endCurrentBlock = currentBlock + 64;
|
||||||
|
|
||||||
// Init the round buffer with the 64 byte block data.
|
// 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
|
// This line will swap endian on big endian and keep endian on
|
||||||
// little endian.
|
// little endian.
|
||||||
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
w[roundPos++] = (unsigned int)sarray[currentBlock + 3] |
|
||||||
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
(((unsigned int)sarray[currentBlock + 2]) << 8) |
|
||||||
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
(((unsigned int)sarray[currentBlock + 1]) << 16) |
|
||||||
| (((unsigned int) sarray[currentBlock]) << 24);
|
(((unsigned int)sarray[currentBlock]) << 24);
|
||||||
}
|
}
|
||||||
innerHash(result, w);
|
innerHash(result, w);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle the last and not full 64 byte block if existing.
|
// Handle the last and not full 64 byte block if existing.
|
||||||
endCurrentBlock = bytelength - currentBlock;
|
endCurrentBlock = bytelength - currentBlock;
|
||||||
clearWBuffert(w);
|
clearWBuffert(w);
|
||||||
size_t lastBlockBytes = 0;
|
size_t lastBlockBytes = 0;
|
||||||
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
for (; lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
||||||
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
w[lastBlockBytes >> 2] |=
|
||||||
}
|
(unsigned int)sarray[lastBlockBytes + currentBlock]
|
||||||
|
<< ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
|
}
|
||||||
|
|
||||||
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
if (endCurrentBlock >= 56) {
|
if (endCurrentBlock >= 56) {
|
||||||
innerHash(result, w);
|
|
||||||
clearWBuffert(w);
|
|
||||||
}
|
|
||||||
w[15] = bytelength << 3;
|
|
||||||
innerHash(result, w);
|
innerHash(result, w);
|
||||||
|
clearWBuffert(w);
|
||||||
|
}
|
||||||
|
w[15] = bytelength << 3;
|
||||||
|
innerHash(result, w);
|
||||||
|
|
||||||
// Store hash in result pointer, and make sure we get in in the correct
|
// Store hash in result pointer, and make sure we get in in the correct
|
||||||
// order on both endian models.
|
// order on both endian models.
|
||||||
for (int hashByte = 20; --hashByte >= 0;) {
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sha1
|
} // namespace sha1
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|
||||||
#endif // SHA1_DEFINED
|
#endif // SHA1_DEFINED
|
||||||
|
#pragma warning(pop)
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -22,8 +22,7 @@ includes("thirdparty")
|
|||||||
|
|
||||||
if is_os("windows") then
|
if is_os("windows") then
|
||||||
add_defines("_WEBSOCKETPP_CPP11_INTERNAL_")
|
add_defines("_WEBSOCKETPP_CPP11_INTERNAL_")
|
||||||
-- add_cxflags("/W4", "/WX")
|
add_cxflags("/W4", "/WX")
|
||||||
add_cxflags("/W4")
|
|
||||||
elseif is_os("linux") then
|
elseif is_os("linux") then
|
||||||
add_requires("glib", {system = true})
|
add_requires("glib", {system = true})
|
||||||
add_packages("glib")
|
add_packages("glib")
|
||||||
@@ -176,8 +175,8 @@ target("media")
|
|||||||
target("qos")
|
target("qos")
|
||||||
set_kind("object")
|
set_kind("object")
|
||||||
add_deps("log")
|
add_deps("log")
|
||||||
add_files("src/qos/kcp/*.c")
|
add_files("src/qos/*.cpp")
|
||||||
add_includedirs("src/qos/kcp", {public = true})
|
add_includedirs("src/qos", {public = true})
|
||||||
|
|
||||||
target("statistics")
|
target("statistics")
|
||||||
set_kind("object")
|
set_kind("object")
|
||||||
|
|||||||
Reference in New Issue
Block a user