[fix] fix all unused variables and type conversions

This commit is contained in:
dijunkun
2024-11-26 23:30:38 +08:00
parent 7e3856a68d
commit 826fc2d312
39 changed files with 4126 additions and 5696 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
} }

View File

@@ -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;

View File

@@ -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");

View File

@@ -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"; }

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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()

View File

@@ -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(), &timestamp[0], &timestamp[1]); m_vTimestamp.insert(m_vTimestamp.end(), &timestamp[0], &timestamp[1]);
} }
#pragma warning(pop)

View File

@@ -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;
} }
} }

View File

@@ -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

View File

@@ -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;
} }

View File

@@ -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;

View File

@@ -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;
} }

View File

@@ -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;

View File

@@ -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
} }
} }
} }

View File

@@ -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"; }

View File

@@ -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
} }
} }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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"; }

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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);
} }
} }

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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")