Restyle
This commit is contained in:
parent
5b79f296d6
commit
fccf66fba2
280 changed files with 56975 additions and 71885 deletions
62
lib/adts.cpp
62
lib/adts.cpp
|
@ -18,10 +18,10 @@ namespace aac {
|
|||
memcpy(data, _data, len);
|
||||
}
|
||||
|
||||
|
||||
bool adts::sameHeader(const adts &rhs) const{
|
||||
if (!rhs || !*this){return false;}
|
||||
return (getAACProfile() == rhs.getAACProfile() && getFrequencyIndex() == rhs.getFrequencyIndex() && getChannelConfig() == rhs.getChannelConfig());
|
||||
return (getAACProfile() == rhs.getAACProfile() && getFrequencyIndex() == rhs.getFrequencyIndex() &&
|
||||
getChannelConfig() == rhs.getChannelConfig());
|
||||
}
|
||||
|
||||
adts::adts(const adts &rhs){
|
||||
|
@ -31,9 +31,7 @@ namespace aac {
|
|||
}
|
||||
|
||||
adts &adts::operator=(const adts &rhs){
|
||||
if (data){
|
||||
free(data);
|
||||
}
|
||||
if (data){free(data);}
|
||||
len = rhs.len;
|
||||
data = (char *)malloc(len);
|
||||
memcpy(data, rhs.data, len);
|
||||
|
@ -41,30 +39,21 @@ namespace aac {
|
|||
}
|
||||
|
||||
adts::~adts(){
|
||||
if (data){
|
||||
free(data);
|
||||
}
|
||||
if (data){free(data);}
|
||||
}
|
||||
|
||||
unsigned long adts::getAACProfile() const{
|
||||
if (!data || !len){
|
||||
return 0;
|
||||
}
|
||||
if (!data || !len){return 0;}
|
||||
return ((data[2] >> 6) & 0x03) + 1;
|
||||
}
|
||||
|
||||
unsigned long adts::getFrequencyIndex() const{
|
||||
if (!data || !len){
|
||||
return 0;
|
||||
}
|
||||
if (!data || !len){return 0;}
|
||||
return ((data[2] >> 2) & 0x0F);
|
||||
|
||||
}
|
||||
|
||||
unsigned long adts::getFrequency() const{
|
||||
if (!data || len < 3){
|
||||
return 0;
|
||||
}
|
||||
if (!data || len < 3){return 0;}
|
||||
switch (getFrequencyIndex()){
|
||||
case 0: return 96000; break;
|
||||
case 1: return 88200; break;
|
||||
|
@ -84,30 +73,22 @@ namespace aac {
|
|||
}
|
||||
|
||||
unsigned long adts::getChannelConfig() const{
|
||||
if (!data || !len){
|
||||
return 0;
|
||||
}
|
||||
if (!data || !len){return 0;}
|
||||
return ((data[2] & 0x01) << 2) | ((data[3] >> 6) & 0x03);
|
||||
}
|
||||
|
||||
unsigned long adts::getChannelCount() const{
|
||||
if (!data || !len){
|
||||
return 0;
|
||||
}
|
||||
if (!data || !len){return 0;}
|
||||
return (getChannelConfig() == 7 ? 8 : getChannelConfig());
|
||||
}
|
||||
|
||||
unsigned long adts::getHeaderSize() const{
|
||||
if (!data || !len){
|
||||
return 0;
|
||||
}
|
||||
if (!data || !len){return 0;}
|
||||
return (data[1] & 0x01 ? 7 : 9);
|
||||
}
|
||||
|
||||
unsigned long adts::getCompleteSize() const{
|
||||
if (!data || len < 6){
|
||||
return 0;
|
||||
}
|
||||
if (!data || len < 6){return 0;}
|
||||
return (((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] >> 5) & 0x07));
|
||||
}
|
||||
|
||||
|
@ -123,16 +104,12 @@ namespace aac {
|
|||
}
|
||||
|
||||
unsigned long adts::getSampleCount() const{
|
||||
if (!data || len < 7){
|
||||
return 0;
|
||||
}
|
||||
if (!data || len < 7){return 0;}
|
||||
return ((data[6] & 0x03) + 1) * 1024; // Number of samples in this frame * 1024
|
||||
}
|
||||
|
||||
char *adts::getPayload(){
|
||||
if (!data || !len){
|
||||
return 0;
|
||||
}
|
||||
if (!data || !len){return 0;}
|
||||
return data + getHeaderSize();
|
||||
}
|
||||
std::string adts::toPrettyString() const{
|
||||
|
@ -147,12 +124,8 @@ namespace aac {
|
|||
}else{
|
||||
res << " MPEG-4" << std::endl;
|
||||
}
|
||||
if ((data[1] & 0x6) != 0){
|
||||
res << " Non-zero layer!" << std::endl;
|
||||
}
|
||||
if ((data[1] & 0x1) == 0x0){
|
||||
res << " CRC present" << std::endl;
|
||||
}
|
||||
if ((data[1] & 0x6) != 0){res << " Non-zero layer!" << std::endl;}
|
||||
if ((data[1] & 0x1) == 0x0){res << " CRC present" << std::endl;}
|
||||
res << " MPEG-4 audio object type: " << getAACProfile() << std::endl;
|
||||
res << " Frequency: " << getFrequency() << "Hz" << std::endl;
|
||||
res << " Channels: " << getChannelCount() << std::endl;
|
||||
|
@ -161,9 +134,10 @@ namespace aac {
|
|||
return res.str();
|
||||
}
|
||||
adts::operator bool() const{
|
||||
return hasSync() && len && len >= getHeaderSize() && getFrequency() && getChannelCount() && getSampleCount();
|
||||
return hasSync() && len && len >= getHeaderSize() && getFrequency() && getChannelCount() &&
|
||||
getSampleCount();
|
||||
}
|
||||
bool adts::hasSync() const{
|
||||
return len && (((int)data[0] << 4) | ((data[1] >> 4) & 0x0F)) == 0xfff;
|
||||
}
|
||||
}
|
||||
}// namespace aac
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "bitstream.h"
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include "bitstream.h"
|
||||
|
||||
namespace aac{
|
||||
class adts{
|
||||
|
@ -24,6 +24,7 @@ namespace aac {
|
|||
char *getPayload();
|
||||
std::string toPrettyString() const;
|
||||
operator bool() const;
|
||||
|
||||
private:
|
||||
char *data;
|
||||
unsigned long len;
|
||||
|
@ -91,6 +92,4 @@ namespace aac {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
}// namespace aac
|
||||
|
|
37
lib/amf.cpp
37
lib/amf.cpp
|
@ -328,8 +328,7 @@ std::string AMF::Object::Pack(){
|
|||
/// \param i Current parsing position in the raw data.
|
||||
/// \param name Indice name for any new object created.
|
||||
/// \returns A single AMF::Object, parsed from the raw data.
|
||||
AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigned int &i,
|
||||
std::string name){
|
||||
AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigned int &i, std::string name){
|
||||
std::string tmpstr;
|
||||
unsigned int tmpi = 0;
|
||||
unsigned char tmpdbl[8];
|
||||
|
@ -375,16 +374,14 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne
|
|||
return AMF::Object(name, (double)tmpi, AMF::AMF0_REFERENCE);
|
||||
break;
|
||||
case AMF::AMF0_XMLDOC:
|
||||
tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 +
|
||||
data[i + 4]; // set tmpi to UTF-8-long length
|
||||
tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; // set tmpi to UTF-8-long length
|
||||
tmpstr.clear(); // clean tmpstr, just to be sure
|
||||
tmpstr.append((const char *)data + i + 5, (size_t)tmpi); // add the string data
|
||||
i += tmpi + 5; // skip length+size+1 forwards
|
||||
return AMF::Object(name, tmpstr, AMF::AMF0_XMLDOC);
|
||||
break;
|
||||
case AMF::AMF0_LONGSTRING:
|
||||
tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 +
|
||||
data[i + 4]; // set tmpi to UTF-8-long length
|
||||
tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; // set tmpi to UTF-8-long length
|
||||
tmpstr.clear(); // clean tmpstr, just to be sure
|
||||
tmpstr.append((const char *)data + i + 5, (size_t)tmpi); // add the string data
|
||||
i += tmpi + 5; // skip length+size+1 forwards
|
||||
|
@ -411,8 +408,7 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne
|
|||
tmpstr.clear(); // clean tmpstr, just to be sure
|
||||
tmpstr.append((const char *)data + i + 2, (size_t)tmpi); // add the string data
|
||||
i += tmpi + 2; // skip length+size forwards
|
||||
ret.addContent(AMF::parseOne(
|
||||
data, len, i,
|
||||
ret.addContent(AMF::parseOne(data, len, i,
|
||||
tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr
|
||||
}
|
||||
i += 3; // skip 0x000009
|
||||
|
@ -429,8 +425,7 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne
|
|||
tmpstr.clear(); // clean tmpstr, just to be sure
|
||||
tmpstr.append((const char *)data + i + 2, (size_t)tmpi); // add the string data
|
||||
i += tmpi + 2; // skip length+size forwards
|
||||
ret.addContent(AMF::parseOne(
|
||||
data, len, i,
|
||||
ret.addContent(AMF::parseOne(data, len, i,
|
||||
tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr
|
||||
}
|
||||
i += 3; // skip 0x000009
|
||||
|
@ -445,8 +440,7 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne
|
|||
tmpstr.clear(); // clean tmpstr, just to be sure
|
||||
tmpstr.append((const char *)data + i + 2, (size_t)tmpi); // add the string data
|
||||
i += tmpi + 2; // skip length+size forwards
|
||||
ret.addContent(AMF::parseOne(
|
||||
data, len, i,
|
||||
ret.addContent(AMF::parseOne(data, len, i,
|
||||
tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr
|
||||
}
|
||||
i += 3; // skip 0x000009
|
||||
|
@ -454,12 +448,10 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne
|
|||
}break;
|
||||
case AMF::AMF0_STRICT_ARRAY:{
|
||||
AMF::Object ret(name, AMF::AMF0_STRICT_ARRAY);
|
||||
tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 +
|
||||
data[i + 4]; // set tmpi to array length
|
||||
tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; // set tmpi to array length
|
||||
i += 5; // skip size+1 forwards
|
||||
while (tmpi > 0){// while not done parsing array
|
||||
ret.addContent(
|
||||
AMF::parseOne(data, len, i, "arrVal")); // add content, recursively parsed, updating i
|
||||
ret.addContent(AMF::parseOne(data, len, i, "arrVal")); // add content, recursively parsed, updating i
|
||||
--tmpi;
|
||||
}
|
||||
return ret;
|
||||
|
@ -712,8 +704,7 @@ std::string AMF::Object3::Pack(){
|
|||
/// \param i Current parsing position in the raw data.
|
||||
/// \param name Indice name for any new object created.
|
||||
/// \returns A single AMF::Object3, parsed from the raw data.
|
||||
AMF::Object3 AMF::parseOne3(const unsigned char *&data, unsigned int &len, unsigned int &i,
|
||||
std::string name){
|
||||
AMF::Object3 AMF::parseOne3(const unsigned char *&data, unsigned int &len, unsigned int &i, std::string name){
|
||||
std::string tmpstr;
|
||||
unsigned int tmpi = 0;
|
||||
unsigned int arrsize = 0;
|
||||
|
@ -974,13 +965,11 @@ AMF::Object3 AMF::parseOne3(const unsigned char *&data, unsigned int &len, unsig
|
|||
if (tmpi > 0){
|
||||
tmpstr.clear(); // clean tmpstr, just to be sure
|
||||
tmpstr.append((const char *)data + i, (size_t)tmpi); // add the string data
|
||||
ret.addContent(
|
||||
AMF::parseOne3(data, len, i, tmpstr)); // add content, recursively parsed, updating i
|
||||
ret.addContent(AMF::parseOne3(data, len, i, tmpstr)); // add content, recursively parsed, updating i
|
||||
}
|
||||
}while (tmpi > 0);
|
||||
while (arrsize > 0){// while not done parsing array
|
||||
ret.addContent(
|
||||
AMF::parseOne3(data, len, i, "arrVal")); // add content, recursively parsed, updating i
|
||||
ret.addContent(AMF::parseOne3(data, len, i, "arrVal")); // add content, recursively parsed, updating i
|
||||
--arrsize;
|
||||
}
|
||||
return ret;
|
||||
|
@ -1046,8 +1035,7 @@ AMF::Object3 AMF::parseOne3(const unsigned char *&data, unsigned int &len, unsig
|
|||
if (tmpi > 0){
|
||||
tmpstr.clear(); // clean tmpstr, just to be sure
|
||||
tmpstr.append((const char *)data + i, (size_t)tmpi); // add the string data
|
||||
ret.addContent(
|
||||
AMF::parseOne3(data, len, i, tmpstr)); // add content, recursively parsed, updating i
|
||||
ret.addContent(AMF::parseOne3(data, len, i, tmpstr)); // add content, recursively parsed, updating i
|
||||
}
|
||||
}while (tmpi > 0); // keep reading dynamic values until empty string
|
||||
}// dynamic types
|
||||
|
@ -1081,4 +1069,3 @@ AMF::Object3 AMF::parse3(const unsigned char *data, unsigned int len){
|
|||
AMF::Object3 AMF::parse3(std::string data){
|
||||
return AMF::parse3((const unsigned char *)data.c_str(), data.size());
|
||||
}// parse
|
||||
|
||||
|
|
|
@ -130,8 +130,6 @@ namespace AMF{
|
|||
/// Parses a std::string to a valid AMF::Object3.
|
||||
Object3 parse3(std::string data);
|
||||
/// Parses a single AMF3 type - used recursively by the AMF::parse3() functions.
|
||||
Object3 parseOne3(const unsigned char *&data, unsigned int &len, unsigned int &i,
|
||||
std::string name);
|
||||
Object3 parseOne3(const unsigned char *&data, unsigned int &len, unsigned int &i, std::string name);
|
||||
|
||||
}// namespace AMF
|
||||
|
||||
|
|
71
lib/auth.cpp
71
lib/auth.cpp
|
@ -1,16 +1,14 @@
|
|||
#include "auth.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace Secure{
|
||||
|
||||
/// Calculates a MD5 digest as per rfc1321, returning it as a hexadecimal alphanumeric string.
|
||||
std::string md5(std::string input) {
|
||||
return md5(input.data(), input.size());
|
||||
}
|
||||
std::string md5(std::string input){return md5(input.data(), input.size());}
|
||||
|
||||
/// Calculates a MD5 digest as per rfc1321, returning it as a hexadecimal alphanumeric string.
|
||||
std::string md5(const char *input, const unsigned int in_len){
|
||||
|
@ -24,9 +22,7 @@ namespace Secure {
|
|||
}
|
||||
|
||||
/// Calculates a SHA256 digest as per NSAs SHA-2, returning it as a hexadecimal alphanumeric string.
|
||||
std::string sha256(std::string input) {
|
||||
return sha256(input.data(), input.size());
|
||||
}
|
||||
std::string sha256(std::string input){return sha256(input.data(), input.size());}
|
||||
|
||||
/// Calculates a SHA256 digest as per NSAs SHA-2, returning it as a hexadecimal alphanumeric string.
|
||||
std::string sha256(const char *input, const unsigned int in_len){
|
||||
|
@ -46,10 +42,24 @@ namespace Secure {
|
|||
// Inspired by the pseudocode as available on Wikipedia on March 2nd, 2015.
|
||||
uint32_t M[16];
|
||||
for (unsigned int i = 0; i < 16; ++i){
|
||||
M[i] = data[i << 2] | (data[(i<<2)+1] << 8) | (data[(i<<2)+2] << 16) | (data[(i<<2)+3] << 24);
|
||||
M[i] = data[i << 2] | (data[(i << 2) + 1] << 8) | (data[(i << 2) + 2] << 16) |
|
||||
(data[(i << 2) + 3] << 24);
|
||||
}
|
||||
static unsigned char shift[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
||||
static uint32_t K[] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
|
||||
static unsigned char shift[] ={7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
||||
static uint32_t K[] ={0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
|
||||
0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
|
||||
0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
|
||||
0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,
|
||||
0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
|
||||
0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
|
||||
uint32_t A = hash[0];
|
||||
uint32_t B = hash[1];
|
||||
uint32_t C = hash[2];
|
||||
|
@ -151,7 +161,8 @@ namespace Secure {
|
|||
// Inspired by the pseudocode as available on Wikipedia on March 3rd, 2015.
|
||||
uint32_t w[64];
|
||||
for (unsigned int i = 0; i < 16; ++i){
|
||||
w[i] = (uint32_t)data[(i<<2)+3] | ((uint32_t)data[(i<<2)+2] << 8) | ((uint32_t)data[(i<<2)+1] << 16) | ((uint32_t)data[(i<<2)+0] << 24);
|
||||
w[i] = (uint32_t)data[(i << 2) + 3] | ((uint32_t)data[(i << 2) + 2] << 8) |
|
||||
((uint32_t)data[(i << 2) + 1] << 16) | ((uint32_t)data[(i << 2) + 0] << 24);
|
||||
}
|
||||
|
||||
for (unsigned int i = 16; i < 64; ++i){
|
||||
|
@ -160,7 +171,17 @@ namespace Secure {
|
|||
w[i] = w[i - 16] + s0 + w[i - 7] + s1;
|
||||
}
|
||||
|
||||
static uint32_t k[] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
|
||||
static uint32_t k[] ={0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
|
||||
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
||||
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
||||
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
|
||||
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
||||
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
|
||||
uint32_t a = hash[0];
|
||||
uint32_t b = hash[1];
|
||||
uint32_t c = hash[2];
|
||||
|
@ -195,7 +216,8 @@ namespace Secure {
|
|||
/// Assumes output is big enough to contain 16 bytes of data.
|
||||
void sha256bin(const char *input, const unsigned int in_len, char *output){
|
||||
// Initialize the hash, according to MD5 spec.
|
||||
uint32_t hash[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
|
||||
uint32_t hash[] ={0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
|
||||
// Add as many whole blocks of 64 bytes as possible from the input, until < 64 are left.
|
||||
unsigned int offset = 0;
|
||||
while (offset + 64 <= in_len){
|
||||
|
@ -263,13 +285,12 @@ namespace Secure {
|
|||
output[28] = (hash[7] >> 24) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Performs HMAC on msg with given key.
|
||||
/// Uses given hasher function, requires hashSize to be set accordingly.
|
||||
/// Output is returned as hexadecimal alphanumeric string.
|
||||
/// The hasher function must be the "bin" version of the hasher to have a compatible function signature.
|
||||
std::string hmac(std::string msg, std::string key, unsigned int hashSize, void hasher(const char *, const unsigned int, char*), unsigned int blockSize){
|
||||
std::string hmac(std::string msg, std::string key, unsigned int hashSize,
|
||||
void hasher(const char *, const unsigned int, char *), unsigned int blockSize){
|
||||
return hmac(msg.data(), msg.size(), key.data(), key.size(), hashSize, hasher, blockSize);
|
||||
}
|
||||
|
||||
|
@ -277,7 +298,9 @@ namespace Secure {
|
|||
/// Uses given hasher function, requires hashSize to be set accordingly.
|
||||
/// Output is returned as hexadecimal alphanumeric string.
|
||||
/// The hasher function must be the "bin" version of the hasher to have a compatible function signature.
|
||||
std::string hmac(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, unsigned int hashSize, void hasher(const char *, const unsigned int, char*), unsigned int blockSize){
|
||||
std::string hmac(const char *msg, const unsigned int msg_len, const char *key,
|
||||
const unsigned int key_len, unsigned int hashSize,
|
||||
void hasher(const char *, const unsigned int, char *), unsigned int blockSize){
|
||||
char output[hashSize];
|
||||
hmacbin(msg, msg_len, key, key_len, hashSize, hasher, blockSize, output);
|
||||
std::stringstream outStr;
|
||||
|
@ -291,7 +314,9 @@ namespace Secure {
|
|||
/// Uses given hasher function, requires hashSize to be set accordingly.
|
||||
/// Output is written in binary form to output, and assumes hashSize bytes are available to be written to.
|
||||
/// The hasher function must be the "bin" version of the hasher to have a compatible function signature.
|
||||
void hmacbin(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, unsigned int hashSize, void hasher(const char*, const unsigned int, char*), unsigned int blockSize, char * output){
|
||||
void hmacbin(const char *msg, const unsigned int msg_len, const char *key, const unsigned int key_len,
|
||||
unsigned int hashSize, void hasher(const char *, const unsigned int, char *),
|
||||
unsigned int blockSize, char *output){
|
||||
char key_data[blockSize]; // holds key as used in HMAC algorithm
|
||||
if (key_len > blockSize){
|
||||
// If the key given is too big, hash it.
|
||||
|
@ -329,9 +354,9 @@ namespace Secure {
|
|||
|
||||
/// Convenience function that sets output to the HMAC-SHA256 of msg and key in binary format.
|
||||
/// Assumes at least 32 bytes are available for writing in output.
|
||||
void hmac_sha256bin(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, char * output){
|
||||
void hmac_sha256bin(const char *msg, const unsigned int msg_len, const char *key,
|
||||
const unsigned int key_len, char *output){
|
||||
return hmacbin(msg, msg_len, key, key_len, 32, sha256bin, 64, output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}// namespace Secure
|
||||
|
|
17
lib/auth.h
17
lib/auth.h
|
@ -13,13 +13,18 @@ namespace Secure {
|
|||
void sha256bin(const char *input, const unsigned int in_len, char *output);
|
||||
|
||||
// Generic HMAC functions
|
||||
std::string hmac(std::string msg, std::string key, unsigned int hashSize, void hasher(const char *, const unsigned int, char*), unsigned int blockSize);
|
||||
std::string hmac(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, unsigned int hashSize, void hasher(const char *, const unsigned int, char*), unsigned int blockSize);
|
||||
void hmacbin(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, unsigned int hashSize, void hasher(const char*, const unsigned int, char*), unsigned int blockSize, char * output);
|
||||
std::string hmac(std::string msg, std::string key, unsigned int hashSize,
|
||||
void hasher(const char *, const unsigned int, char *), unsigned int blockSize);
|
||||
std::string hmac(const char *msg, const unsigned int msg_len, const char *key,
|
||||
const unsigned int key_len, unsigned int hashSize,
|
||||
void hasher(const char *, const unsigned int, char *), unsigned int blockSize);
|
||||
void hmacbin(const char *msg, const unsigned int msg_len, const char *key, const unsigned int key_len,
|
||||
unsigned int hashSize, void hasher(const char *, const unsigned int, char *),
|
||||
unsigned int blockSize, char *output);
|
||||
// Specific HMAC functions
|
||||
std::string hmac_sha256(std::string msg, std::string key);
|
||||
std::string hmac_sha256(const char *msg, const unsigned int msg_len, const char *key, const unsigned int key_len);
|
||||
void hmac_sha256bin(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, char * output);
|
||||
|
||||
}
|
||||
void hmac_sha256bin(const char *msg, const unsigned int msg_len, const char *key,
|
||||
const unsigned int key_len, char *output);
|
||||
|
||||
}// namespace Secure
|
||||
|
|
|
@ -35,8 +35,7 @@ unsigned long long Bit::getMSB(char *pointer, unsigned int offsetBits, unsigned
|
|||
/// This function assumes Most Significant Bits first.
|
||||
/// WARNING: UNFINISHED. DO NOT USE.
|
||||
/// \todo Finish writing this - untested atm.
|
||||
void Bit::setMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits,
|
||||
unsigned long long value){
|
||||
void Bit::setMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits, unsigned long long value){
|
||||
// Set the pointer to the last byte we need to be setting
|
||||
pointer += (offsetBits + dataBits) >> 3;
|
||||
// The offset is now guaranteed less than a whole byte.
|
||||
|
@ -73,4 +72,3 @@ bool Util::stringToBool(std::string &str){
|
|||
return (strncmp(tmp.c_str(), "1", 1) == 0 || strncmp(tmp.c_str(), "yes", 3) == 0 ||
|
||||
strncmp(tmp.c_str(), "true", 4) == 0 || strncmp(tmp.c_str(), "cont", 4) == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,7 @@ namespace Bit{
|
|||
unsigned long long getMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits);
|
||||
unsigned long long getByName(char *pointer);
|
||||
// bitfield setters
|
||||
void setMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits,
|
||||
unsigned long long value);
|
||||
void setMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits, unsigned long long value);
|
||||
void setByName(char *pointer);
|
||||
|
||||
// Host to binary/binary to host functions - similar to kernel ntoh/hton functions.
|
||||
|
@ -143,8 +142,7 @@ namespace Bit{
|
|||
|
||||
/// Retrieves a long in network order from the pointer p.
|
||||
inline unsigned long btohl_le(const char *p){
|
||||
return ((unsigned long)p[3] << 24) | ((unsigned long)p[2] << 16) | ((unsigned long)p[1] << 8) |
|
||||
p[0];
|
||||
return ((unsigned long)p[3] << 24) | ((unsigned long)p[2] << 16) | ((unsigned long)p[1] << 8) | p[0];
|
||||
}
|
||||
|
||||
/// Stores a long value of val in little endian to the pointer p.
|
||||
|
@ -171,8 +169,7 @@ namespace Bit{
|
|||
inline unsigned long long btohll_le(const char *p){
|
||||
return ((unsigned long long)p[7] << 56) | ((unsigned long long)p[6] << 48) |
|
||||
((unsigned long long)p[5] << 40) | ((unsigned long long)p[4] << 32) |
|
||||
((unsigned long)p[3] << 24) | ((unsigned long)p[2] << 16) | ((unsigned long)p[1] << 8) |
|
||||
p[0];
|
||||
((unsigned long)p[3] << 24) | ((unsigned long)p[2] << 16) | ((unsigned long)p[1] << 8) | p[0];
|
||||
}
|
||||
|
||||
/// Stores a long value of val in little endian to the pointer p.
|
||||
|
@ -188,4 +185,3 @@ namespace Bit{
|
|||
}
|
||||
|
||||
}// namespace Bit
|
||||
|
||||
|
|
|
@ -50,8 +50,7 @@ namespace Utils{
|
|||
// return 0;
|
||||
}
|
||||
if (count > size()){
|
||||
DEBUG_MSG(DLVL_ERROR, "Not enough bits left in stream. Left: %d requested: %d", (int)size(),
|
||||
(int)count);
|
||||
DEBUG_MSG(DLVL_ERROR, "Not enough bits left in stream. Left: %d requested: %d", (int)size(), (int)count);
|
||||
return 0;
|
||||
}
|
||||
long long unsigned int retval = 0;
|
||||
|
@ -131,16 +130,14 @@ namespace Utils{
|
|||
|
||||
long long int bitstream::getExpGolomb(){
|
||||
long long unsigned int temp = golombGetter();
|
||||
return (temp >> 1) *
|
||||
(1 - ((temp & 1) << 1)); // Is actually return (temp / 2) * (1 - (temp & 1) * 2);
|
||||
return (temp >> 1) * (1 - ((temp & 1) << 1)); // Is actually return (temp / 2) * (1 - (temp & 1) * 2);
|
||||
}
|
||||
|
||||
long long unsigned int bitstream::getUExpGolomb(){return golombGetter() - 1;}
|
||||
|
||||
long long int bitstream::peekExpGolomb(){
|
||||
long long unsigned int temp = golombPeeker();
|
||||
return (temp >> 1) *
|
||||
(1 - ((temp & 1) << 1)); // Is actually return (temp / 2) * (1 - (temp & 1) * 2);
|
||||
return (temp >> 1) * (1 - ((temp & 1) << 1)); // Is actually return (temp / 2) * (1 - (temp & 1) * 2);
|
||||
}
|
||||
|
||||
long long unsigned int bitstream::peekUExpGolomb(){return golombPeeker() - 1;}
|
||||
|
@ -285,4 +282,3 @@ namespace Utils{
|
|||
data.erase(0, pos);
|
||||
}
|
||||
}// namespace Utils
|
||||
|
||||
|
|
|
@ -93,4 +93,3 @@ namespace Utils{
|
|||
void fixData();
|
||||
};
|
||||
}// namespace Utils
|
||||
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
#include "certificate.h"
|
||||
#include "defines.h"
|
||||
|
||||
Certificate::Certificate()
|
||||
:rsa_ctx(NULL)
|
||||
{
|
||||
Certificate::Certificate() : rsa_ctx(NULL){
|
||||
memset((void *)&cert, 0x00, sizeof(cert));
|
||||
memset((void *)&key, 0x00, sizeof(key));
|
||||
}
|
||||
|
||||
int Certificate::init(const std::string &countryName,
|
||||
const std::string &organization,
|
||||
const std::string& commonName)
|
||||
{
|
||||
int Certificate::init(const std::string &countryName, const std::string &organization,
|
||||
const std::string &commonName){
|
||||
|
||||
mbedtls_ctr_drbg_context rand_ctx ={};
|
||||
mbedtls_entropy_context entropy_ctx ={};
|
||||
|
@ -51,7 +47,8 @@ int Certificate::init(const std::string &countryName,
|
|||
// initialize random number generator
|
||||
mbedtls_ctr_drbg_init(&rand_ctx);
|
||||
mbedtls_entropy_init(&entropy_ctx);
|
||||
r = mbedtls_ctr_drbg_seed(&rand_ctx, mbedtls_entropy_func, &entropy_ctx, (const unsigned char*)personalisation, strlen(personalisation));
|
||||
r = mbedtls_ctr_drbg_seed(&rand_ctx, mbedtls_entropy_func, &entropy_ctx,
|
||||
(const unsigned char *)personalisation, strlen(personalisation));
|
||||
if (0 != r){
|
||||
FAIL_MSG("Failed to initialize and seed the entropy context.");
|
||||
r = -10;
|
||||
|
@ -86,9 +83,7 @@ int Certificate::init(const std::string &countryName,
|
|||
time_from = (time_from < 1000000000) ? 1000000000 : time_from;
|
||||
time_to = time_from + (60 * 60 * 24 * 365); // valid for a year
|
||||
|
||||
if (time_to < time_from) {
|
||||
time_to = INT_MAX;
|
||||
}
|
||||
if (time_to < time_from){time_to = INT_MAX;}
|
||||
|
||||
r = strftime(time_from_str, sizeof(time_from_str), "%Y%m%d%H%M%S", gmtime(&time_from));
|
||||
if (0 == r){
|
||||
|
@ -111,9 +106,7 @@ int Certificate::init(const std::string &countryName,
|
|||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
sprintf(serial_hex + (i * 2), "%02x", serial_ptr[i]);
|
||||
}
|
||||
for (i = 0; i < 8; ++i){sprintf(serial_hex + (i * 2), "%02x", serial_ptr[i]);}
|
||||
|
||||
// start creating the certificate
|
||||
mbedtls_x509write_crt_init(&write_cert);
|
||||
|
@ -204,9 +197,7 @@ int Certificate::init(const std::string &countryName,
|
|||
mbedtls_x509write_crt_free(&write_cert);
|
||||
mbedtls_mpi_free(&serial_mpi);
|
||||
|
||||
if (r < 0) {
|
||||
shutdown();
|
||||
}
|
||||
if (r < 0){shutdown();}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -235,6 +226,3 @@ std::string Certificate::getFingerprintSha256() {
|
|||
std::string result = std::string((char *)fingerprint_hex + 1, (32 * 3) - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,15 +10,15 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <mbedtls/config.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/x509_crt.h>
|
||||
#include <mbedtls/x509_csr.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <string>
|
||||
|
||||
class Certificate{
|
||||
public:
|
||||
|
|
309
lib/checksum.h
309
lib/checksum.h
|
@ -3,69 +3,42 @@
|
|||
namespace checksum{
|
||||
inline unsigned int crc32c(unsigned int crc, const char *data, size_t len){
|
||||
static const unsigned int table[256] ={
|
||||
0x00000000U, 0x04C11DB7U, 0x09823B6EU, 0x0D4326D9U,
|
||||
0x130476DCU, 0x17C56B6BU, 0x1A864DB2U, 0x1E475005U,
|
||||
0x2608EDB8U, 0x22C9F00FU, 0x2F8AD6D6U, 0x2B4BCB61U,
|
||||
0x350C9B64U, 0x31CD86D3U, 0x3C8EA00AU, 0x384FBDBDU,
|
||||
0x4C11DB70U, 0x48D0C6C7U, 0x4593E01EU, 0x4152FDA9U,
|
||||
0x5F15ADACU, 0x5BD4B01BU, 0x569796C2U, 0x52568B75U,
|
||||
0x6A1936C8U, 0x6ED82B7FU, 0x639B0DA6U, 0x675A1011U,
|
||||
0x791D4014U, 0x7DDC5DA3U, 0x709F7B7AU, 0x745E66CDU,
|
||||
0x9823B6E0U, 0x9CE2AB57U, 0x91A18D8EU, 0x95609039U,
|
||||
0x8B27C03CU, 0x8FE6DD8BU, 0x82A5FB52U, 0x8664E6E5U,
|
||||
0xBE2B5B58U, 0xBAEA46EFU, 0xB7A96036U, 0xB3687D81U,
|
||||
0xAD2F2D84U, 0xA9EE3033U, 0xA4AD16EAU, 0xA06C0B5DU,
|
||||
0xD4326D90U, 0xD0F37027U, 0xDDB056FEU, 0xD9714B49U,
|
||||
0xC7361B4CU, 0xC3F706FBU, 0xCEB42022U, 0xCA753D95U,
|
||||
0xF23A8028U, 0xF6FB9D9FU, 0xFBB8BB46U, 0xFF79A6F1U,
|
||||
0xE13EF6F4U, 0xE5FFEB43U, 0xE8BCCD9AU, 0xEC7DD02DU,
|
||||
0x34867077U, 0x30476DC0U, 0x3D044B19U, 0x39C556AEU,
|
||||
0x278206ABU, 0x23431B1CU, 0x2E003DC5U, 0x2AC12072U,
|
||||
0x128E9DCFU, 0x164F8078U, 0x1B0CA6A1U, 0x1FCDBB16U,
|
||||
0x018AEB13U, 0x054BF6A4U, 0x0808D07DU, 0x0CC9CDCAU,
|
||||
0x7897AB07U, 0x7C56B6B0U, 0x71159069U, 0x75D48DDEU,
|
||||
0x6B93DDDBU, 0x6F52C06CU, 0x6211E6B5U, 0x66D0FB02U,
|
||||
0x5E9F46BFU, 0x5A5E5B08U, 0x571D7DD1U, 0x53DC6066U,
|
||||
0x4D9B3063U, 0x495A2DD4U, 0x44190B0DU, 0x40D816BAU,
|
||||
0xACA5C697U, 0xA864DB20U, 0xA527FDF9U, 0xA1E6E04EU,
|
||||
0xBFA1B04BU, 0xBB60ADFCU, 0xB6238B25U, 0xB2E29692U,
|
||||
0x8AAD2B2FU, 0x8E6C3698U, 0x832F1041U, 0x87EE0DF6U,
|
||||
0x99A95DF3U, 0x9D684044U, 0x902B669DU, 0x94EA7B2AU,
|
||||
0xE0B41DE7U, 0xE4750050U, 0xE9362689U, 0xEDF73B3EU,
|
||||
0xF3B06B3BU, 0xF771768CU, 0xFA325055U, 0xFEF34DE2U,
|
||||
0xC6BCF05FU, 0xC27DEDE8U, 0xCF3ECB31U, 0xCBFFD686U,
|
||||
0xD5B88683U, 0xD1799B34U, 0xDC3ABDEDU, 0xD8FBA05AU,
|
||||
0x690CE0EEU, 0x6DCDFD59U, 0x608EDB80U, 0x644FC637U,
|
||||
0x7A089632U, 0x7EC98B85U, 0x738AAD5CU, 0x774BB0EBU,
|
||||
0x4F040D56U, 0x4BC510E1U, 0x46863638U, 0x42472B8FU,
|
||||
0x5C007B8AU, 0x58C1663DU, 0x558240E4U, 0x51435D53U,
|
||||
0x251D3B9EU, 0x21DC2629U, 0x2C9F00F0U, 0x285E1D47U,
|
||||
0x36194D42U, 0x32D850F5U, 0x3F9B762CU, 0x3B5A6B9BU,
|
||||
0x0315D626U, 0x07D4CB91U, 0x0A97ED48U, 0x0E56F0FFU,
|
||||
0x1011A0FAU, 0x14D0BD4DU, 0x19939B94U, 0x1D528623U,
|
||||
0xF12F560EU, 0xF5EE4BB9U, 0xF8AD6D60U, 0xFC6C70D7U,
|
||||
0xE22B20D2U, 0xE6EA3D65U, 0xEBA91BBCU, 0xEF68060BU,
|
||||
0xD727BBB6U, 0xD3E6A601U, 0xDEA580D8U, 0xDA649D6FU,
|
||||
0xC423CD6AU, 0xC0E2D0DDU, 0xCDA1F604U, 0xC960EBB3U,
|
||||
0xBD3E8D7EU, 0xB9FF90C9U, 0xB4BCB610U, 0xB07DABA7U,
|
||||
0xAE3AFBA2U, 0xAAFBE615U, 0xA7B8C0CCU, 0xA379DD7BU,
|
||||
0x9B3660C6U, 0x9FF77D71U, 0x92B45BA8U, 0x9675461FU,
|
||||
0x8832161AU, 0x8CF30BADU, 0x81B02D74U, 0x857130C3U,
|
||||
0x5D8A9099U, 0x594B8D2EU, 0x5408ABF7U, 0x50C9B640U,
|
||||
0x4E8EE645U, 0x4A4FFBF2U, 0x470CDD2BU, 0x43CDC09CU,
|
||||
0x7B827D21U, 0x7F436096U, 0x7200464FU, 0x76C15BF8U,
|
||||
0x68860BFDU, 0x6C47164AU, 0x61043093U, 0x65C52D24U,
|
||||
0x119B4BE9U, 0x155A565EU, 0x18197087U, 0x1CD86D30U,
|
||||
0x029F3D35U, 0x065E2082U, 0x0B1D065BU, 0x0FDC1BECU,
|
||||
0x3793A651U, 0x3352BBE6U, 0x3E119D3FU, 0x3AD08088U,
|
||||
0x2497D08DU, 0x2056CD3AU, 0x2D15EBE3U, 0x29D4F654U,
|
||||
0xC5A92679U, 0xC1683BCEU, 0xCC2B1D17U, 0xC8EA00A0U,
|
||||
0xD6AD50A5U, 0xD26C4D12U, 0xDF2F6BCBU, 0xDBEE767CU,
|
||||
0xE3A1CBC1U, 0xE760D676U, 0xEA23F0AFU, 0xEEE2ED18U,
|
||||
0xF0A5BD1DU, 0xF464A0AAU, 0xF9278673U, 0xFDE69BC4U,
|
||||
0x89B8FD09U, 0x8D79E0BEU, 0x803AC667U, 0x84FBDBD0U,
|
||||
0x9ABC8BD5U, 0x9E7D9662U, 0x933EB0BBU, 0x97FFAD0CU,
|
||||
0xAFB010B1U, 0xAB710D06U, 0xA6322BDFU, 0xA2F33668U,
|
||||
0x00000000U, 0x04C11DB7U, 0x09823B6EU, 0x0D4326D9U, 0x130476DCU, 0x17C56B6BU, 0x1A864DB2U,
|
||||
0x1E475005U, 0x2608EDB8U, 0x22C9F00FU, 0x2F8AD6D6U, 0x2B4BCB61U, 0x350C9B64U, 0x31CD86D3U,
|
||||
0x3C8EA00AU, 0x384FBDBDU, 0x4C11DB70U, 0x48D0C6C7U, 0x4593E01EU, 0x4152FDA9U, 0x5F15ADACU,
|
||||
0x5BD4B01BU, 0x569796C2U, 0x52568B75U, 0x6A1936C8U, 0x6ED82B7FU, 0x639B0DA6U, 0x675A1011U,
|
||||
0x791D4014U, 0x7DDC5DA3U, 0x709F7B7AU, 0x745E66CDU, 0x9823B6E0U, 0x9CE2AB57U, 0x91A18D8EU,
|
||||
0x95609039U, 0x8B27C03CU, 0x8FE6DD8BU, 0x82A5FB52U, 0x8664E6E5U, 0xBE2B5B58U, 0xBAEA46EFU,
|
||||
0xB7A96036U, 0xB3687D81U, 0xAD2F2D84U, 0xA9EE3033U, 0xA4AD16EAU, 0xA06C0B5DU, 0xD4326D90U,
|
||||
0xD0F37027U, 0xDDB056FEU, 0xD9714B49U, 0xC7361B4CU, 0xC3F706FBU, 0xCEB42022U, 0xCA753D95U,
|
||||
0xF23A8028U, 0xF6FB9D9FU, 0xFBB8BB46U, 0xFF79A6F1U, 0xE13EF6F4U, 0xE5FFEB43U, 0xE8BCCD9AU,
|
||||
0xEC7DD02DU, 0x34867077U, 0x30476DC0U, 0x3D044B19U, 0x39C556AEU, 0x278206ABU, 0x23431B1CU,
|
||||
0x2E003DC5U, 0x2AC12072U, 0x128E9DCFU, 0x164F8078U, 0x1B0CA6A1U, 0x1FCDBB16U, 0x018AEB13U,
|
||||
0x054BF6A4U, 0x0808D07DU, 0x0CC9CDCAU, 0x7897AB07U, 0x7C56B6B0U, 0x71159069U, 0x75D48DDEU,
|
||||
0x6B93DDDBU, 0x6F52C06CU, 0x6211E6B5U, 0x66D0FB02U, 0x5E9F46BFU, 0x5A5E5B08U, 0x571D7DD1U,
|
||||
0x53DC6066U, 0x4D9B3063U, 0x495A2DD4U, 0x44190B0DU, 0x40D816BAU, 0xACA5C697U, 0xA864DB20U,
|
||||
0xA527FDF9U, 0xA1E6E04EU, 0xBFA1B04BU, 0xBB60ADFCU, 0xB6238B25U, 0xB2E29692U, 0x8AAD2B2FU,
|
||||
0x8E6C3698U, 0x832F1041U, 0x87EE0DF6U, 0x99A95DF3U, 0x9D684044U, 0x902B669DU, 0x94EA7B2AU,
|
||||
0xE0B41DE7U, 0xE4750050U, 0xE9362689U, 0xEDF73B3EU, 0xF3B06B3BU, 0xF771768CU, 0xFA325055U,
|
||||
0xFEF34DE2U, 0xC6BCF05FU, 0xC27DEDE8U, 0xCF3ECB31U, 0xCBFFD686U, 0xD5B88683U, 0xD1799B34U,
|
||||
0xDC3ABDEDU, 0xD8FBA05AU, 0x690CE0EEU, 0x6DCDFD59U, 0x608EDB80U, 0x644FC637U, 0x7A089632U,
|
||||
0x7EC98B85U, 0x738AAD5CU, 0x774BB0EBU, 0x4F040D56U, 0x4BC510E1U, 0x46863638U, 0x42472B8FU,
|
||||
0x5C007B8AU, 0x58C1663DU, 0x558240E4U, 0x51435D53U, 0x251D3B9EU, 0x21DC2629U, 0x2C9F00F0U,
|
||||
0x285E1D47U, 0x36194D42U, 0x32D850F5U, 0x3F9B762CU, 0x3B5A6B9BU, 0x0315D626U, 0x07D4CB91U,
|
||||
0x0A97ED48U, 0x0E56F0FFU, 0x1011A0FAU, 0x14D0BD4DU, 0x19939B94U, 0x1D528623U, 0xF12F560EU,
|
||||
0xF5EE4BB9U, 0xF8AD6D60U, 0xFC6C70D7U, 0xE22B20D2U, 0xE6EA3D65U, 0xEBA91BBCU, 0xEF68060BU,
|
||||
0xD727BBB6U, 0xD3E6A601U, 0xDEA580D8U, 0xDA649D6FU, 0xC423CD6AU, 0xC0E2D0DDU, 0xCDA1F604U,
|
||||
0xC960EBB3U, 0xBD3E8D7EU, 0xB9FF90C9U, 0xB4BCB610U, 0xB07DABA7U, 0xAE3AFBA2U, 0xAAFBE615U,
|
||||
0xA7B8C0CCU, 0xA379DD7BU, 0x9B3660C6U, 0x9FF77D71U, 0x92B45BA8U, 0x9675461FU, 0x8832161AU,
|
||||
0x8CF30BADU, 0x81B02D74U, 0x857130C3U, 0x5D8A9099U, 0x594B8D2EU, 0x5408ABF7U, 0x50C9B640U,
|
||||
0x4E8EE645U, 0x4A4FFBF2U, 0x470CDD2BU, 0x43CDC09CU, 0x7B827D21U, 0x7F436096U, 0x7200464FU,
|
||||
0x76C15BF8U, 0x68860BFDU, 0x6C47164AU, 0x61043093U, 0x65C52D24U, 0x119B4BE9U, 0x155A565EU,
|
||||
0x18197087U, 0x1CD86D30U, 0x029F3D35U, 0x065E2082U, 0x0B1D065BU, 0x0FDC1BECU, 0x3793A651U,
|
||||
0x3352BBE6U, 0x3E119D3FU, 0x3AD08088U, 0x2497D08DU, 0x2056CD3AU, 0x2D15EBE3U, 0x29D4F654U,
|
||||
0xC5A92679U, 0xC1683BCEU, 0xCC2B1D17U, 0xC8EA00A0U, 0xD6AD50A5U, 0xD26C4D12U, 0xDF2F6BCBU,
|
||||
0xDBEE767CU, 0xE3A1CBC1U, 0xE760D676U, 0xEA23F0AFU, 0xEEE2ED18U, 0xF0A5BD1DU, 0xF464A0AAU,
|
||||
0xF9278673U, 0xFDE69BC4U, 0x89B8FD09U, 0x8D79E0BEU, 0x803AC667U, 0x84FBDBD0U, 0x9ABC8BD5U,
|
||||
0x9E7D9662U, 0x933EB0BBU, 0x97FFAD0CU, 0xAFB010B1U, 0xAB710D06U, 0xA6322BDFU, 0xA2F33668U,
|
||||
0xBCB4666DU, 0xB8757BDAU, 0xB5365D03U, 0xB1F740B4U,
|
||||
};
|
||||
|
||||
|
@ -79,71 +52,43 @@ namespace checksum {
|
|||
|
||||
inline unsigned int crc32LE(unsigned int crc, const char *data, size_t len){
|
||||
static const unsigned int table[256] ={
|
||||
0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU,
|
||||
0x076dc419U, 0x706af48fU, 0xe963a535U, 0x9e6495a3U,
|
||||
0x0edb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U,
|
||||
0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, 0x90bf1d91U,
|
||||
0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
|
||||
0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U,
|
||||
0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU,
|
||||
0x14015c4fU, 0x63066cd9U, 0xfa0f3d63U, 0x8d080df5U,
|
||||
0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, 0xa2677172U,
|
||||
0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
|
||||
0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U,
|
||||
0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U,
|
||||
0x26d930acU, 0x51de003aU, 0xc8d75180U, 0xbfd06116U,
|
||||
0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, 0xb8bda50fU,
|
||||
0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
|
||||
0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU,
|
||||
0x76dc4190U, 0x01db7106U, 0x98d220bcU, 0xefd5102aU,
|
||||
0x71b18589U, 0x06b6b51fU, 0x9fbfe4a5U, 0xe8b8d433U,
|
||||
0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, 0xe10e9818U,
|
||||
0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
|
||||
0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU,
|
||||
0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U,
|
||||
0x65b0d9c6U, 0x12b7e950U, 0x8bbeb8eaU, 0xfcb9887cU,
|
||||
0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U,
|
||||
0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
|
||||
0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU,
|
||||
0x4369e96aU, 0x346ed9fcU, 0xad678846U, 0xda60b8d0U,
|
||||
0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U,
|
||||
0x5005713cU, 0x270241aaU, 0xbe0b1010U, 0xc90c2086U,
|
||||
0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
|
||||
0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U,
|
||||
0x59b33d17U, 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU,
|
||||
0xedb88320U, 0x9abfb3b6U, 0x03b6e20cU, 0x74b1d29aU,
|
||||
0xead54739U, 0x9dd277afU, 0x04db2615U, 0x73dc1683U,
|
||||
0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
|
||||
0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U,
|
||||
0xf00f9344U, 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU,
|
||||
0xf762575dU, 0x806567cbU, 0x196c3671U, 0x6e6b06e7U,
|
||||
0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, 0x67dd4accU,
|
||||
0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
|
||||
0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U,
|
||||
0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU,
|
||||
0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U,
|
||||
0xdf60efc3U, 0xa867df55U, 0x316e8eefU, 0x4669be79U,
|
||||
0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
|
||||
0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU,
|
||||
0xc5ba3bbeU, 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U,
|
||||
0xc2d7ffa7U, 0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU,
|
||||
0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x026d930aU,
|
||||
0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
|
||||
0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U,
|
||||
0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U,
|
||||
0x86d3d2d4U, 0xf1d4e242U, 0x68ddb3f8U, 0x1fda836eU,
|
||||
0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U,
|
||||
0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
|
||||
0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U,
|
||||
0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U,
|
||||
0xa7672661U, 0xd06016f7U, 0x4969474dU, 0x3e6e77dbU,
|
||||
0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, 0x37d83bf0U,
|
||||
0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
|
||||
0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U,
|
||||
0xbad03605U, 0xcdd70693U, 0x54de5729U, 0x23d967bfU,
|
||||
0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U,
|
||||
0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU
|
||||
};
|
||||
0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, 0x706af48fU, 0xe963a535U,
|
||||
0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU,
|
||||
0xe7b82d07U, 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, 0x1adad47dU,
|
||||
0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU,
|
||||
0x14015c4fU, 0x63066cd9U, 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
|
||||
0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, 0x35b5a8faU, 0x42b2986cU,
|
||||
0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU,
|
||||
0x51de003aU, 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, 0xb8bda50fU,
|
||||
0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU,
|
||||
0xb6662d3dU, 0x76dc4190U, 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
|
||||
0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, 0xe10e9818U, 0x7f6a0dbbU,
|
||||
0x086d3d2dU, 0x91646c97U, 0xe6635c01U, 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU,
|
||||
0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, 0x8bbeb8eaU,
|
||||
0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU,
|
||||
0xa3bc0074U, 0xd4bb30e2U, 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
|
||||
0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U,
|
||||
0x5005713cU, 0x270241aaU, 0xbe0b1010U, 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U,
|
||||
0xce61e49fU, 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, 0x2eb40d81U,
|
||||
0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, 0x03b6e20cU, 0x74b1d29aU, 0xead54739U,
|
||||
0x9dd277afU, 0x04db2615U, 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
|
||||
0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, 0x8708a3d2U, 0x1e01f268U,
|
||||
0x6906c2feU, 0xf762575dU, 0x806567cbU, 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U,
|
||||
0x10da7a5aU, 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, 0xd6d6a3e8U,
|
||||
0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU,
|
||||
0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
|
||||
0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, 0xcc0c7795U, 0xbb0b4703U,
|
||||
0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U,
|
||||
0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x026d930aU,
|
||||
0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU,
|
||||
0x0cb61b38U, 0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
|
||||
0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U, 0x88085ae6U,
|
||||
0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U,
|
||||
0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, 0x4969474dU,
|
||||
0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U,
|
||||
0x47b2cf7fU, 0x30b5ffe9U, 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
|
||||
0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U,
|
||||
0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU};
|
||||
|
||||
while (len > 0){
|
||||
crc = table[*data ^ ((crc >> 24) & 0xff)] ^ (crc << 8);
|
||||
|
@ -155,77 +100,47 @@ namespace checksum {
|
|||
|
||||
inline unsigned int crc32(unsigned int crc, const char *data, size_t len){
|
||||
static const unsigned int table[256] ={
|
||||
0x00000000U, 0xB71DC104U, 0x6E3B8209U, 0xD926430DU,
|
||||
0xDC760413U, 0x6B6BC517U, 0xB24D861AU, 0x0550471EU,
|
||||
0xB8ED0826U, 0x0FF0C922U, 0xD6D68A2FU, 0x61CB4B2BU,
|
||||
0x649B0C35U, 0xD386CD31U, 0x0AA08E3CU, 0xBDBD4F38U,
|
||||
0x70DB114CU, 0xC7C6D048U, 0x1EE09345U, 0xA9FD5241U,
|
||||
0xACAD155FU, 0x1BB0D45BU, 0xC2969756U, 0x758B5652U,
|
||||
0xC836196AU, 0x7F2BD86EU, 0xA60D9B63U, 0x11105A67U,
|
||||
0x14401D79U, 0xA35DDC7DU, 0x7A7B9F70U, 0xCD665E74U,
|
||||
0xE0B62398U, 0x57ABE29CU, 0x8E8DA191U, 0x39906095U,
|
||||
0x3CC0278BU, 0x8BDDE68FU, 0x52FBA582U, 0xE5E66486U,
|
||||
0x585B2BBEU, 0xEF46EABAU, 0x3660A9B7U, 0x817D68B3U,
|
||||
0x842D2FADU, 0x3330EEA9U, 0xEA16ADA4U, 0x5D0B6CA0U,
|
||||
0x906D32D4U, 0x2770F3D0U, 0xFE56B0DDU, 0x494B71D9U,
|
||||
0x4C1B36C7U, 0xFB06F7C3U, 0x2220B4CEU, 0x953D75CAU,
|
||||
0x28803AF2U, 0x9F9DFBF6U, 0x46BBB8FBU, 0xF1A679FFU,
|
||||
0xF4F63EE1U, 0x43EBFFE5U, 0x9ACDBCE8U, 0x2DD07DECU,
|
||||
0x77708634U, 0xC06D4730U, 0x194B043DU, 0xAE56C539U,
|
||||
0xAB068227U, 0x1C1B4323U, 0xC53D002EU, 0x7220C12AU,
|
||||
0xCF9D8E12U, 0x78804F16U, 0xA1A60C1BU, 0x16BBCD1FU,
|
||||
0x13EB8A01U, 0xA4F64B05U, 0x7DD00808U, 0xCACDC90CU,
|
||||
0x07AB9778U, 0xB0B6567CU, 0x69901571U, 0xDE8DD475U,
|
||||
0xDBDD936BU, 0x6CC0526FU, 0xB5E61162U, 0x02FBD066U,
|
||||
0xBF469F5EU, 0x085B5E5AU, 0xD17D1D57U, 0x6660DC53U,
|
||||
0x63309B4DU, 0xD42D5A49U, 0x0D0B1944U, 0xBA16D840U,
|
||||
0x97C6A5ACU, 0x20DB64A8U, 0xF9FD27A5U, 0x4EE0E6A1U,
|
||||
0x4BB0A1BFU, 0xFCAD60BBU, 0x258B23B6U, 0x9296E2B2U,
|
||||
0x2F2BAD8AU, 0x98366C8EU, 0x41102F83U, 0xF60DEE87U,
|
||||
0xF35DA999U, 0x4440689DU, 0x9D662B90U, 0x2A7BEA94U,
|
||||
0xE71DB4E0U, 0x500075E4U, 0x892636E9U, 0x3E3BF7EDU,
|
||||
0x3B6BB0F3U, 0x8C7671F7U, 0x555032FAU, 0xE24DF3FEU,
|
||||
0x5FF0BCC6U, 0xE8ED7DC2U, 0x31CB3ECFU, 0x86D6FFCBU,
|
||||
0x8386B8D5U, 0x349B79D1U, 0xEDBD3ADCU, 0x5AA0FBD8U,
|
||||
0xEEE00C69U, 0x59FDCD6DU, 0x80DB8E60U, 0x37C64F64U,
|
||||
0x3296087AU, 0x858BC97EU, 0x5CAD8A73U, 0xEBB04B77U,
|
||||
0x560D044FU, 0xE110C54BU, 0x38368646U, 0x8F2B4742U,
|
||||
0x8A7B005CU, 0x3D66C158U, 0xE4408255U, 0x535D4351U,
|
||||
0x9E3B1D25U, 0x2926DC21U, 0xF0009F2CU, 0x471D5E28U,
|
||||
0x424D1936U, 0xF550D832U, 0x2C769B3FU, 0x9B6B5A3BU,
|
||||
0x26D61503U, 0x91CBD407U, 0x48ED970AU, 0xFFF0560EU,
|
||||
0xFAA01110U, 0x4DBDD014U, 0x949B9319U, 0x2386521DU,
|
||||
0x0E562FF1U, 0xB94BEEF5U, 0x606DADF8U, 0xD7706CFCU,
|
||||
0xD2202BE2U, 0x653DEAE6U, 0xBC1BA9EBU, 0x0B0668EFU,
|
||||
0xB6BB27D7U, 0x01A6E6D3U, 0xD880A5DEU, 0x6F9D64DAU,
|
||||
0x6ACD23C4U, 0xDDD0E2C0U, 0x04F6A1CDU, 0xB3EB60C9U,
|
||||
0x7E8D3EBDU, 0xC990FFB9U, 0x10B6BCB4U, 0xA7AB7DB0U,
|
||||
0xA2FB3AAEU, 0x15E6FBAAU, 0xCCC0B8A7U, 0x7BDD79A3U,
|
||||
0xC660369BU, 0x717DF79FU, 0xA85BB492U, 0x1F467596U,
|
||||
0x1A163288U, 0xAD0BF38CU, 0x742DB081U, 0xC3307185U,
|
||||
0x99908A5DU, 0x2E8D4B59U, 0xF7AB0854U, 0x40B6C950U,
|
||||
0x45E68E4EU, 0xF2FB4F4AU, 0x2BDD0C47U, 0x9CC0CD43U,
|
||||
0x217D827BU, 0x9660437FU, 0x4F460072U, 0xF85BC176U,
|
||||
0xFD0B8668U, 0x4A16476CU, 0x93300461U, 0x242DC565U,
|
||||
0xE94B9B11U, 0x5E565A15U, 0x87701918U, 0x306DD81CU,
|
||||
0x353D9F02U, 0x82205E06U, 0x5B061D0BU, 0xEC1BDC0FU,
|
||||
0x51A69337U, 0xE6BB5233U, 0x3F9D113EU, 0x8880D03AU,
|
||||
0x8DD09724U, 0x3ACD5620U, 0xE3EB152DU, 0x54F6D429U,
|
||||
0x7926A9C5U, 0xCE3B68C1U, 0x171D2BCCU, 0xA000EAC8U,
|
||||
0xA550ADD6U, 0x124D6CD2U, 0xCB6B2FDFU, 0x7C76EEDBU,
|
||||
0xC1CBA1E3U, 0x76D660E7U, 0xAFF023EAU, 0x18EDE2EEU,
|
||||
0x1DBDA5F0U, 0xAAA064F4U, 0x738627F9U, 0xC49BE6FDU,
|
||||
0x09FDB889U, 0xBEE0798DU, 0x67C63A80U, 0xD0DBFB84U,
|
||||
0xD58BBC9AU, 0x62967D9EU, 0xBBB03E93U, 0x0CADFF97U,
|
||||
0xB110B0AFU, 0x060D71ABU, 0xDF2B32A6U, 0x6836F3A2U,
|
||||
0x6D66B4BCU, 0xDA7B75B8U, 0x035D36B5U, 0xB440F7B1U
|
||||
};
|
||||
0x00000000U, 0xB71DC104U, 0x6E3B8209U, 0xD926430DU, 0xDC760413U, 0x6B6BC517U, 0xB24D861AU,
|
||||
0x0550471EU, 0xB8ED0826U, 0x0FF0C922U, 0xD6D68A2FU, 0x61CB4B2BU, 0x649B0C35U, 0xD386CD31U,
|
||||
0x0AA08E3CU, 0xBDBD4F38U, 0x70DB114CU, 0xC7C6D048U, 0x1EE09345U, 0xA9FD5241U, 0xACAD155FU,
|
||||
0x1BB0D45BU, 0xC2969756U, 0x758B5652U, 0xC836196AU, 0x7F2BD86EU, 0xA60D9B63U, 0x11105A67U,
|
||||
0x14401D79U, 0xA35DDC7DU, 0x7A7B9F70U, 0xCD665E74U, 0xE0B62398U, 0x57ABE29CU, 0x8E8DA191U,
|
||||
0x39906095U, 0x3CC0278BU, 0x8BDDE68FU, 0x52FBA582U, 0xE5E66486U, 0x585B2BBEU, 0xEF46EABAU,
|
||||
0x3660A9B7U, 0x817D68B3U, 0x842D2FADU, 0x3330EEA9U, 0xEA16ADA4U, 0x5D0B6CA0U, 0x906D32D4U,
|
||||
0x2770F3D0U, 0xFE56B0DDU, 0x494B71D9U, 0x4C1B36C7U, 0xFB06F7C3U, 0x2220B4CEU, 0x953D75CAU,
|
||||
0x28803AF2U, 0x9F9DFBF6U, 0x46BBB8FBU, 0xF1A679FFU, 0xF4F63EE1U, 0x43EBFFE5U, 0x9ACDBCE8U,
|
||||
0x2DD07DECU, 0x77708634U, 0xC06D4730U, 0x194B043DU, 0xAE56C539U, 0xAB068227U, 0x1C1B4323U,
|
||||
0xC53D002EU, 0x7220C12AU, 0xCF9D8E12U, 0x78804F16U, 0xA1A60C1BU, 0x16BBCD1FU, 0x13EB8A01U,
|
||||
0xA4F64B05U, 0x7DD00808U, 0xCACDC90CU, 0x07AB9778U, 0xB0B6567CU, 0x69901571U, 0xDE8DD475U,
|
||||
0xDBDD936BU, 0x6CC0526FU, 0xB5E61162U, 0x02FBD066U, 0xBF469F5EU, 0x085B5E5AU, 0xD17D1D57U,
|
||||
0x6660DC53U, 0x63309B4DU, 0xD42D5A49U, 0x0D0B1944U, 0xBA16D840U, 0x97C6A5ACU, 0x20DB64A8U,
|
||||
0xF9FD27A5U, 0x4EE0E6A1U, 0x4BB0A1BFU, 0xFCAD60BBU, 0x258B23B6U, 0x9296E2B2U, 0x2F2BAD8AU,
|
||||
0x98366C8EU, 0x41102F83U, 0xF60DEE87U, 0xF35DA999U, 0x4440689DU, 0x9D662B90U, 0x2A7BEA94U,
|
||||
0xE71DB4E0U, 0x500075E4U, 0x892636E9U, 0x3E3BF7EDU, 0x3B6BB0F3U, 0x8C7671F7U, 0x555032FAU,
|
||||
0xE24DF3FEU, 0x5FF0BCC6U, 0xE8ED7DC2U, 0x31CB3ECFU, 0x86D6FFCBU, 0x8386B8D5U, 0x349B79D1U,
|
||||
0xEDBD3ADCU, 0x5AA0FBD8U, 0xEEE00C69U, 0x59FDCD6DU, 0x80DB8E60U, 0x37C64F64U, 0x3296087AU,
|
||||
0x858BC97EU, 0x5CAD8A73U, 0xEBB04B77U, 0x560D044FU, 0xE110C54BU, 0x38368646U, 0x8F2B4742U,
|
||||
0x8A7B005CU, 0x3D66C158U, 0xE4408255U, 0x535D4351U, 0x9E3B1D25U, 0x2926DC21U, 0xF0009F2CU,
|
||||
0x471D5E28U, 0x424D1936U, 0xF550D832U, 0x2C769B3FU, 0x9B6B5A3BU, 0x26D61503U, 0x91CBD407U,
|
||||
0x48ED970AU, 0xFFF0560EU, 0xFAA01110U, 0x4DBDD014U, 0x949B9319U, 0x2386521DU, 0x0E562FF1U,
|
||||
0xB94BEEF5U, 0x606DADF8U, 0xD7706CFCU, 0xD2202BE2U, 0x653DEAE6U, 0xBC1BA9EBU, 0x0B0668EFU,
|
||||
0xB6BB27D7U, 0x01A6E6D3U, 0xD880A5DEU, 0x6F9D64DAU, 0x6ACD23C4U, 0xDDD0E2C0U, 0x04F6A1CDU,
|
||||
0xB3EB60C9U, 0x7E8D3EBDU, 0xC990FFB9U, 0x10B6BCB4U, 0xA7AB7DB0U, 0xA2FB3AAEU, 0x15E6FBAAU,
|
||||
0xCCC0B8A7U, 0x7BDD79A3U, 0xC660369BU, 0x717DF79FU, 0xA85BB492U, 0x1F467596U, 0x1A163288U,
|
||||
0xAD0BF38CU, 0x742DB081U, 0xC3307185U, 0x99908A5DU, 0x2E8D4B59U, 0xF7AB0854U, 0x40B6C950U,
|
||||
0x45E68E4EU, 0xF2FB4F4AU, 0x2BDD0C47U, 0x9CC0CD43U, 0x217D827BU, 0x9660437FU, 0x4F460072U,
|
||||
0xF85BC176U, 0xFD0B8668U, 0x4A16476CU, 0x93300461U, 0x242DC565U, 0xE94B9B11U, 0x5E565A15U,
|
||||
0x87701918U, 0x306DD81CU, 0x353D9F02U, 0x82205E06U, 0x5B061D0BU, 0xEC1BDC0FU, 0x51A69337U,
|
||||
0xE6BB5233U, 0x3F9D113EU, 0x8880D03AU, 0x8DD09724U, 0x3ACD5620U, 0xE3EB152DU, 0x54F6D429U,
|
||||
0x7926A9C5U, 0xCE3B68C1U, 0x171D2BCCU, 0xA000EAC8U, 0xA550ADD6U, 0x124D6CD2U, 0xCB6B2FDFU,
|
||||
0x7C76EEDBU, 0xC1CBA1E3U, 0x76D660E7U, 0xAFF023EAU, 0x18EDE2EEU, 0x1DBDA5F0U, 0xAAA064F4U,
|
||||
0x738627F9U, 0xC49BE6FDU, 0x09FDB889U, 0xBEE0798DU, 0x67C63A80U, 0xD0DBFB84U, 0xD58BBC9AU,
|
||||
0x62967D9EU, 0xBBB03E93U, 0x0CADFF97U, 0xB110B0AFU, 0x060D71ABU, 0xDF2B32A6U, 0x6836F3A2U,
|
||||
0x6D66B4BCU, 0xDA7B75B8U, 0x035D36B5U, 0xB440F7B1U};
|
||||
|
||||
const char *tmpData = data;
|
||||
const char *end = tmpData + len;
|
||||
while(tmpData < end){
|
||||
crc = table[((unsigned char) crc) ^ *tmpData++] ^ (crc >> 8);
|
||||
}
|
||||
while (tmpData < end){crc = table[((unsigned char)crc) ^ *tmpData++] ^ (crc >> 8);}
|
||||
return crc;
|
||||
}
|
||||
}
|
||||
}// namespace checksum
|
||||
|
|
|
@ -132,8 +132,7 @@ void Util::Config::printHelp(std::ostream &output){
|
|||
}
|
||||
while (f.size() < longest){f.append(" ");}
|
||||
if (it->isMember("arg")){
|
||||
output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString()
|
||||
<< std::endl;
|
||||
output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() << std::endl;
|
||||
}else{
|
||||
output << f << (*it)["help"].asString() << std::endl;
|
||||
}
|
||||
|
@ -141,8 +140,7 @@ void Util::Config::printHelp(std::ostream &output){
|
|||
if (it->isMember("arg_num")){
|
||||
f = it.key();
|
||||
while (f.size() < longest){f.append(" ");}
|
||||
output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString()
|
||||
<< std::endl;
|
||||
output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,8 +186,8 @@ bool Util::Config::parseArgs(int &argc, char **&argv){
|
|||
<< std::endl;
|
||||
#endif
|
||||
#ifdef WITH_THREADNAMES
|
||||
std::cout
|
||||
<< "- Flag: With threadnames. Debuggers will show sensible human-readable thread names."
|
||||
std::cout << "- Flag: With threadnames. Debuggers will show sensible human-readable thread "
|
||||
"names."
|
||||
<< std::endl;
|
||||
#endif
|
||||
/*LTS-START*/
|
||||
|
@ -210,9 +208,8 @@ bool Util::Config::parseArgs(int &argc, char **&argv){
|
|||
#endif
|
||||
#ifdef STATS_DELAY
|
||||
if (STATS_DELAY != 15){
|
||||
std::cout << "- Setting: Stats delay " << STATS_DELAY
|
||||
<< ". Statistics of viewer counts are delayed by " << STATS_DELAY
|
||||
<< " seconds as opposed to the default of 15 seconds. ";
|
||||
std::cout << "- Setting: Stats delay " << STATS_DELAY << ". Statistics of viewer counts are delayed by "
|
||||
<< STATS_DELAY << " seconds as opposed to the default of 15 seconds. ";
|
||||
if (STATS_DELAY > 15){
|
||||
std::cout << "This makes them more accurate." << std::endl;
|
||||
}else{
|
||||
|
@ -263,8 +260,7 @@ bool Util::Config::hasOption(const std::string &optname){
|
|||
/// If the option does not exist, this exits the application with a return code of 37.
|
||||
JSON::Value &Util::Config::getOption(std::string optname, bool asArray){
|
||||
if (!vals.isMember(optname)){
|
||||
std::cout << "Fatal error: a non-existent option '" << optname << "' was accessed."
|
||||
<< std::endl;
|
||||
std::cout << "Fatal error: a non-existent option '" << optname << "' was accessed." << std::endl;
|
||||
exit(37);
|
||||
}
|
||||
if (!vals[optname].isMember("value") || !vals[optname]["value"].isArray()){
|
||||
|
@ -313,8 +309,7 @@ static void callThreadCallback(void *cDataArg){
|
|||
INSANE_MSG("Thread for %p ended", cDataArg);
|
||||
}
|
||||
|
||||
int Util::Config::threadServer(Socket::Server &server_socket,
|
||||
int (*callback)(Socket::Connection &)){
|
||||
int Util::Config::threadServer(Socket::Server &server_socket, int (*callback)(Socket::Connection &)){
|
||||
Util::Procs::socketList.insert(server_socket.getSocket());
|
||||
while (is_active && server_socket.connected()){
|
||||
Socket::Connection S = server_socket.accept();
|
||||
|
@ -354,9 +349,7 @@ int Util::Config::forkServer(Socket::Server &server_socket, int (*callback)(Sock
|
|||
}
|
||||
}
|
||||
Util::Procs::socketList.erase(server_socket.getSocket());
|
||||
if (!is_restarting){
|
||||
server_socket.close();
|
||||
}
|
||||
if (!is_restarting){server_socket.close();}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -463,8 +456,7 @@ void Util::Config::signal_handler(int signum, siginfo_t *sigInfo, void *ignore){
|
|||
case SI_TIMER:
|
||||
case SI_ASYNCIO:
|
||||
case SI_MESGQ:
|
||||
INFO_MSG("Received signal %s (%d) from process %d", strsignal(signum), signum,
|
||||
sigInfo->si_pid);
|
||||
INFO_MSG("Received signal %s (%d) from process %d", strsignal(signum), signum, sigInfo->si_pid);
|
||||
break;
|
||||
default: INFO_MSG("Received signal %s (%d)", strsignal(signum), signum); break;
|
||||
}
|
||||
|
@ -653,4 +645,3 @@ void Util::setUser(std::string username){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,4 +64,3 @@ namespace Util{
|
|||
void setUser(std::string user);
|
||||
|
||||
}// namespace Util
|
||||
|
||||
|
|
|
@ -15,18 +15,20 @@
|
|||
#define DLVL_INSANE 9 // Everything is reported in insane detail.
|
||||
#define DLVL_DONTEVEN 10 // All messages enabled, even pointless ones.
|
||||
#define PRETTY_PRINT_TIME "%ud%uh%um%us"
|
||||
#define PRETTY_ARG_TIME(t) (int)(t)/86400, ((int)(t)%86400)/3600, ((int)(t)%3600)/60, (int)(t)%60
|
||||
#define PRETTY_ARG_TIME(t) \
|
||||
(int)(t) / 86400, ((int)(t) % 86400) / 3600, ((int)(t) % 3600) / 60, (int)(t) % 60
|
||||
#define PRETTY_PRINT_MSTIME "%ud%.2uh%.2um%.2us.%.3u"
|
||||
#define PRETTY_ARG_MSTIME(t) PRETTY_ARG_TIME(t / 1000), (int)(t % 1000)
|
||||
#if DEBUG > -1
|
||||
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
static const char * DBG_LVL_LIST[] = {"NONE", "FAIL", "ERROR", "WARN", "INFO", "MEDIUM", "HIGH", "VERYHIGH", "EXTREME", "INSANE", "DONTEVEN"};
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
static const char *DBG_LVL_LIST[] ={"NONE", "FAIL", "ERROR", "WARN", "INFO", "MEDIUM",
|
||||
"HIGH", "VERYHIGH", "EXTREME", "INSANE", "DONTEVEN"};
|
||||
|
||||
#if !defined(PRIu64)
|
||||
#define PRIu64 "llu"
|
||||
|
@ -40,15 +42,31 @@ static const char * DBG_LVL_LIST[] = {"NONE", "FAIL", "ERROR", "WARN", "INFO", "
|
|||
#include <errno.h>
|
||||
|
||||
#if DEBUG >= DLVL_DEVEL
|
||||
#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|%s|%d|%s:%d|%s|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, getpid(), __FILE__, __LINE__, Util::Config::streamName.c_str(), ##__VA_ARGS__);}
|
||||
#define DEBUG_MSG(lvl, msg, ...) \
|
||||
if (Util::Config::printDebugLevel >= lvl){\
|
||||
fprintf(stderr, "%s|%s|%d|%s:%d|%s|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, \
|
||||
getpid(), __FILE__, __LINE__, Util::Config::streamName.c_str(), ##__VA_ARGS__); \
|
||||
}
|
||||
#else
|
||||
#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|%s|%d||%s|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, getpid(), Util::Config::streamName.c_str(), ##__VA_ARGS__);}
|
||||
#define DEBUG_MSG(lvl, msg, ...) \
|
||||
if (Util::Config::printDebugLevel >= lvl){\
|
||||
fprintf(stderr, "%s|%s|%d||%s|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, \
|
||||
getpid(), Util::Config::streamName.c_str(), ##__VA_ARGS__); \
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if DEBUG >= DLVL_DEVEL
|
||||
#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|MistProcess|%d|%s:%d|%s|" msg "\n", DBG_LVL_LIST[lvl], getpid(), __FILE__, __LINE__, Util::Config::streamName.c_str(), ##__VA_ARGS__);}
|
||||
#define DEBUG_MSG(lvl, msg, ...) \
|
||||
if (Util::Config::printDebugLevel >= lvl){\
|
||||
fprintf(stderr, "%s|MistProcess|%d|%s:%d|%s|" msg "\n", DBG_LVL_LIST[lvl], getpid(), __FILE__, \
|
||||
__LINE__, Util::Config::streamName.c_str(), ##__VA_ARGS__); \
|
||||
}
|
||||
#else
|
||||
#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|MistProcess|%d||%s|" msg "\n", DBG_LVL_LIST[lvl], getpid(), Util::Config::streamName.c_str(), ##__VA_ARGS__);}
|
||||
#define DEBUG_MSG(lvl, msg, ...) \
|
||||
if (Util::Config::printDebugLevel >= lvl){\
|
||||
fprintf(stderr, "%s|MistProcess|%d||%s|" msg "\n", DBG_LVL_LIST[lvl], getpid(), \
|
||||
Util::Config::streamName.c_str(), ##__VA_ARGS__); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -64,9 +82,7 @@ static inline void show_stackframe() {
|
|||
messages = backtrace_symbols(trace, trace_size);
|
||||
for (i = 1; i < trace_size; ++i){
|
||||
size_t p = 0;
|
||||
while(messages[i][p] != '(' && messages[i][p] != ' ' && messages[i][p] != 0){
|
||||
++p;
|
||||
}
|
||||
while (messages[i][p] != '(' && messages[i][p] != ' ' && messages[i][p] != 0){++p;}
|
||||
DEBUG_MSG(0, "Backtrace[%d]: %s", i, messages[i] + p);
|
||||
}
|
||||
}
|
||||
|
@ -94,12 +110,12 @@ static inline void show_stackframe(){}
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SHM_DATASIZE
|
||||
#define SHM_DATASIZE 20
|
||||
#endif
|
||||
|
||||
#define AUDIO_KEY_INTERVAL 2000 ///< This define controls the keyframe interval for non-video tracks, such as audio and metadata tracks.
|
||||
#define AUDIO_KEY_INTERVAL \
|
||||
2000 ///< This define controls the keyframe interval for non-video tracks, such as audio and metadata tracks.
|
||||
|
||||
#ifndef STATS_DELAY
|
||||
#define STATS_DELAY 15
|
||||
|
@ -166,7 +182,6 @@ static inline void show_stackframe(){}
|
|||
|
||||
#define SIMUL_TRACKS 20
|
||||
|
||||
|
||||
#ifndef UDP_API_HOST
|
||||
#define UDP_API_HOST "localhost"
|
||||
#endif
|
||||
|
@ -180,4 +195,3 @@ static inline void show_stackframe(){}
|
|||
// The amount of milliseconds a simulated live stream is allowed to be "behind".
|
||||
// Setting this value to lower than 2 seconds **WILL** cause stuttering in playback due to buffer negotiation.
|
||||
#define SIMULATED_LIVE_BUFFER 7000
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "downloader.h"
|
||||
#include "defines.h"
|
||||
#include "downloader.h"
|
||||
#include "encode.h"
|
||||
#include "timing.h"
|
||||
|
||||
|
@ -136,7 +136,8 @@ namespace HTTP{
|
|||
}
|
||||
|
||||
/// Sends a request for the given URL, does no waiting.
|
||||
void Downloader::doRequest(const HTTP::URL &link, const std::string &method, const void * body, const size_t bodyLen){
|
||||
void Downloader::doRequest(const HTTP::URL &link, const std::string &method, const void *body,
|
||||
const size_t bodyLen){
|
||||
prepareRequest(link, method);
|
||||
H.sendRequest(getSocket(), body, bodyLen, false);
|
||||
H.Clean();
|
||||
|
@ -147,7 +148,6 @@ namespace HTTP{
|
|||
doRequest(link, method, body.data(), body.size());
|
||||
}
|
||||
|
||||
|
||||
/// Do a HEAD request to download the HTTP headers only, returns true on success
|
||||
bool Downloader::head(const HTTP::URL &link, uint8_t maxRecursiveDepth){
|
||||
if (!canRequest(link)){return false;}
|
||||
|
@ -190,9 +190,7 @@ namespace HTTP{
|
|||
}
|
||||
}
|
||||
|
||||
if(H.protocol == "HTTP/1.0"){
|
||||
getSocket().close();
|
||||
}
|
||||
if (H.protocol == "HTTP/1.0"){getSocket().close();}
|
||||
|
||||
H.headerOnly = false;
|
||||
return true; // Success!
|
||||
|
@ -218,9 +216,11 @@ namespace HTTP{
|
|||
getSocket().close();
|
||||
}else{
|
||||
if (retryCount - loop + 1 > 2){
|
||||
INFO_MSG("Lost connection while retrieving %s (%zu/%" PRIu32 ")", link.getUrl().c_str(), retryCount - loop + 1, retryCount);
|
||||
INFO_MSG("Lost connection while retrieving %s (%zu/%" PRIu32 ")", link.getUrl().c_str(),
|
||||
retryCount - loop + 1, retryCount);
|
||||
}else{
|
||||
MEDIUM_MSG("Lost connection while retrieving %s (%zu/%" PRIu32 ")", link.getUrl().c_str(), retryCount - loop + 1, retryCount);
|
||||
MEDIUM_MSG("Lost connection while retrieving %s (%zu/%" PRIu32 ")", link.getUrl().c_str(),
|
||||
retryCount - loop + 1, retryCount);
|
||||
}
|
||||
H.Clean();
|
||||
}
|
||||
|
@ -230,7 +230,8 @@ namespace HTTP{
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Downloader::getRangeNonBlocking(const HTTP::URL &link, size_t byteStart, size_t byteEnd, Util::DataCallback &cb){
|
||||
bool Downloader::getRangeNonBlocking(const HTTP::URL &link, size_t byteStart, size_t byteEnd,
|
||||
Util::DataCallback &cb){
|
||||
char tmp[32];
|
||||
if (byteEnd <= 0){// get range from byteStart til eof
|
||||
sprintf(tmp, "bytes=%zu-", byteStart);
|
||||
|
@ -277,9 +278,7 @@ namespace HTTP{
|
|||
return true;
|
||||
}
|
||||
|
||||
const HTTP::URL & Downloader::lastURL(){
|
||||
return nbLink;
|
||||
}
|
||||
const HTTP::URL &Downloader::lastURL(){return nbLink;}
|
||||
|
||||
// continue handling a request, originally set up by the getNonBlocking() function
|
||||
// returns true if the request is complete
|
||||
|
@ -375,7 +374,8 @@ namespace HTTP{
|
|||
return post(link, payload.data(), payload.size(), sync, maxRecursiveDepth);
|
||||
}
|
||||
|
||||
bool Downloader::post(const HTTP::URL &link, const void * payload, const size_t payloadLen, bool sync, uint8_t maxRecursiveDepth){
|
||||
bool Downloader::post(const HTTP::URL &link, const void *payload, const size_t payloadLen,
|
||||
bool sync, uint8_t maxRecursiveDepth){
|
||||
if (!canRequest(link)){return false;}
|
||||
size_t loop = retryCount; // max 5 attempts
|
||||
while (--loop){// loop while we are unsuccessful
|
||||
|
@ -499,4 +499,3 @@ namespace HTTP{
|
|||
}
|
||||
|
||||
}// namespace HTTP
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "http_parser.h"
|
||||
#include "url.h"
|
||||
#include "socket.h"
|
||||
#include "url.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace HTTP{
|
||||
|
@ -11,7 +11,8 @@ namespace HTTP{
|
|||
std::string &data();
|
||||
const std::string &const_data() const;
|
||||
void prepareRequest(const HTTP::URL &link, const std::string &method = "");
|
||||
void doRequest(const HTTP::URL &link, const std::string &method = "", const void * body = 0, const size_t bodyLen = 0);
|
||||
void doRequest(const HTTP::URL &link, const std::string &method = "", const void *body = 0,
|
||||
const size_t bodyLen = 0);
|
||||
void doRequest(const HTTP::URL &link, const std::string &method, const std::string &body);
|
||||
bool get(const std::string &link, Util::DataCallback &cb = Util::defaultDataCallback);
|
||||
bool get(const HTTP::URL &link, uint8_t maxRecursiveDepth = 6, Util::DataCallback &cb = Util::defaultDataCallback);
|
||||
|
@ -20,7 +21,8 @@ namespace HTTP{
|
|||
Util::DataCallback &cb = Util::defaultDataCallback);
|
||||
bool getRangeNonBlocking(const HTTP::URL &link, size_t byteStart, size_t byteEnd,
|
||||
Util::DataCallback &cb = Util::defaultDataCallback);
|
||||
bool post(const HTTP::URL &link, const void * payload, const size_t payloadLen, bool sync = true, uint8_t maxRecursiveDepth = 6);
|
||||
bool post(const HTTP::URL &link, const void *payload, const size_t payloadLen, bool sync = true,
|
||||
uint8_t maxRecursiveDepth = 6);
|
||||
bool post(const HTTP::URL &link, const std::string &payload, bool sync = true,
|
||||
uint8_t maxRecursiveDepth = 6);
|
||||
|
||||
|
@ -65,8 +67,4 @@ namespace HTTP{
|
|||
uint64_t nbReqTime;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}// namespace HTTP
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <algorithm>
|
||||
#include "defines.h"
|
||||
#include "dtls_srtp_handshake.h"
|
||||
#include <algorithm>
|
||||
|
||||
/* Write mbedtls into a log file. */
|
||||
#define LOG_TO_FILE 0
|
||||
|
@ -12,17 +12,15 @@
|
|||
|
||||
static void print_mbedtls_error(int r);
|
||||
static void print_mbedtls_debug_message(void *ctx, int level, const char *file, int line, const char *str);
|
||||
static int on_mbedtls_wants_to_read(void* user, unsigned char* buf, size_t len); /* Called when mbedtls wants to read data from e.g. a socket. */
|
||||
static int on_mbedtls_wants_to_write(void* user, const unsigned char* buf, size_t len); /* Called when mbedtls wants to write data to e.g. a socket. */
|
||||
static int on_mbedtls_wants_to_read(void *user, unsigned char *buf,
|
||||
size_t len); /* Called when mbedtls wants to read data from e.g. a socket. */
|
||||
static int on_mbedtls_wants_to_write(void *user, const unsigned char *buf,
|
||||
size_t len); /* Called when mbedtls wants to write data to e.g. a socket. */
|
||||
static std::string mbedtls_err_to_string(int r);
|
||||
|
||||
/* ----------------------------------------- */
|
||||
|
||||
DTLSSRTPHandshake::DTLSSRTPHandshake()
|
||||
:write_callback(NULL)
|
||||
,cert(NULL)
|
||||
,key(NULL)
|
||||
{
|
||||
DTLSSRTPHandshake::DTLSSRTPHandshake() : write_callback(NULL), cert(NULL), key(NULL){
|
||||
memset((void *)&entropy_ctx, 0x00, sizeof(entropy_ctx));
|
||||
memset((void *)&rand_ctx, 0x00, sizeof(rand_ctx));
|
||||
memset((void *)&ssl_ctx, 0x00, sizeof(ssl_ctx));
|
||||
|
@ -31,17 +29,12 @@ DTLSSRTPHandshake::DTLSSRTPHandshake()
|
|||
memset((void *)&timer_ctx, 0x00, sizeof(timer_ctx));
|
||||
}
|
||||
|
||||
int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate,
|
||||
mbedtls_pk_context* privateKey,
|
||||
int(*writeCallback)(const uint8_t* data, int* nbytes)
|
||||
)
|
||||
{
|
||||
int DTLSSRTPHandshake::init(mbedtls_x509_crt *certificate, mbedtls_pk_context *privateKey,
|
||||
int (*writeCallback)(const uint8_t *data, int *nbytes)){
|
||||
|
||||
int r = 0;
|
||||
mbedtls_ssl_srtp_profile srtp_profiles[] = {
|
||||
MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
|
||||
MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32
|
||||
};
|
||||
mbedtls_ssl_srtp_profile srtp_profiles[] ={MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
|
||||
MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32};
|
||||
|
||||
if (!writeCallback){
|
||||
FAIL_MSG("No writeCallack function given.");
|
||||
|
@ -72,7 +65,8 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate,
|
|||
mbedtls_ssl_cookie_init(&cookie_ctx);
|
||||
|
||||
/* seed and setup the random number generator */
|
||||
r = mbedtls_ctr_drbg_seed(&rand_ctx, mbedtls_entropy_func, &entropy_ctx, (const unsigned char*)"mist-srtp", 9);
|
||||
r = mbedtls_ctr_drbg_seed(&rand_ctx, mbedtls_entropy_func, &entropy_ctx,
|
||||
(const unsigned char *)"mist-srtp", 9);
|
||||
if (0 != r){
|
||||
print_mbedtls_error(r);
|
||||
r = -20;
|
||||
|
@ -80,7 +74,8 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate,
|
|||
}
|
||||
|
||||
/* load defaults into our ssl_conf */
|
||||
r = mbedtls_ssl_config_defaults(&ssl_conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
r = mbedtls_ssl_config_defaults(&ssl_conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (0 != r){
|
||||
print_mbedtls_error(r);
|
||||
r = -30;
|
||||
|
@ -95,7 +90,8 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate,
|
|||
mbedtls_debug_set_threshold(10);
|
||||
|
||||
/* enable SRTP */
|
||||
r = mbedtls_ssl_conf_dtls_srtp_protection_profiles(&ssl_conf, srtp_profiles, sizeof(srtp_profiles) / sizeof(srtp_profiles[0]));
|
||||
r = mbedtls_ssl_conf_dtls_srtp_protection_profiles(&ssl_conf, srtp_profiles,
|
||||
sizeof(srtp_profiles) / sizeof(srtp_profiles[0]));
|
||||
if (0 != r){
|
||||
print_mbedtls_error(r);
|
||||
r = -40;
|
||||
|
@ -135,7 +131,8 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate,
|
|||
/* set temp id, just adds some exta randomness */
|
||||
{
|
||||
std::string remote_id = "mist";
|
||||
r = mbedtls_ssl_set_client_transport_id(&ssl_ctx, (const unsigned char*)remote_id.c_str(), remote_id.size());
|
||||
r = mbedtls_ssl_set_client_transport_id(&ssl_ctx, (const unsigned char *)remote_id.c_str(),
|
||||
remote_id.size());
|
||||
if (0 != r){
|
||||
print_mbedtls_error(r);
|
||||
r = -80;
|
||||
|
@ -150,9 +147,7 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate,
|
|||
|
||||
error:
|
||||
|
||||
if (r < 0) {
|
||||
shutdown();
|
||||
}
|
||||
if (r < 0){shutdown();}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -218,13 +213,15 @@ int DTLSSRTPHandshake::parse(const uint8_t* data, size_t nbytes) {
|
|||
/* see the dtls server example; this is used to prevent certain attacks (ddos) */
|
||||
case MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED:{
|
||||
if (0 != resetSession()){
|
||||
ERROR_MSG("Failed to reset the session which is necessary when we need to verify the HELLO.");
|
||||
ERROR_MSG(
|
||||
"Failed to reset the session which is necessary when we need to verify the HELLO.");
|
||||
return -3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MBEDTLS_ERR_SSL_WANT_READ:{
|
||||
DONTEVEN_MSG("mbedtls wants a bit more data before it can continue parsing the DTLS handshake.");
|
||||
DONTEVEN_MSG(
|
||||
"mbedtls wants a bit more data before it can continue parsing the DTLS handshake.");
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
|
@ -233,8 +230,7 @@ int DTLSSRTPHandshake::parse(const uint8_t* data, size_t nbytes) {
|
|||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (MBEDTLS_ERR_SSL_WANT_WRITE == r);
|
||||
}while (MBEDTLS_ERR_SSL_WANT_WRITE == r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -252,7 +248,8 @@ int DTLSSRTPHandshake::resetSession() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
r = mbedtls_ssl_set_client_transport_id(&ssl_ctx, (const unsigned char*)remote_id.c_str(), remote_id.size());
|
||||
r = mbedtls_ssl_set_client_transport_id(&ssl_ctx, (const unsigned char *)remote_id.c_str(),
|
||||
remote_id.size());
|
||||
if (0 != r){
|
||||
print_mbedtls_error(r);
|
||||
return -2;
|
||||
|
@ -336,14 +333,10 @@ static int on_mbedtls_wants_to_read(void* user, unsigned char* buf, size_t len)
|
|||
}
|
||||
|
||||
/* figure out how much we can read. */
|
||||
if (hs->buffer.size() == 0) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
if (hs->buffer.size() == 0){return MBEDTLS_ERR_SSL_WANT_READ;}
|
||||
|
||||
size_t nbytes = hs->buffer.size();
|
||||
if (nbytes > len) {
|
||||
nbytes = len;
|
||||
}
|
||||
if (nbytes > len){nbytes = len;}
|
||||
|
||||
/* "read" into the given buffer. */
|
||||
memcpy(buf, &hs->buffer[0], nbytes);
|
||||
|
@ -392,22 +385,21 @@ static void print_mbedtls_debug_message(void *ctx, int level, const char *file,
|
|||
|
||||
#if LOG_TO_FILE
|
||||
static std::ofstream ofs;
|
||||
if (!ofs.is_open()) {
|
||||
ofs.open("mbedtls.log", std::ios::out);
|
||||
}
|
||||
if (!ofs.is_open()) {
|
||||
return;
|
||||
}
|
||||
if (!ofs.is_open()){ofs.open("mbedtls.log", std::ios::out);}
|
||||
if (!ofs.is_open()){return;}
|
||||
ofs << str;
|
||||
ofs.flush();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static std::string mbedtls_err_to_string(int r){
|
||||
switch (r){
|
||||
case MBEDTLS_ERR_SSL_WANT_READ: { return "MBEDTLS_ERR_SSL_WANT_READ"; }
|
||||
case MBEDTLS_ERR_SSL_WANT_WRITE: { return "MBEDTLS_ERR_SSL_WANT_WRITE"; }
|
||||
case MBEDTLS_ERR_SSL_WANT_READ:{
|
||||
return "MBEDTLS_ERR_SSL_WANT_READ";
|
||||
}
|
||||
case MBEDTLS_ERR_SSL_WANT_WRITE:{
|
||||
return "MBEDTLS_ERR_SSL_WANT_WRITE";
|
||||
}
|
||||
default:{
|
||||
print_mbedtls_error(r);
|
||||
return "UNKNOWN";
|
||||
|
@ -416,5 +408,3 @@ static std::string mbedtls_err_to_string(int r) {
|
|||
}
|
||||
|
||||
/* ---------------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <deque>
|
||||
#include <mbedtls/config.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/certs.h>
|
||||
#include <mbedtls/x509.h>
|
||||
#include <mbedtls/config.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/debug.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/ssl.h>
|
||||
#include <mbedtls/ssl_cookie.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/debug.h>
|
||||
#include <mbedtls/timing.h>
|
||||
#include <mbedtls/x509.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* ----------------------------------------- */
|
||||
|
||||
class DTLSSRTPHandshake{
|
||||
public:
|
||||
DTLSSRTPHandshake();
|
||||
int init(mbedtls_x509_crt* certificate, mbedtls_pk_context* privateKey, int(*writeCallback)(const uint8_t* data, int* nbytes)); // writeCallback should return 0 on succes < 0 on error. nbytes holds the number of bytes to be sent and needs to be set to the number of bytes actually sent.
|
||||
int init(mbedtls_x509_crt *certificate,
|
||||
mbedtls_pk_context *privateKey, int (*writeCallback)(const uint8_t *data, int *nbytes)); // writeCallback should return 0 on succes < 0 on error. nbytes holds the number of bytes to be sent and needs to be set to the number of bytes actually sent.
|
||||
int shutdown();
|
||||
int parse(const uint8_t *data, size_t nbytes);
|
||||
bool hasKeyingMaterial();
|
||||
|
@ -50,10 +51,8 @@ public:
|
|||
/* ----------------------------------------- */
|
||||
|
||||
inline bool DTLSSRTPHandshake::hasKeyingMaterial(){
|
||||
return (0 != remote_key.size()
|
||||
&& 0 != remote_salt.size()
|
||||
&& 0 != local_key.size()
|
||||
&& 0 != local_salt.size());
|
||||
return (0 != remote_key.size() && 0 != remote_salt.size() && 0 != local_key.size() &&
|
||||
0 != local_salt.size());
|
||||
}
|
||||
|
||||
/* ----------------------------------------- */
|
||||
|
|
89
lib/dtsc.cpp
89
lib/dtsc.cpp
|
@ -1,11 +1,11 @@
|
|||
/// \file dtsc.cpp
|
||||
/// Holds all code for DDVTECH Stream Container parsing/generation.
|
||||
|
||||
#include "dtsc.h"
|
||||
#include "defines.h"
|
||||
#include "dtsc.h"
|
||||
#include <arpa/inet.h> //for htonl/ntohl
|
||||
#include <stdlib.h>
|
||||
#include <string.h> //for memcmp
|
||||
#include <arpa/inet.h> //for htonl/ntohl
|
||||
char DTSC::Magic_Header[] = "DTSC";
|
||||
char DTSC::Magic_Packet[] = "DTPD";
|
||||
char DTSC::Magic_Packet2[] = "DTP2";
|
||||
|
@ -30,9 +30,7 @@ DTSC::File & DTSC::File::operator =(const File & rhs) {
|
|||
F = 0;
|
||||
}
|
||||
endPos = rhs.endPos;
|
||||
if (rhs.myPack) {
|
||||
myPack = rhs.myPack;
|
||||
}
|
||||
if (rhs.myPack){myPack = rhs.myPack;}
|
||||
metadata = rhs.metadata;
|
||||
currtime = rhs.currtime;
|
||||
lastreadpos = rhs.lastreadpos;
|
||||
|
@ -83,7 +81,8 @@ DTSC::File::File(std::string filename, bool create) {
|
|||
return;
|
||||
}
|
||||
if (memcmp(buffer, DTSC::Magic_Header, 4) != 0){
|
||||
if (memcmp(buffer, DTSC::Magic_Packet2, 4) != 0 && memcmp(buffer, DTSC::Magic_Packet, 4) != 0 && memcmp(buffer, DTSC::Magic_Command, 4) != 0) {
|
||||
if (memcmp(buffer, DTSC::Magic_Packet2, 4) != 0 &&
|
||||
memcmp(buffer, DTSC::Magic_Packet, 4) != 0 && memcmp(buffer, DTSC::Magic_Command, 4) != 0){
|
||||
DEBUG_MSG(DLVL_ERROR, "%s is not a valid DTSC file", filename.c_str());
|
||||
fclose(F);
|
||||
F = 0;
|
||||
|
@ -112,20 +111,16 @@ DTSC::File::File(std::string filename, bool create) {
|
|||
}else{
|
||||
fseek(F, 0, SEEK_SET);
|
||||
File Fhead(filename + ".dtsh");
|
||||
if (Fhead) {
|
||||
metadata = Fhead.metadata;
|
||||
}
|
||||
if (Fhead){metadata = Fhead.metadata;}
|
||||
}
|
||||
currframe = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Returns the header metadata for this file as JSON::Value.
|
||||
DTSC::Meta &DTSC::File::getMeta(){
|
||||
return metadata;
|
||||
}
|
||||
|
||||
|
||||
/// (Re)writes the given string to the header area if the size is the same as the existing header.
|
||||
/// Forces a write if force is set to true.
|
||||
bool DTSC::File::writeHeader(std::string &header, bool force){
|
||||
|
@ -137,9 +132,7 @@ bool DTSC::File::writeHeader(std::string & header, bool force) {
|
|||
int pSize = htonl(header.size());
|
||||
fseek(F, 4, SEEK_SET);
|
||||
int tmpret = fwrite((void *)(&pSize), 4, 1, F);
|
||||
if (tmpret != 1) {
|
||||
return false;
|
||||
}
|
||||
if (tmpret != 1){return false;}
|
||||
fseek(F, 8, SEEK_SET);
|
||||
int ret = fwrite(header.c_str(), headerSize, 1, F);
|
||||
fseek(F, 8 + headerSize, SEEK_SET);
|
||||
|
@ -153,17 +146,11 @@ long long int DTSC::File::addHeader(std::string & header) {
|
|||
long long int writePos = ftell(F);
|
||||
int hSize = htonl(header.size());
|
||||
int ret = fwrite(DTSC::Magic_Header, 4, 1, F); // write header
|
||||
if (ret != 1) {
|
||||
return 0;
|
||||
}
|
||||
if (ret != 1){return 0;}
|
||||
ret = fwrite((void *)(&hSize), 4, 1, F); // write size
|
||||
if (ret != 1) {
|
||||
return 0;
|
||||
}
|
||||
if (ret != 1){return 0;}
|
||||
ret = fwrite(header.c_str(), header.size(), 1, F); // write contents
|
||||
if (ret != 1) {
|
||||
return 0;
|
||||
}
|
||||
if (ret != 1){return 0;}
|
||||
fseek(F, 0, SEEK_END);
|
||||
endPos = ftell(F);
|
||||
return writePos; // return position written at
|
||||
|
@ -212,9 +199,7 @@ void DTSC::File::readHeader(int pos) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (!metadata.live){
|
||||
metadata.vod = true;
|
||||
}
|
||||
if (!metadata.live){metadata.vod = true;}
|
||||
}
|
||||
|
||||
long int DTSC::File::getBytePosEOF(){
|
||||
|
@ -261,14 +246,11 @@ void DTSC::File::seekNext() {
|
|||
return seekNext();
|
||||
}
|
||||
long long unsigned int version = 0;
|
||||
if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0) {
|
||||
version = 1;
|
||||
}
|
||||
if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0) {
|
||||
version = 2;
|
||||
}
|
||||
if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0){version = 1;}
|
||||
if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0){version = 2;}
|
||||
if (version == 0){
|
||||
DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d", (unsigned int)lastreadpos, (char *)buffer, DTSC::Magic_Packet2, (int)lastreadpos);
|
||||
DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d",
|
||||
(unsigned int)lastreadpos, (char *)buffer, DTSC::Magic_Packet2, (int)lastreadpos);
|
||||
myPack.null();
|
||||
return;
|
||||
}
|
||||
|
@ -320,7 +302,8 @@ void DTSC::File::seekNext() {
|
|||
}
|
||||
}
|
||||
if (currentPositions.size()){
|
||||
for (std::set<seekPos>::iterator curPosIter = currentPositions.begin(); curPosIter != currentPositions.end(); curPosIter++) {
|
||||
for (std::set<seekPos>::iterator curPosIter = currentPositions.begin();
|
||||
curPosIter != currentPositions.end(); curPosIter++){
|
||||
if ((*curPosIter).trackID == tmpPos.trackID && (*curPosIter).seekTime >= tmpPos.seekTime){
|
||||
insert = false;
|
||||
break;
|
||||
|
@ -330,9 +313,7 @@ void DTSC::File::seekNext() {
|
|||
}
|
||||
}
|
||||
if (insert){
|
||||
if (tmpPos.seekTime > 0xffffffffffffff00ll){
|
||||
tmpPos.seekTime = 0;
|
||||
}
|
||||
if (tmpPos.seekTime > 0xffffffffffffff00ll){tmpPos.seekTime = 0;}
|
||||
currentPositions.insert(tmpPos);
|
||||
}else{
|
||||
seek_time(myPack.getTime(), myPack.getTrackId(), true);
|
||||
|
@ -357,12 +338,11 @@ void DTSC::File::parseNext(){
|
|||
return;
|
||||
}
|
||||
long long unsigned int version = 0;
|
||||
if (memcmp(header_buffer, DTSC::Magic_Packet, 4) == 0 || memcmp(header_buffer, DTSC::Magic_Command, 4) == 0 || memcmp(header_buffer, DTSC::Magic_Header, 4) == 0) {
|
||||
if (memcmp(header_buffer, DTSC::Magic_Packet, 4) == 0 || memcmp(header_buffer, DTSC::Magic_Command, 4) == 0 ||
|
||||
memcmp(header_buffer, DTSC::Magic_Header, 4) == 0){
|
||||
version = 1;
|
||||
}
|
||||
if (memcmp(header_buffer, DTSC::Magic_Packet2, 4) == 0) {
|
||||
version = 2;
|
||||
}
|
||||
if (memcmp(header_buffer, DTSC::Magic_Packet2, 4) == 0){version = 2;}
|
||||
if (version == 0){
|
||||
DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x: %.4s", (unsigned int)lastreadpos, (char *)buffer);
|
||||
myPack.null();
|
||||
|
@ -421,9 +401,7 @@ bool DTSC::File::seek_time(unsigned int ms, unsigned int trackNo, bool forceSeek
|
|||
DTSC::Track &trackRef = metadata.tracks[trackNo];
|
||||
for (unsigned int i = 0; i < trackRef.keys.size(); i++){
|
||||
long keyTime = trackRef.keys[i].getTime();
|
||||
if (keyTime > ms) {
|
||||
break;
|
||||
}
|
||||
if (keyTime > ms){break;}
|
||||
if ((long long unsigned int)keyTime > tmpPos.seekTime){
|
||||
tmpPos.seekTime = keyTime;
|
||||
tmpPos.bytePos = trackRef.keys[i].getBpos();
|
||||
|
@ -449,7 +427,8 @@ bool DTSC::File::seek_time(unsigned int ms, unsigned int trackNo, bool forceSeek
|
|||
unsigned int packID = ntohl(((int *)header)[2]);
|
||||
if (memcmp(header, Magic_Packet2, 4) != 0 || packID != trackNo){
|
||||
if (memcmp(header, "DT", 2) != 0){
|
||||
DEBUG_MSG(DLVL_WARN, "Invalid header during seek to %u in track %d @ %lld - resetting bytePos from %lld to zero", ms, trackNo, lastreadpos, tmpPos.bytePos);
|
||||
DEBUG_MSG(DLVL_WARN, "Invalid header during seek to %u in track %d @ %lld - resetting bytePos from %lld to zero",
|
||||
ms, trackNo, lastreadpos, tmpPos.bytePos);
|
||||
tmpPos.bytePos = 0;
|
||||
continue;
|
||||
}
|
||||
|
@ -468,9 +447,7 @@ bool DTSC::File::seek_time(unsigned int ms, unsigned int trackNo, bool forceSeek
|
|||
}
|
||||
}
|
||||
// DEBUG_MSG(DLVL_HIGH, "Seek to %u:%d resulted in %lli", trackNo, ms, tmpPos.seekTime);
|
||||
if (tmpPos.seekTime > 0xffffffffffffff00ll){
|
||||
tmpPos.seekTime = 0;
|
||||
}
|
||||
if (tmpPos.seekTime > 0xffffffffffffff00ll){tmpPos.seekTime = 0;}
|
||||
currentPositions.insert(tmpPos);
|
||||
return true;
|
||||
}
|
||||
|
@ -488,9 +465,7 @@ bool DTSC::File::seek_time(unsigned int ms) {
|
|||
}
|
||||
|
||||
bool DTSC::File::seek_bpos(int bpos){
|
||||
if (fseek(F, bpos, SEEK_SET) == 0) {
|
||||
return true;
|
||||
}
|
||||
if (fseek(F, bpos, SEEK_SET) == 0){return true;}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -498,9 +473,7 @@ void DTSC::File::rewritePacket(std::string & newPacket, int bytePos) {
|
|||
fseek(F, bytePos, SEEK_SET);
|
||||
fwrite(newPacket.c_str(), newPacket.size(), 1, F);
|
||||
fseek(F, 0, SEEK_END);
|
||||
if (ftell(F) > endPos) {
|
||||
endPos = ftell(F);
|
||||
}
|
||||
if (ftell(F) > endPos){endPos = ftell(F);}
|
||||
}
|
||||
|
||||
void DTSC::File::writePacket(std::string &newPacket){
|
||||
|
@ -515,15 +488,11 @@ void DTSC::File::writePacket(JSON::Value & newPacket) {
|
|||
}
|
||||
|
||||
bool DTSC::File::atKeyframe(){
|
||||
if (myPack.getFlag("keyframe")) {
|
||||
return true;
|
||||
}
|
||||
if (myPack.getFlag("keyframe")){return true;}
|
||||
long long int bTime = myPack.getTime();
|
||||
DTSC::Track &trackRef = metadata.tracks[myPack.getTrackId()];
|
||||
for (unsigned int i = 0; i < trackRef.keys.size(); i++){
|
||||
if (trackRef.keys[i].getTime() >= bTime) {
|
||||
return (trackRef.keys[i].getTime() == bTime);
|
||||
}
|
||||
if (trackRef.keys[i].getTime() >= bTime){return (trackRef.keys[i].getTime() == bTime);}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
83
lib/dtsc.h
83
lib/dtsc.h
|
@ -2,16 +2,16 @@
|
|||
/// Holds all headers for DDVTECH Stream Container parsing/generation.
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <stdint.h> //for uint64_t
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include <stdio.h> //for FILE
|
||||
#include "json.h"
|
||||
#include "socket.h"
|
||||
#include "timing.h"
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <stdint.h> //for uint64_t
|
||||
#include <stdio.h> //for FILE
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define DTSC_INT 0x01
|
||||
#define DTSC_STR 0x02
|
||||
|
@ -53,9 +53,7 @@ namespace DTSC {
|
|||
return true;
|
||||
}else{
|
||||
if (seekTime == rhs.seekTime){
|
||||
if (trackID < rhs.trackID) {
|
||||
return true;
|
||||
}
|
||||
if (trackID < rhs.trackID){return true;}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -65,13 +63,7 @@ namespace DTSC {
|
|||
unsigned int trackID; ///< Stores the track the DTSC packet referenced by this structure is associated with.
|
||||
};
|
||||
|
||||
enum packType {
|
||||
DTSC_INVALID,
|
||||
DTSC_HEAD,
|
||||
DTSC_V1,
|
||||
DTSC_V2,
|
||||
DTCM
|
||||
};
|
||||
enum packType{DTSC_INVALID, DTSC_HEAD, DTSC_V1, DTSC_V2, DTCM};
|
||||
|
||||
/// This class allows scanning through raw binary format DTSC data.
|
||||
/// It can be used as an iterator or as a direct accessor.
|
||||
|
@ -98,6 +90,7 @@ namespace DTSC {
|
|||
std::string asString() const;
|
||||
void getString(char *&result, size_t &len) const;
|
||||
JSON::Value asJSON() const;
|
||||
|
||||
private:
|
||||
char *p;
|
||||
size_t len;
|
||||
|
@ -106,8 +99,8 @@ namespace DTSC {
|
|||
/// DTSC::Packets can currently be three types:
|
||||
/// DTSC_HEAD packets are the "DTSC" header string, followed by 4 bytes len and packed content.
|
||||
/// DTSC_V1 packets are "DTPD", followed by 4 bytes len and packed content.
|
||||
/// DTSC_V2 packets are "DTP2", followed by 4 bytes len, 4 bytes trackID, 8 bytes time, and packed content.
|
||||
/// The len is always without the first 8 bytes counted.
|
||||
/// DTSC_V2 packets are "DTP2", followed by 4 bytes len, 4 bytes trackID, 8 bytes time, and packed
|
||||
/// content. The len is always without the first 8 bytes counted.
|
||||
class Packet{
|
||||
public:
|
||||
Packet();
|
||||
|
@ -120,7 +113,9 @@ namespace DTSC {
|
|||
packType getVersion() const;
|
||||
void reInit(Socket::Connection &src);
|
||||
void reInit(const char *data_, unsigned int len, bool noCopy = false);
|
||||
void genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, uint64_t packBytePos, bool isKeyframe, int64_t bootMsOffset = 0);
|
||||
void genericFill(long long packTime, long long packOffset, long long packTrack,
|
||||
const char *packData, long long packDataSize, uint64_t packBytePos,
|
||||
bool isKeyframe, int64_t bootMsOffset = 0);
|
||||
void appendData(const char *appendData, uint32_t appendLen);
|
||||
void getString(const char *identifier, char *&result, size_t &len) const;
|
||||
void getString(const char *identifier, std::string &result) const;
|
||||
|
@ -145,6 +140,7 @@ namespace DTSC {
|
|||
std::string toSummary() const;
|
||||
Scan getScan() const;
|
||||
Scan getScan();
|
||||
|
||||
protected:
|
||||
bool master;
|
||||
packType version;
|
||||
|
@ -159,16 +155,14 @@ namespace DTSC {
|
|||
/// A child class of DTSC::Packet, which allows overriding the packet time efficiently.
|
||||
class RetimedPacket : public Packet{
|
||||
public:
|
||||
RetimedPacket(uint64_t reTime){
|
||||
timeOverride = reTime;
|
||||
}
|
||||
RetimedPacket(uint64_t reTime, const Packet & rhs) : Packet(rhs){
|
||||
timeOverride = reTime;
|
||||
}
|
||||
RetimedPacket(uint64_t reTime, const char * data_, unsigned int len, bool noCopy = false) : Packet(data_, len, noCopy){
|
||||
RetimedPacket(uint64_t reTime){timeOverride = reTime;}
|
||||
RetimedPacket(uint64_t reTime, const Packet &rhs) : Packet(rhs){timeOverride = reTime;}
|
||||
RetimedPacket(uint64_t reTime, const char *data_, unsigned int len, bool noCopy = false)
|
||||
: Packet(data_, len, noCopy){
|
||||
timeOverride = reTime;
|
||||
}
|
||||
virtual uint64_t getTime() const{return timeOverride;}
|
||||
|
||||
protected:
|
||||
uint64_t timeOverride;
|
||||
};
|
||||
|
@ -197,9 +191,7 @@ namespace DTSC {
|
|||
if (seekTime < rhs.seekTime){
|
||||
return true;
|
||||
}else{
|
||||
if (seekTime > rhs.seekTime) {
|
||||
return false;
|
||||
}
|
||||
if (seekTime > rhs.seekTime){return false;}
|
||||
}
|
||||
return (trackID < rhs.trackID);
|
||||
}
|
||||
|
@ -220,6 +212,7 @@ namespace DTSC {
|
|||
void setIvec(const char *iVec, int len);
|
||||
long long int asInt();
|
||||
char *getData();
|
||||
|
||||
private:
|
||||
///\brief Data storage for this initialization vector.
|
||||
///
|
||||
|
@ -239,6 +232,7 @@ namespace DTSC {
|
|||
void setOffset(uint32_t newOffset);
|
||||
char *getData();
|
||||
void toPrettyString(std::ostream &str, int indent = 0);
|
||||
|
||||
private:
|
||||
#define PACKED_PART_SIZE 9
|
||||
///\brief Data storage for this Part.
|
||||
|
@ -266,6 +260,7 @@ namespace DTSC {
|
|||
void setTime(unsigned long long newTime);
|
||||
char *getData();
|
||||
void toPrettyString(std::ostream &str, int indent = 0);
|
||||
|
||||
private:
|
||||
#define PACKED_KEY_SIZE 25
|
||||
///\brief Data storage for this Key.
|
||||
|
@ -291,6 +286,7 @@ namespace DTSC {
|
|||
void setSize(unsigned long newSize);
|
||||
char *getData();
|
||||
void toPrettyString(std::ostream &str, int indent = 0);
|
||||
|
||||
private:
|
||||
#define PACKED_FRAGMENT_SIZE 13
|
||||
///\brief Data storage for this Fragment.
|
||||
|
@ -314,9 +310,12 @@ namespace DTSC {
|
|||
return (parts.size() && keySizes.size() && (keySizes.size() == keys.size()));
|
||||
}
|
||||
/*
|
||||
void update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 1900);
|
||||
void update(long long packTime, long long packOffset, long long packDataSize, uint64_t
|
||||
packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 1900);
|
||||
*/
|
||||
void update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 1900, const char * iVec = 0);
|
||||
void update(long long packTime, long long packOffset, long long packDataSize,
|
||||
uint64_t packBytePos, bool isKeyframe, long long packSendSize,
|
||||
unsigned long segment_size = 1900, const char *iVec = 0);
|
||||
int getSendLen(bool skipDynamic = false);
|
||||
void send(Socket::Connection &conn, bool skipDynamic = false);
|
||||
void writeTo(char *&p);
|
||||
|
@ -358,6 +357,7 @@ namespace DTSC {
|
|||
int fpks;
|
||||
void removeFirstKey();
|
||||
uint32_t secsSinceFirstFragmentInsert();
|
||||
|
||||
private:
|
||||
std::string cachedIdent;
|
||||
std::deque<uint32_t> fragInsertTime;
|
||||
|
@ -380,11 +380,16 @@ namespace DTSC {
|
|||
void updatePosOverride(DTSC::Packet &pack, uint64_t bpos);
|
||||
void update(JSON::Value &pack, unsigned long segment_size = 1900);
|
||||
/*LTS
|
||||
void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 1900);
|
||||
LTS*/
|
||||
void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 1900, const char * iVec = 0);
|
||||
unsigned int getSendLen(bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>());
|
||||
void send(Socket::Connection & conn, bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>());
|
||||
void update(long long packTime, long long packOffset, long long packTrack, long long
|
||||
packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long
|
||||
segment_size = 1900); LTS*/
|
||||
void update(long long packTime, long long packOffset, long long packTrack,
|
||||
long long packDataSize, uint64_t packBytePos, bool isKeyframe,
|
||||
long long packSendSize = 0, unsigned long segment_size = 1900, const char *iVec = 0);
|
||||
unsigned int getSendLen(bool skipDynamic = false,
|
||||
std::set<unsigned long> selectedTracks = std::set<unsigned long>());
|
||||
void send(Socket::Connection &conn, bool skipDynamic = false,
|
||||
std::set<unsigned long> selectedTracks = std::set<unsigned long>());
|
||||
void writeTo(char *p);
|
||||
JSON::Value toJSON();
|
||||
void reset();
|
||||
|
@ -448,6 +453,7 @@ namespace DTSC {
|
|||
void writePacket(JSON::Value &newPacket);
|
||||
bool atKeyframe();
|
||||
void selectTracks(std::set<unsigned long> &tracks);
|
||||
|
||||
private:
|
||||
long int endPos;
|
||||
void readHeader(int pos);
|
||||
|
@ -466,5 +472,4 @@ namespace DTSC {
|
|||
};
|
||||
// FileWriter
|
||||
|
||||
}
|
||||
|
||||
}// namespace DTSC
|
||||
|
|
630
lib/dtscmeta.cpp
630
lib/dtscmeta.cpp
File diff suppressed because it is too large
Load diff
14
lib/ebml.cpp
14
lib/ebml.cpp
|
@ -1,6 +1,6 @@
|
|||
#include "ebml.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
#include "ebml.h"
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -380,8 +380,7 @@ namespace EBML{
|
|||
switch (getType()){
|
||||
case ELEM_MASTER:{
|
||||
const uint64_t payLen = getPayloadLen();
|
||||
ret << std::string(indent, ' ') << "Element [" << getIDString(getID()) << "] ("
|
||||
<< getOuterLen() << "b, ";
|
||||
ret << std::string(indent, ' ') << "Element [" << getIDString(getID()) << "] (" << getOuterLen() << "b, ";
|
||||
if (payLen == 0xFFFFFFFFFFFFFFFFull){
|
||||
ret << "infinite";
|
||||
}else{
|
||||
|
@ -639,9 +638,8 @@ namespace EBML{
|
|||
|
||||
std::string Block::toPrettyString(const uint8_t indent, const uint8_t detail) const{
|
||||
std::stringstream ret;
|
||||
ret << std::string(indent, ' ') << getIDString(getID()) << " with "
|
||||
<< (unsigned int)getFrameCount() << " frame(s) for track " << getTrackNum() << " @ "
|
||||
<< getTimecode();
|
||||
ret << std::string(indent, ' ') << getIDString(getID()) << " with " << (unsigned int)getFrameCount()
|
||||
<< " frame(s) for track " << getTrackNum() << " @ " << getTimecode();
|
||||
if (isKeyframe()){ret << " [KeyOnly]";}
|
||||
if (isInvisible()){ret << " [Invisible]";}
|
||||
if (isDiscardable()){ret << " [Discardable]";}
|
||||
|
@ -656,8 +654,7 @@ namespace EBML{
|
|||
for (uint32_t frameNo = 0; frameNo < getFrameCount(); ++frameNo){
|
||||
const char *payDat = getFrameData(frameNo);
|
||||
const uint64_t payLen = getFrameSize(frameNo);
|
||||
ret << std::dec << std::string(indent + 4, ' ') << "Frame " << (frameNo + 1) << " ("
|
||||
<< payLen << "b):";
|
||||
ret << std::dec << std::string(indent + 4, ' ') << "Frame " << (frameNo + 1) << " (" << payLen << "b):";
|
||||
if (!payDat || !payLen || detail < 6){
|
||||
ret << std::endl;
|
||||
continue;
|
||||
|
@ -683,4 +680,3 @@ namespace EBML{
|
|||
return ret.str();
|
||||
}
|
||||
}// namespace EBML
|
||||
|
||||
|
|
|
@ -121,4 +121,3 @@ namespace EBML{
|
|||
virtual std::string toPrettyString(const uint8_t indent = 0, const uint8_t detail = 3) const;
|
||||
};
|
||||
}// namespace EBML
|
||||
|
||||
|
|
|
@ -118,8 +118,7 @@ namespace EBML{
|
|||
|
||||
void sendElemInfo(Socket::Connection &C, const std::string &appName, double duration){
|
||||
sendElemHead(C, EID_INFO,
|
||||
13 + 2 * appName.size() +
|
||||
(duration > 0 ? sizeElemDbl(EID_DURATION, duration) : 0));
|
||||
13 + 2 * appName.size() + (duration > 0 ? sizeElemDbl(EID_DURATION, duration) : 0));
|
||||
sendElemUInt(C, EID_TIMECODESCALE, 1000000);
|
||||
if (duration > 0){sendElemDbl(C, EID_DURATION, duration);}
|
||||
sendElemStr(C, EID_MUXINGAPP, appName);
|
||||
|
@ -136,8 +135,7 @@ namespace EBML{
|
|||
(duration > 0 ? sizeElemDbl(EID_DURATION, duration) : 0));
|
||||
}
|
||||
|
||||
void sendSimpleBlock(Socket::Connection &C, DTSC::Packet &pkt, uint64_t clusterTime,
|
||||
bool forceKeyframe){
|
||||
void sendSimpleBlock(Socket::Connection &C, DTSC::Packet &pkt, uint64_t clusterTime, bool forceKeyframe){
|
||||
size_t dataLen = 0;
|
||||
char *dataPointer = 0;
|
||||
pkt.getString("data", dataPointer, dataLen);
|
||||
|
@ -170,8 +168,7 @@ namespace EBML{
|
|||
return sizeElemHead(EID_SEEK, elems) + elems;
|
||||
}
|
||||
|
||||
void sendElemCuePoint(Socket::Connection &C, uint64_t time, uint64_t track, uint64_t clusterPos,
|
||||
uint64_t relaPos){
|
||||
void sendElemCuePoint(Socket::Connection &C, uint64_t time, uint64_t track, uint64_t clusterPos, uint64_t relaPos){
|
||||
uint32_t elemsA = 0, elemsB = 0;
|
||||
elemsA += sizeElemUInt(EID_CUETRACK, track);
|
||||
elemsA += sizeElemUInt(EID_CUECLUSTERPOSITION, clusterPos);
|
||||
|
@ -196,4 +193,3 @@ namespace EBML{
|
|||
}
|
||||
|
||||
}// namespace EBML
|
||||
|
||||
|
|
|
@ -17,8 +17,7 @@ namespace EBML{
|
|||
|
||||
void sendElemSeek(Socket::Connection &C, uint32_t ID, uint64_t bytePos);
|
||||
uint32_t sizeElemSeek(uint32_t ID, uint64_t bytePos);
|
||||
void sendElemCuePoint(Socket::Connection &C, uint64_t time, uint64_t track, uint64_t clusterPos,
|
||||
uint64_t relaPos);
|
||||
void sendElemCuePoint(Socket::Connection &C, uint64_t time, uint64_t track, uint64_t clusterPos, uint64_t relaPos);
|
||||
uint32_t sizeElemCuePoint(uint64_t time, uint64_t track, uint64_t clusterPos, uint64_t relaPos);
|
||||
|
||||
uint8_t sizeUInt(const uint64_t val);
|
||||
|
@ -28,8 +27,6 @@ namespace EBML{
|
|||
uint32_t sizeElemDbl(uint32_t ID, const double val);
|
||||
uint32_t sizeElemStr(uint32_t ID, const std::string &val);
|
||||
|
||||
void sendSimpleBlock(Socket::Connection &C, DTSC::Packet &pkt, uint64_t clusterTime,
|
||||
bool forceKeyframe = false);
|
||||
void sendSimpleBlock(Socket::Connection &C, DTSC::Packet &pkt, uint64_t clusterTime, bool forceKeyframe = false);
|
||||
uint32_t sizeSimpleBlock(uint64_t trackId, uint32_t dataSize);
|
||||
}// namespace EBML
|
||||
|
||||
|
|
|
@ -101,11 +101,9 @@ namespace Encodings{
|
|||
std::string escaped = "";
|
||||
int max = c.length();
|
||||
for (int i = 0; i < max; i++){
|
||||
if (('0' <= c[i] && c[i] <= '9') || ('a' <= c[i] && c[i] <= 'z') ||
|
||||
('A' <= c[i] && c[i] <= 'Z') ||
|
||||
if (('0' <= c[i] && c[i] <= '9') || ('a' <= c[i] && c[i] <= 'z') || ('A' <= c[i] && c[i] <= 'Z') ||
|
||||
(c[i] == '$' || c[i] == '-' || c[i] == '_' || c[i] == '.' || c[i] == ',' || c[i] == '!' ||
|
||||
c[i] == '~' || c[i] == ';' || c[i] == '*' || c[i] == '(' || c[i] == ')' ||
|
||||
c[i] == '\'') ||
|
||||
c[i] == '~' || c[i] == ';' || c[i] == '*' || c[i] == '(' || c[i] == ')' || c[i] == '\'') ||
|
||||
(ign.size() && ign.find(c[i]) != std::string::npos)){
|
||||
escaped.append(&c[i], 1);
|
||||
}else{
|
||||
|
@ -143,4 +141,3 @@ namespace Encodings{
|
|||
}
|
||||
|
||||
}// namespace Encodings
|
||||
|
||||
|
|
|
@ -40,4 +40,3 @@ namespace Encodings{
|
|||
};
|
||||
|
||||
}// namespace Encodings
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#include "encryption.h"
|
||||
#include "auth.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
#include "encode.h"
|
||||
#include "encryption.h"
|
||||
#include "http_parser.h"
|
||||
#include "nal.h" /*LTS*/
|
||||
#include "rijndael.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include "rijndael.h"
|
||||
#include "defines.h"
|
||||
#include "bitfields.h"
|
||||
#include "http_parser.h"
|
||||
#include "encode.h"
|
||||
#include "nal.h"/*LTS*/
|
||||
#include <sstream>
|
||||
|
||||
namespace Encryption{
|
||||
|
@ -19,14 +19,11 @@ namespace Encryption {
|
|||
std::stringstream res;
|
||||
for (int i = 0; i < dataLen; i++){
|
||||
res << std::hex << std::setw(2) << std::setfill('0') << (int)data[i];
|
||||
if (i % 4 == 3){
|
||||
res << " ";
|
||||
}
|
||||
if (i % 4 == 3){res << " ";}
|
||||
}
|
||||
return res.str();
|
||||
}
|
||||
|
||||
|
||||
std::string AES_Crypt(const std::string &data, const std::string &key, std::string &ivec){
|
||||
return AES_Crypt(data.data(), data.size(), key.data(), ivec.data());
|
||||
}
|
||||
|
@ -43,7 +40,8 @@ namespace Encryption {
|
|||
/// This function encrypts data in-place.
|
||||
/// It alters all parameters except dataLen.
|
||||
/// Do not use it unless you know what you are doing.
|
||||
void AESPartialCrypt(char * data, int dataLen, char * expandedKey, char * eCount, char * iVec, unsigned int & num, bool & initialize) {
|
||||
void AESPartialCrypt(char *data, int dataLen, char *expandedKey, char *eCount, char *iVec,
|
||||
unsigned int &num, bool &initialize){
|
||||
if (initialize){
|
||||
num = 0;
|
||||
memset(eCount, 0, 16);
|
||||
|
@ -100,7 +98,6 @@ namespace Encryption {
|
|||
return std::string(result, 8);
|
||||
}
|
||||
|
||||
|
||||
/// This function encrypts data in-place.
|
||||
void AESFullCrypt(char *data, int dataLen, const char *key, const char *ivec){
|
||||
unsigned int num = 0;
|
||||
|
@ -137,9 +134,7 @@ namespace Encryption {
|
|||
pos += *it;
|
||||
}
|
||||
}
|
||||
if (codec == "AAC") {
|
||||
Encryption::AESFullCrypt(data, dataLen, key, iVec);
|
||||
}
|
||||
if (codec == "AAC"){Encryption::AESFullCrypt(data, dataLen, key, iVec);}
|
||||
}
|
||||
|
||||
/// Converts a hexidecimal string format key to binary string format.
|
||||
|
@ -153,7 +148,6 @@ namespace Encryption {
|
|||
return std::string(newkey, 16);
|
||||
}
|
||||
|
||||
|
||||
/// Helper function for urlescape.
|
||||
/// Encodes a character as two hex digits.
|
||||
std::string hex(char dec){
|
||||
|
@ -171,9 +165,7 @@ namespace Encryption {
|
|||
std::string hex(const std::string &input){
|
||||
std::string res;
|
||||
res.reserve(input.size() * 2);
|
||||
for (unsigned int i = 0; i < input.size(); i++) {
|
||||
res += hex(input[i]);
|
||||
}
|
||||
for (unsigned int i = 0; i < input.size(); i++){res += hex(input[i]);}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -181,7 +173,8 @@ namespace Encryption {
|
|||
int hostPos = vmData.url.find("://") + 3;
|
||||
int portPos = vmData.url.find(":", hostPos);
|
||||
|
||||
std::string hostName = vmData.url.substr(hostPos, (portPos == std::string::npos ? portPos : portPos - hostPos));
|
||||
std::string hostName =
|
||||
vmData.url.substr(hostPos, (portPos == std::string::npos ? portPos : portPos - hostPos));
|
||||
int port = (portPos == std::string::npos ? 80 : atoi(vmData.url.data() + portPos + 1));
|
||||
Socket::Connection veriConn(hostName, port, true);
|
||||
|
||||
|
@ -229,5 +222,4 @@ namespace Encryption {
|
|||
offset += laurl.size() + 1; //+1 for the concluding 0-byte
|
||||
memcpy(shmPage + offset, lauurl.c_str(), lauurl.size() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
}// namespace Encryption
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include "dtsc.h"
|
||||
#include <string>
|
||||
|
||||
namespace Encryption{
|
||||
class verimatrixData{
|
||||
|
@ -23,7 +23,8 @@ namespace Encryption {
|
|||
|
||||
// These functions are dangerous for your data
|
||||
void AESFullCrypt(char *data, int dataLen, const char *key, const char *ivec);
|
||||
void AESPartialCrypt(char * data, int dataLen, char * expandedKey, char * eCount, char * iVec, unsigned int & num, bool & initialize);
|
||||
void AESPartialCrypt(char *data, int dataLen, char *expandedKey, char *eCount, char *iVec,
|
||||
unsigned int &num, bool &initialize);
|
||||
|
||||
std::string PR_GenerateContentKey(std::string &keyseed, std::string &keyid);
|
||||
std::string PR_GuidToByteArray(std::string &guid);
|
||||
|
@ -31,4 +32,4 @@ namespace Encryption {
|
|||
void encryptPlayReady(DTSC::Packet &pack, std::string &codec, const char *iVec, const char *key);
|
||||
|
||||
void fillVerimatrix(verimatrixData &vmData);
|
||||
}
|
||||
}// namespace Encryption
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/// \file flv_tag.cpp
|
||||
/// Holds all code for the FLV namespace.
|
||||
|
||||
#include "flv_tag.h"
|
||||
#include "adts.h"
|
||||
#include "defines.h"
|
||||
#include "flv_tag.h"
|
||||
#include "rtmpchunks.h"
|
||||
#include "timing.h"
|
||||
#include "util.h"
|
||||
#include "adts.h"
|
||||
#include <fcntl.h> //for Tag::FileLoader
|
||||
#include <sstream>
|
||||
#include <stdio.h> //for Tag::FileLoader
|
||||
|
@ -20,8 +20,7 @@
|
|||
/// Defaults to a audio+video header on FLV version 0x01 if no header received yet.
|
||||
char FLV::Header[13] ={'F', 'L', 'V', 0x01, 0x05, 0, 0, 0, 0x09, 0, 0, 0, 0};
|
||||
|
||||
bool FLV::Parse_Error =
|
||||
false; ///< This variable is set to true if a problem is encountered while parsing the FLV.
|
||||
bool FLV::Parse_Error = false; ///< This variable is set to true if a problem is encountered while parsing the FLV.
|
||||
std::string FLV::Error_Str = "";
|
||||
|
||||
/// Checks a FLV Header for validness. Returns true if the header is valid, false
|
||||
|
@ -504,51 +503,41 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Meta &M, std::set<long unsigned int> &selTrack
|
|||
if (M.tracks[*it].type == "video"){
|
||||
trinfo.addContent(AMF::Object("", AMF::AMF0_OBJECT));
|
||||
trinfo.getContentP(i)->addContent(AMF::Object(
|
||||
"length", ((double)M.tracks[*it].lastms / 1000) * ((double)M.tracks[*it].fpks / 1000.0),
|
||||
AMF::AMF0_NUMBER));
|
||||
"length", ((double)M.tracks[*it].lastms / 1000) * ((double)M.tracks[*it].fpks / 1000.0), AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->addContent(
|
||||
AMF::Object("timescale", ((double)M.tracks[*it].fpks / 1000.0), AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->addContent(AMF::Object("sampledescription", AMF::AMF0_STRICT_ARRAY));
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("hasVideo", 1, AMF::AMF0_BOOL));
|
||||
if (M.tracks[*it].codec == "H264"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 7, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "avc1"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "avc1"));
|
||||
}
|
||||
if (M.tracks[*it].codec == "ScreenVideo2"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 6, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "sv2"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "sv2"));
|
||||
}
|
||||
if (M.tracks[*it].codec == "VP6Alpha"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 5, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "vp6a"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "vp6a"));
|
||||
}
|
||||
if (M.tracks[*it].codec == "VP6"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 4, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "vp6"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "vp6"));
|
||||
}
|
||||
if (M.tracks[*it].codec == "ScreenVideo1"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 3, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "sv1"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "sv1"));
|
||||
}
|
||||
if (M.tracks[*it].codec == "H263"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 2, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "h263"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "h263"));
|
||||
}
|
||||
if (M.tracks[*it].codec == "JPEG"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 1, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "jpeg"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "jpeg"));
|
||||
}
|
||||
amfdata.getContentP(1)->addContent(
|
||||
AMF::Object("width", M.tracks[*it].width, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(
|
||||
AMF::Object("height", M.tracks[*it].height, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("width", M.tracks[*it].width, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("height", M.tracks[*it].height, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(
|
||||
AMF::Object("videoframerate", (double)M.tracks[*it].fpks / 1000.0, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(
|
||||
|
@ -557,30 +546,23 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Meta &M, std::set<long unsigned int> &selTrack
|
|||
}
|
||||
if (M.tracks[*it].type == "audio"){
|
||||
trinfo.addContent(AMF::Object("", AMF::AMF0_OBJECT));
|
||||
trinfo.getContentP(i)->addContent(
|
||||
AMF::Object("length", ((double)M.tracks[*it].lastms) * ((double)M.tracks[*it].rate),
|
||||
AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->addContent(
|
||||
AMF::Object("timescale", M.tracks[*it].rate, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->addContent(AMF::Object(
|
||||
"length", ((double)M.tracks[*it].lastms) * ((double)M.tracks[*it].rate), AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->addContent(AMF::Object("timescale", M.tracks[*it].rate, AMF::AMF0_NUMBER));
|
||||
trinfo.getContentP(i)->addContent(AMF::Object("sampledescription", AMF::AMF0_STRICT_ARRAY));
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("hasAudio", 1, AMF::AMF0_BOOL));
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("audiodelay", 0.0, AMF::AMF0_NUMBER));
|
||||
if (M.tracks[*it].codec == "AAC"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("audiocodecid", (std::string) "mp4a"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "mp4a"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "mp4a"));
|
||||
}
|
||||
if (M.tracks[*it].codec == "MP3"){
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("audiocodecid", (std::string) "mp3"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(
|
||||
AMF::Object("sampletype", (std::string) "mp3"));
|
||||
trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string) "mp3"));
|
||||
}
|
||||
amfdata.getContentP(1)->addContent(
|
||||
AMF::Object("audiochannels", M.tracks[*it].channels, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(
|
||||
AMF::Object("audiosamplerate", M.tracks[*it].rate, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(
|
||||
AMF::Object("audiosamplesize", M.tracks[*it].size, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("audiochannels", M.tracks[*it].channels, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("audiosamplerate", M.tracks[*it].rate, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(AMF::Object("audiosamplesize", M.tracks[*it].size, AMF::AMF0_NUMBER));
|
||||
amfdata.getContentP(1)->addContent(
|
||||
AMF::Object("audiodatarate", (double)M.tracks[*it].bps / 128.0, AMF::AMF0_NUMBER));
|
||||
++i;
|
||||
|
@ -836,20 +818,17 @@ void FLV::Tag::toMeta(DTSC::Meta &metadata, AMF::Object &amf_storage, unsigned i
|
|||
if (data[0] == 0x12){
|
||||
AMF::Object meta_in = AMF::parse((unsigned char *)data + 11, len - 15);
|
||||
AMF::Object *tmp = 0;
|
||||
if (meta_in.getContentP(1) && meta_in.getContentP(0) &&
|
||||
(meta_in.getContentP(0)->StrValue() == "onMetaData")){
|
||||
if (meta_in.getContentP(1) && meta_in.getContentP(0) && (meta_in.getContentP(0)->StrValue() == "onMetaData")){
|
||||
tmp = meta_in.getContentP(1);
|
||||
}else{
|
||||
if (meta_in.getContentP(2) && meta_in.getContentP(1) &&
|
||||
(meta_in.getContentP(1)->StrValue() == "onMetaData")){
|
||||
if (meta_in.getContentP(2) && meta_in.getContentP(1) && (meta_in.getContentP(1)->StrValue() == "onMetaData")){
|
||||
tmp = meta_in.getContentP(2);
|
||||
}
|
||||
}
|
||||
if (tmp){amf_storage = *tmp;}
|
||||
return;
|
||||
}
|
||||
if (data[0] == 0x08 &&
|
||||
(metadata.tracks[reTrack].codec == "" || metadata.tracks[reTrack].codec != getAudioCodec() ||
|
||||
if (data[0] == 0x08 && (metadata.tracks[reTrack].codec == "" || metadata.tracks[reTrack].codec != getAudioCodec() ||
|
||||
(needsInitData() && isInitData()))){
|
||||
char audiodata = data[11];
|
||||
metadata.tracks[reTrack].trackID = reTrack;
|
||||
|
@ -863,16 +842,14 @@ void FLV::Tag::toMeta(DTSC::Meta &metadata, AMF::Object &amf_storage, unsigned i
|
|||
case 0xC: metadata.tracks[reTrack].rate = 44100; break;
|
||||
}
|
||||
if (amf_storage.getContentP("audiosamplerate")){
|
||||
metadata.tracks[reTrack].rate =
|
||||
(long long int)amf_storage.getContentP("audiosamplerate")->NumValue();
|
||||
metadata.tracks[reTrack].rate = (long long int)amf_storage.getContentP("audiosamplerate")->NumValue();
|
||||
}
|
||||
switch (audiodata & 0x02){
|
||||
case 0x0: metadata.tracks[reTrack].size = 8; break;
|
||||
case 0x2: metadata.tracks[reTrack].size = 16; break;
|
||||
}
|
||||
if (amf_storage.getContentP("audiosamplesize")){
|
||||
metadata.tracks[reTrack].size =
|
||||
(long long int)amf_storage.getContentP("audiosamplesize")->NumValue();
|
||||
metadata.tracks[reTrack].size = (long long int)amf_storage.getContentP("audiosamplesize")->NumValue();
|
||||
}
|
||||
switch (audiodata & 0x01){
|
||||
case 0x0: metadata.tracks[reTrack].channels = 1; break;
|
||||
|
@ -898,8 +875,7 @@ void FLV::Tag::toMeta(DTSC::Meta &metadata, AMF::Object &amf_storage, unsigned i
|
|||
}
|
||||
}
|
||||
|
||||
if (data[0] == 0x09 &&
|
||||
((needsInitData() && isInitData()) || !metadata.tracks[reTrack].codec.size())){
|
||||
if (data[0] == 0x09 && ((needsInitData() && isInitData()) || !metadata.tracks[reTrack].codec.size())){
|
||||
char videodata = data[11];
|
||||
metadata.tracks[reTrack].codec = getVideoCodec();
|
||||
metadata.tracks[reTrack].type = "video";
|
||||
|
@ -908,8 +884,7 @@ void FLV::Tag::toMeta(DTSC::Meta &metadata, AMF::Object &amf_storage, unsigned i
|
|||
metadata.tracks[reTrack].width = (long long int)amf_storage.getContentP("width")->NumValue();
|
||||
}
|
||||
if (amf_storage.getContentP("height")){
|
||||
metadata.tracks[reTrack].height =
|
||||
(long long int)amf_storage.getContentP("height")->NumValue();
|
||||
metadata.tracks[reTrack].height = (long long int)amf_storage.getContentP("height")->NumValue();
|
||||
}
|
||||
if (!metadata.tracks[reTrack].fpks && amf_storage.getContentP("videoframerate")){
|
||||
if (amf_storage.getContentP("videoframerate")->NumValue()){
|
||||
|
@ -960,4 +935,3 @@ bool FLV::Tag::checkBufferSize(){
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,7 @@ namespace FLV{
|
|||
extern char Header[13]; ///< Holds the last FLV header parsed.
|
||||
extern bool Parse_Error; ///< This variable is set to true if a problem is encountered while
|
||||
///< parsing the FLV.
|
||||
extern std::string
|
||||
Error_Str; ///< This variable is set if a problem is encountered while parsing the FLV.
|
||||
extern std::string Error_Str; ///< This variable is set if a problem is encountered while parsing the FLV.
|
||||
|
||||
// functions
|
||||
bool check_header(char *header); ///< Checks a FLV Header for validness.
|
||||
|
@ -45,8 +44,7 @@ namespace FLV{
|
|||
void offset(int64_t o);
|
||||
Tag(); ///< Constructor for a new, empty, tag.
|
||||
Tag(const Tag &O); ///< Copy constructor, copies the contents of an existing tag.
|
||||
Tag &
|
||||
operator=(const Tag &O); ///< Assignment operator - works exactly like the copy constructor.
|
||||
Tag &operator=(const Tag &O); ///< Assignment operator - works exactly like the copy constructor.
|
||||
Tag(const RTMPStream::Chunk &O); ///< Copy constructor from a RTMP chunk.
|
||||
~Tag(); ///< Generic destructor.
|
||||
// loader functions
|
||||
|
@ -76,4 +74,3 @@ namespace FLV{
|
|||
// Tag
|
||||
|
||||
}// namespace FLV
|
||||
|
||||
|
|
79
lib/h264.cpp
79
lib/h264.cpp
|
@ -1,10 +1,10 @@
|
|||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include "h264.h"
|
||||
#include "bitfields.h"
|
||||
#include "bitstream.h"
|
||||
#include "defines.h"
|
||||
#include "h264.h"
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
|
@ -93,8 +93,7 @@ namespace h264{
|
|||
// Fill the bitstream
|
||||
Utils::bitstream bs;
|
||||
for (size_t i = 1; i < dataLen; i++){
|
||||
if (i + 2 < dataLen &&
|
||||
(memcmp(data + i, "\000\000\003", 3) == 0)){// Emulation prevention bytes
|
||||
if (i + 2 < dataLen && (memcmp(data + i, "\000\000\003", 3) == 0)){// Emulation prevention bytes
|
||||
// Yes, we increase i here
|
||||
bs.append(data + i, 2);
|
||||
i += 2;
|
||||
|
@ -111,8 +110,7 @@ namespace h264{
|
|||
result.level = bs.get(8);
|
||||
bs.getUExpGolomb();
|
||||
if (profileIdc == 100 || profileIdc == 110 || profileIdc == 122 || profileIdc == 244 ||
|
||||
profileIdc == 44 || profileIdc == 83 || profileIdc == 86 || profileIdc == 118 ||
|
||||
profileIdc == 128){
|
||||
profileIdc == 44 || profileIdc == 83 || profileIdc == 86 || profileIdc == 118 || profileIdc == 128){
|
||||
// chroma format idc
|
||||
char chromaFormatIdc = bs.getUExpGolomb();
|
||||
if (chromaFormatIdc == 3){result.sep_col_plane = (bs.get(1) == 1);}
|
||||
|
@ -260,7 +258,6 @@ namespace h264{
|
|||
result.width = ((result.width * sar_width) / sar_height);
|
||||
}else{
|
||||
result.height = ((result.height * sar_height) / sar_width);
|
||||
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -351,8 +348,7 @@ namespace h264{
|
|||
bitDepthChromaMinus8 = bs.getUExpGolomb();
|
||||
derived_bitDepth_C = 8 + bitDepthChromaMinus8;
|
||||
derived_qpBdOffset_C = 6 * bitDepthChromaMinus8;
|
||||
derived_rawMbBits =
|
||||
256 * derived_bitDepth_Y + 2 * derived_mbWidthC * derived_mbHeightC * derived_bitDepth_C;
|
||||
derived_rawMbBits = 256 * derived_bitDepth_Y + 2 * derived_mbWidthC * derived_mbHeightC * derived_bitDepth_C;
|
||||
qpprimeYZeroTransformBypassFlag = bs.get(1);
|
||||
seqScalingMatrixPresentFlag = bs.get(1);
|
||||
if (seqScalingMatrixPresentFlag){
|
||||
|
@ -361,8 +357,7 @@ namespace h264{
|
|||
|
||||
derived_scalingList4x4Amount = 6;
|
||||
scalingList4x4 = (uint64_t **)malloc(derived_scalingList4x4Amount * sizeof(uint64_t *));
|
||||
useDefaultScalingMatrix4x4Flag =
|
||||
(bool *)malloc(derived_scalingList4x4Amount * sizeof(bool));
|
||||
useDefaultScalingMatrix4x4Flag = (bool *)malloc(derived_scalingList4x4Amount * sizeof(bool));
|
||||
for (int i = 0; i < derived_scalingList4x4Amount; i++){
|
||||
scalingList4x4[i] = NULL;
|
||||
useDefaultScalingMatrix4x4Flag[i] = false;
|
||||
|
@ -370,8 +365,7 @@ namespace h264{
|
|||
|
||||
derived_scalingList8x8Amount = derived_scalingListSize - 6;
|
||||
scalingList8x8 = (uint64_t **)malloc(derived_scalingList8x8Amount * sizeof(uint64_t *));
|
||||
useDefaultScalingMatrix8x8Flag =
|
||||
(bool *)malloc(derived_scalingList8x8Amount * sizeof(bool));
|
||||
useDefaultScalingMatrix8x8Flag = (bool *)malloc(derived_scalingList8x8Amount * sizeof(bool));
|
||||
for (int i = 0; i < derived_scalingList8x8Amount; i++){
|
||||
scalingList8x8[i] = NULL;
|
||||
useDefaultScalingMatrix8x8Flag[i] = false;
|
||||
|
@ -472,8 +466,7 @@ namespace h264{
|
|||
out << " -> RawMbBits: " << derived_rawMbBits << std::endl;
|
||||
out << " qpprime_y_zero-transform_bypass_flag: " << (qpprimeYZeroTransformBypassFlag ? 1 : 0)
|
||||
<< std::endl;
|
||||
out << " seq_scaling_matrix_present_flag: " << (seqScalingMatrixPresentFlag ? 1 : 0)
|
||||
<< std::endl;
|
||||
out << " seq_scaling_matrix_present_flag: " << (seqScalingMatrixPresentFlag ? 1 : 0) << std::endl;
|
||||
if (seqScalingMatrixPresentFlag){
|
||||
for (int i = 0; i < derived_scalingListSize; i++){
|
||||
out << " seq_scaling_list_present_flag[" << i
|
||||
|
@ -503,16 +496,14 @@ namespace h264{
|
|||
out << " log2_max_frame_num_minus4: " << log2MaxFrameNumMinus4
|
||||
<< (log2MaxFrameNumMinus4 >= 13 ? " INVALID" : "") << std::endl;
|
||||
out << " -> MaxFrameNum: " << derived_maxFrameNum << std::endl;
|
||||
out << " pic_order_cnt_type: " << picOrderCntType << (picOrderCntType >= 3 ? " INVALID" : "")
|
||||
<< std::endl;
|
||||
out << " pic_order_cnt_type: " << picOrderCntType << (picOrderCntType >= 3 ? " INVALID" : "") << std::endl;
|
||||
if (!picOrderCntType){
|
||||
out << " log2_max_pic_order_cnt_lsb_minus4: " << log2MaxPicOrderCntLsbMinus4
|
||||
<< (log2MaxPicOrderCntLsbMinus4 >= 13 ? " INVALID" : "") << std::endl;
|
||||
out << " -> MaxPicOrderCntLsb: " << derived_maxPicOrderCntLsb << std::endl;
|
||||
}
|
||||
out << " max_num_ref_frames: " << maxNumRefFrames << std::endl;
|
||||
out << " gaps_in_frame_num_value_allowed_flag: " << (gapsInFrameNumValueAllowedFlag ? 1 : 0)
|
||||
<< std::endl;
|
||||
out << " gaps_in_frame_num_value_allowed_flag: " << (gapsInFrameNumValueAllowedFlag ? 1 : 0) << std::endl;
|
||||
out << " pic_width_in_mbs_minus_1: " << picWidthInMbsMinus1 << std::endl;
|
||||
out << " -> PicWidthInMbs: " << derived_picWidthInMbs << std::endl;
|
||||
out << " -> PicWidthInSamples_L: " << derived_picWidthInSamples_L << std::endl;
|
||||
|
@ -725,17 +716,14 @@ namespace h264{
|
|||
<< (bottomFieldPicOrderInFramePresentFlag ? 1 : 0) << std::endl;
|
||||
out << " num_slice_groups_minus1: " << numSliceGroupsMinus1 << std::endl;
|
||||
if (numSliceGroupsMinus1 > 0){return;}
|
||||
out << " num_ref_idx_10_default_active_minus1: " << numrefIdx10DefaultActiveMinus1
|
||||
<< std::endl;
|
||||
out << " num_ref_idx_11_default_active_minus1: " << numrefIdx11DefaultActiveMinus1
|
||||
<< std::endl;
|
||||
out << " num_ref_idx_10_default_active_minus1: " << numrefIdx10DefaultActiveMinus1 << std::endl;
|
||||
out << " num_ref_idx_11_default_active_minus1: " << numrefIdx11DefaultActiveMinus1 << std::endl;
|
||||
out << " weighted_pred_flag: " << (weightedPredFlag ? 1 : 0) << std::endl;
|
||||
out << " weighted_bipred_idc: " << (uint32_t)weightedBipredIdc << std::endl;
|
||||
out << " pic_init_qp_minus26: " << picInitQpMinus26 << std::endl;
|
||||
out << " pic_init_qs_minus26: " << picInitQsMinus26 << std::endl;
|
||||
out << " chroma_qp_index_offset: " << chromaQpIndexOffset << std::endl;
|
||||
out << " deblocking_filter_control_present_flag: " << deblockingFilterControlPresentFlag
|
||||
<< std::endl;
|
||||
out << " deblocking_filter_control_present_flag: " << deblockingFilterControlPresentFlag << std::endl;
|
||||
out << " constrained_intra_pred_flag: " << constrainedIntraPredFlag << std::endl;
|
||||
out << " redundant_pic_cnt_present_flag: " << redundantPicCntPresentFlag << std::endl;
|
||||
if (status_moreRBSP){
|
||||
|
@ -848,8 +836,7 @@ namespace h264{
|
|||
payload[1 + byteOffset] |= (0x08 >> bitOffset);
|
||||
payload[2 + byteOffset] &= secondBitmask;
|
||||
payload[2 + byteOffset] |= (0x08 << (8 - bitOffset));
|
||||
INFO_MSG("Translated %.2X to %.2X %.2X", toCopy, payload[1 + byteOffset],
|
||||
payload[2 + byteOffset]);
|
||||
INFO_MSG("Translated %.2X to %.2X %.2X", toCopy, payload[1 + byteOffset], payload[2 + byteOffset]);
|
||||
}
|
||||
|
||||
void codedSliceUnit::toPrettyString(std::ostream &out){
|
||||
|
@ -922,12 +909,10 @@ namespace h264{
|
|||
uuid.str("x264 encoder configuration");
|
||||
}
|
||||
out << " UUID: " << uuid.str() << std::endl;
|
||||
out << " Payload: " << std::string(payload.data() + payloadOffset + 16, payloadSize - 17)
|
||||
<< std::endl;
|
||||
out << " Payload: " << std::string(payload.data() + payloadOffset + 16, payloadSize - 17) << std::endl;
|
||||
}break;
|
||||
default:
|
||||
out << " Message of type " << payloadType << ", " << payloadSize << " bytes long"
|
||||
<< std::endl;
|
||||
out << " Message of type " << payloadType << ", " << payloadSize << " bytes long" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1149,8 +1134,7 @@ namespace h264{
|
|||
out << std::string(indent + 2, ' ')
|
||||
<< "aspect_ratio_info_present_flag: " << aspectRatioInfoPresentFlag << std::endl;
|
||||
if (aspectRatioInfoPresentFlag){
|
||||
out << std::string(indent + 2, ' ') << "aspect_ratio_idc: " << (int32_t)aspectRatioIdc
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "aspect_ratio_idc: " << (int32_t)aspectRatioIdc << std::endl;
|
||||
if (aspectRatioIdc == 255){
|
||||
out << std::string(indent + 2, ' ') << "sar_width: " << sarWidth << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "sar_height: " << sarHeight << std::endl;
|
||||
|
@ -1166,16 +1150,14 @@ namespace h264{
|
|||
<< "video_signal_type_present_flag: " << videoSignalTypePresentFlag << std::endl;
|
||||
if (videoSignalTypePresentFlag){
|
||||
out << std::string(indent + 2, ' ') << "video_format" << videoFormat << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "video_full_range_flag" << videoFullRangeFlag
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "video_full_range_flag" << videoFullRangeFlag << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "colour_description_present_flag"
|
||||
<< colourDescriptionPresentFlag << std::endl;
|
||||
if (colourDescriptionPresentFlag){
|
||||
out << std::string(indent + 2, ' ') << "colour_primaries" << colourPrimaries << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "transfer_characteristics" << transferCharacteristics
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "matrix_coefficients" << matrixCoefficients
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "matrix_coefficients" << matrixCoefficients << std::endl;
|
||||
}
|
||||
}
|
||||
out << std::string(indent + 2, ' ')
|
||||
|
@ -1186,13 +1168,11 @@ namespace h264{
|
|||
out << std::string(indent + 2, ' ') << "chroma_sample_loc_type_bottom_field"
|
||||
<< chromaSampleLocTypeBottomField << std::endl;
|
||||
}
|
||||
out << std::string(indent + 2, ' ') << "timing_info_present_flag: " << timingInfoPresentFlag
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "timing_info_present_flag: " << timingInfoPresentFlag << std::endl;
|
||||
if (timingInfoPresentFlag){
|
||||
out << std::string(indent + 2, ' ') << "num_units_in_tick: " << numUnitsInTick << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "time_scale: " << timeScale << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "fixed_frame_rate_flag: " << fixedFrameRateFlag
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "fixed_frame_rate_flag: " << fixedFrameRateFlag << std::endl;
|
||||
}
|
||||
out << std::string(indent + 2, ' ')
|
||||
<< "nal_hrd_parameters_present_flag: " << nalHrdParametersPresentFlag << std::endl;
|
||||
|
@ -1202,27 +1182,20 @@ namespace h264{
|
|||
if (nalHrdParametersPresentFlag || vclHrdParametersPresentFlag){
|
||||
out << std::string(indent + 2, ' ') << "low_delay_hrd_flag: " << lowDelayHrdFlag << std::endl;
|
||||
}
|
||||
out << std::string(indent + 2, ' ') << "pic_struct_present_flag: " << picStructPresentFlag
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "pic_struct_present_flag: " << picStructPresentFlag << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "bitstream_restiction_flag: " << bitstreamRestrictionFlag
|
||||
<< std::endl;
|
||||
if (bitstreamRestrictionFlag){
|
||||
out << std::string(indent + 2, ' ')
|
||||
<< "motion_vectors_over_pic_boundaries_flag: " << motionVectorsOverPicBoundariesFlag
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "max_bytes_per_pic_denom: " << maxBytesPerPicDenom
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "max_bits_per_mb_denom: " << maxBitsPerMbDenom
|
||||
<< std::endl;
|
||||
<< "motion_vectors_over_pic_boundaries_flag: " << motionVectorsOverPicBoundariesFlag << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "max_bytes_per_pic_denom: " << maxBytesPerPicDenom << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "max_bits_per_mb_denom: " << maxBitsPerMbDenom << std::endl;
|
||||
out << std::string(indent + 2, ' ')
|
||||
<< "log2_max_mv_length_horizontal: " << log2MaxMvLengthHorizontal << std::endl;
|
||||
out << std::string(indent + 2, ' ')
|
||||
<< "log2_max_mv_length_vertical: " << log2MaxMvLengthVertical << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "num_reorder_frames: " << numReorderFrames
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "max_dec_frame_buffering: " << maxDecFrameBuffering
|
||||
<< std::endl;
|
||||
out << std::string(indent + 2, ' ') << "num_reorder_frames: " << numReorderFrames << std::endl;
|
||||
out << std::string(indent + 2, ' ') << "max_dec_frame_buffering: " << maxDecFrameBuffering << std::endl;
|
||||
}
|
||||
}
|
||||
}// namespace h264
|
||||
|
||||
|
|
|
@ -303,4 +303,3 @@ namespace h264{
|
|||
nalUnit *nalFactory(FILE *in, bool annexb = true);
|
||||
nalUnit *nalFactory(const char *data, size_t len, size_t &offset, bool annexb = true);
|
||||
}// namespace h264
|
||||
|
||||
|
|
129
lib/h265.cpp
129
lib/h265.cpp
|
@ -1,6 +1,6 @@
|
|||
#include "h265.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
#include "h265.h"
|
||||
|
||||
namespace h265{
|
||||
const char *typeToStr(uint8_t type){
|
||||
|
@ -64,8 +64,7 @@ namespace h265{
|
|||
hvccBox.setPayload(hvccData);
|
||||
std::deque<MP4::HVCCArrayEntry> arrays = hvccBox.getArrays();
|
||||
for (std::deque<MP4::HVCCArrayEntry>::iterator it = arrays.begin(); it != arrays.end(); it++){
|
||||
for (std::deque<std::string>::iterator nalIt = it->nalUnits.begin();
|
||||
nalIt != it->nalUnits.end(); nalIt++){
|
||||
for (std::deque<std::string>::iterator nalIt = it->nalUnits.begin(); nalIt != it->nalUnits.end(); nalIt++){
|
||||
nalUnits[it->nalUnitType].insert(*nalIt);
|
||||
}
|
||||
}
|
||||
|
@ -156,8 +155,7 @@ namespace h265{
|
|||
|
||||
metaInfo initData::getMeta(){
|
||||
metaInfo res;
|
||||
if (!nalUnits.count(33)){
|
||||
return res;}
|
||||
if (!nalUnits.count(33)){return res;}
|
||||
spsUnit sps(*nalUnits[33].begin());
|
||||
sps.getMeta(res);
|
||||
return res;
|
||||
|
@ -195,8 +193,7 @@ namespace h265{
|
|||
}
|
||||
}
|
||||
|
||||
std::string printProfileTierLevel(Utils::bitstream &bs, unsigned int maxSubLayersMinus1,
|
||||
size_t indent){
|
||||
std::string printProfileTierLevel(Utils::bitstream &bs, unsigned int maxSubLayersMinus1, size_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "general_profile_space: " << bs.get(2) << std::endl;
|
||||
r << std::string(indent, ' ') << "general_tier_flag: " << bs.get(1) << std::endl;
|
||||
|
@ -205,10 +202,8 @@ namespace h265{
|
|||
<< bs.get(32) << std::dec << std::endl;
|
||||
r << std::string(indent, ' ') << "general_progressive_source_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "general_interlaced_source_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "general_non_packed_constraint_flag: " << bs.get(1)
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "general_frame_only_constraint_flag: " << bs.get(1)
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "general_non_packed_constraint_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "general_frame_only_constraint_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "general_reserved_zero_44bits: " << bs.get(44) << std::endl;
|
||||
r << std::string(indent, ' ') << "general_level_idc: " << bs.get(8) << std::endl;
|
||||
std::deque<bool> profilePresent;
|
||||
|
@ -226,8 +221,7 @@ namespace h265{
|
|||
|
||||
if (maxSubLayersMinus1){
|
||||
for (int i = maxSubLayersMinus1; i < 8; i++){
|
||||
r << std::string(indent + 1, ' ') << "reserved_zero_2_bits[" << i << "]: " << bs.get(2)
|
||||
<< std::endl;
|
||||
r << std::string(indent + 1, ' ') << "reserved_zero_2_bits[" << i << "]: " << bs.get(2) << std::endl;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < maxSubLayersMinus1; i++){
|
||||
|
@ -238,16 +232,11 @@ namespace h265{
|
|||
r << std::string(indent + 2, ' ') << "sub_layer_profile_idc: " << bs.get(5) << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_profile_compatibility_flags: " << std::hex
|
||||
<< bs.get(32) << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_progressive_source_flag: " << bs.get(1)
|
||||
<< std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_interlaced_source_flag: " << bs.get(1)
|
||||
<< std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_non_packed_constraint_flag: " << bs.get(1)
|
||||
<< std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_frame_only_constraint_flag: " << bs.get(1)
|
||||
<< std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_reserved_zero_44bits: " << bs.get(44)
|
||||
<< std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_progressive_source_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_interlaced_source_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_non_packed_constraint_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_frame_only_constraint_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_reserved_zero_44bits: " << bs.get(44) << std::endl;
|
||||
}
|
||||
if (levelPresent[i]){
|
||||
r << std::string(indent + 2, ' ') << "sub_layer_level_idc: " << bs.get(8) << std::endl;
|
||||
|
@ -256,17 +245,13 @@ namespace h265{
|
|||
return r.str();
|
||||
}
|
||||
|
||||
void updateProfileTierLevel(Utils::bitstream &bs, MP4::HVCC &hvccBox,
|
||||
unsigned int maxSubLayersMinus1){
|
||||
void updateProfileTierLevel(Utils::bitstream &bs, MP4::HVCC &hvccBox, unsigned int maxSubLayersMinus1){
|
||||
hvccBox.setGeneralProfileSpace(bs.get(2));
|
||||
|
||||
unsigned int tierFlag = bs.get(1);
|
||||
hvccBox.setGeneralProfileIdc(
|
||||
std::max((unsigned long long)hvccBox.getGeneralProfileIdc(), bs.get(5)));
|
||||
hvccBox.setGeneralProfileCompatibilityFlags(hvccBox.getGeneralProfileCompatibilityFlags() &
|
||||
bs.get(32));
|
||||
hvccBox.setGeneralConstraintIndicatorFlags(hvccBox.getGeneralConstraintIndicatorFlags() &
|
||||
bs.get(48));
|
||||
hvccBox.setGeneralProfileIdc(std::max((unsigned long long)hvccBox.getGeneralProfileIdc(), bs.get(5)));
|
||||
hvccBox.setGeneralProfileCompatibilityFlags(hvccBox.getGeneralProfileCompatibilityFlags() & bs.get(32));
|
||||
hvccBox.setGeneralConstraintIndicatorFlags(hvccBox.getGeneralConstraintIndicatorFlags() & bs.get(48));
|
||||
unsigned int levelIdc = bs.get(8);
|
||||
|
||||
if (tierFlag && !hvccBox.getGeneralTierFlag()){
|
||||
|
@ -309,8 +294,7 @@ namespace h265{
|
|||
|
||||
unsigned int maxSubLayers = bs.get(3) + 1;
|
||||
|
||||
hvccBox.setNumberOfTemporalLayers(
|
||||
std::max((unsigned int)hvccBox.getNumberOfTemporalLayers(), maxSubLayers));
|
||||
hvccBox.setNumberOfTemporalLayers(std::max((unsigned int)hvccBox.getNumberOfTemporalLayers(), maxSubLayers));
|
||||
|
||||
bs.skip(17);
|
||||
|
||||
|
@ -326,8 +310,7 @@ namespace h265{
|
|||
r << std::string(indent, ' ') << "vps_reserved_three_2bits: " << bs.get(2) << std::endl;
|
||||
r << std::string(indent, ' ') << "vps_max_layers_minus1: " << bs.get(6) << std::endl;
|
||||
unsigned int maxSubLayersMinus1 = bs.get(3);
|
||||
r << std::string(indent, ' ') << "vps_max_sub_layers_minus1: " << maxSubLayersMinus1
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "vps_max_sub_layers_minus1: " << maxSubLayersMinus1 << std::endl;
|
||||
r << std::string(indent, ' ') << "vps_temporal_id_nesting_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "vps_reserved_0xffff_16bits: " << std::hex << bs.get(16)
|
||||
<< std::dec << std::endl;
|
||||
|
@ -347,8 +330,7 @@ namespace h265{
|
|||
unsigned int vps_max_layer_id = bs.get(6);
|
||||
uint64_t vps_num_layer_sets_minus1 = bs.getUExpGolomb();
|
||||
r << std::string(indent, ' ') << "vps_max_layer_id: " << vps_max_layer_id << std::endl;
|
||||
r << std::string(indent, ' ') << "vps_num_layer_sets_minus1: " << vps_num_layer_sets_minus1
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "vps_num_layer_sets_minus1: " << vps_num_layer_sets_minus1 << std::endl;
|
||||
for (int i = 1; i <= vps_num_layer_sets_minus1; i++){
|
||||
for (int j = 0; j < vps_max_layer_id; j++){
|
||||
r << std::string(indent, ' ') << "layer_id_included_flag[" << i << "][" << j
|
||||
|
@ -356,8 +338,7 @@ namespace h265{
|
|||
}
|
||||
}
|
||||
bool vps_timing_info = bs.get(1);
|
||||
r << std::string(indent, ' ') << "vps_timing_info_present_flag: " << (vps_timing_info ? 1 : 0)
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "vps_timing_info_present_flag: " << (vps_timing_info ? 1 : 0) << std::endl;
|
||||
|
||||
return r.str();
|
||||
}
|
||||
|
@ -420,15 +401,14 @@ namespace h265{
|
|||
deltaIdxMinus1 = bs.getUExpGolomb();
|
||||
r << std::string(indent, ' ') << "delta_idx_minus_1: " << deltaIdxMinus1 << std::endl;
|
||||
}
|
||||
r << std::string(indent, ' ')
|
||||
<< "delta_rps_sign: " << (int)bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ')
|
||||
<< "abs_delta_rps_minus1: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "delta_rps_sign: " << (int)bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "abs_delta_rps_minus1: " << bs.getUExpGolomb() << std::endl;
|
||||
uint64_t refRpsIdx = idx - deltaIdxMinus1 - 1;
|
||||
uint64_t deltaPocs = negativePics[refRpsIdx] + positivePics[refRpsIdx];
|
||||
for (int j = 0; j < deltaPocs; j++){
|
||||
bool usedByCurrPicFlag = bs.get(1);
|
||||
r << std::string(indent + 1, ' ') << "used_by_curr_pic_flag[" << j << "]: " << usedByCurrPicFlag << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "used_by_curr_pic_flag[" << j
|
||||
<< "]: " << usedByCurrPicFlag << std::endl;
|
||||
if (!usedByCurrPicFlag){
|
||||
r << std::string(indent + 1, ' ') << "used_delta_flag[" << j << "]: " << bs.get(1) << std::endl;
|
||||
}
|
||||
|
@ -492,8 +472,7 @@ namespace h265{
|
|||
std::string printVuiParameters(Utils::bitstream &bs, size_t indent){
|
||||
std::stringstream r;
|
||||
bool aspectRatio = bs.get(1);
|
||||
r << std::string(indent, ' ') << "aspect_ratio_info_present_flag: " << (aspectRatio ? 1 : 0)
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "aspect_ratio_info_present_flag: " << (aspectRatio ? 1 : 0) << std::endl;
|
||||
if (aspectRatio){
|
||||
uint16_t aspectRatioIdc = bs.get(8);
|
||||
r << std::string(indent, ' ') << "aspect_ratio_idc: " << aspectRatioIdc << std::endl;
|
||||
|
@ -595,39 +574,29 @@ namespace h265{
|
|||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "sps_video_parameter_set_id: " << bs.get(4) << std::endl;
|
||||
unsigned int maxSubLayersMinus1 = bs.get(3);
|
||||
r << std::string(indent, ' ') << "sps_max_sub_layers_minus1: " << maxSubLayersMinus1
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "sps_max_sub_layers_minus1: " << maxSubLayersMinus1 << std::endl;
|
||||
r << std::string(indent, ' ') << "sps_temporal_id_nesting_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "profile_tier_level(): " << std::endl
|
||||
<< printProfileTierLevel(bs, maxSubLayersMinus1, indent + 1);
|
||||
r << std::string(indent, ' ') << "sps_seq_parameter_set_id: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "sps_seq_parameter_set_id: " << bs.getUExpGolomb() << std::endl;
|
||||
uint64_t chromaFormatIdc = bs.getUExpGolomb();
|
||||
r << std::string(indent, ' ') << "chroma_format_idc: " << chromaFormatIdc << std::endl;
|
||||
if (chromaFormatIdc == 3){
|
||||
r << std::string(indent, ' ') << "separate_colour_plane_flag: " << bs.get(1) << std::endl;
|
||||
}
|
||||
r << std::string(indent, ' ') << "pic_width_in_luma_samples: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "pic_height_in_luma_samples: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "pic_width_in_luma_samples: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "pic_height_in_luma_samples: " << bs.getUExpGolomb() << std::endl;
|
||||
bool conformance_window_flag = bs.get(1);
|
||||
r << std::string(indent, ' ') << "conformance_window_flag: " << conformance_window_flag
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "conformance_window_flag: " << conformance_window_flag << std::endl;
|
||||
if (conformance_window_flag){
|
||||
r << std::string(indent, ' ') << "conf_window_left_offset: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "conf_window_right_offset: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "conf_window_top_offset: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "conf_window_bottom_offset: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "conf_window_left_offset: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "conf_window_right_offset: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "conf_window_top_offset: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "conf_window_bottom_offset: " << bs.getUExpGolomb() << std::endl;
|
||||
}
|
||||
r << std::string(indent, ' ') << "bit_depth_luma_minus8: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "bit_depth_chroma_minus8: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "log2_max_pic_order_cnt_lsb_minus4: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "log2_max_pic_order_cnt_lsb_minus4: " << bs.getUExpGolomb() << std::endl;
|
||||
bool subLayerOrdering = bs.get(1);
|
||||
r << std::string(indent, ' ')
|
||||
<< "sps_sub_layer_ordering_info_present_flag: " << subLayerOrdering << std::endl;
|
||||
|
@ -647,23 +616,18 @@ namespace h265{
|
|||
<< std::endl;
|
||||
r << std::string(indent, ' ')
|
||||
<< "log2_diff_max_min_transform_block_size: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "max_transform_hierarchy_depth_inter: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "max_transform_hierarchy_depth_intra: " << bs.getUExpGolomb()
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "max_transform_hierarchy_depth_inter: " << bs.getUExpGolomb() << std::endl;
|
||||
r << std::string(indent, ' ') << "max_transform_hierarchy_depth_intra: " << bs.getUExpGolomb() << std::endl;
|
||||
bool scalingListEnabled = bs.get(1);
|
||||
r << std::string(indent, ' ') << "scaling_list_enabled_flag: " << scalingListEnabled
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "scaling_list_enabled_flag: " << scalingListEnabled << std::endl;
|
||||
if (scalingListEnabled){WARN_MSG("Not implemented scaling list in HEVC sps");}
|
||||
r << std::string(indent, ' ') << "amp_enabled_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "sample_adaptive_offset_enabled_flag: " << bs.get(1)
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "sample_adaptive_offset_enabled_flag: " << bs.get(1) << std::endl;
|
||||
bool pcmEnabled = bs.get(1);
|
||||
r << std::string(indent, ' ') << "pcm_enabled_flag: " << pcmEnabled << std::endl;
|
||||
if (pcmEnabled){WARN_MSG("Not implemented pcm_enabled in HEVC sps");}
|
||||
uint64_t shortTermPicSets = bs.getUExpGolomb();
|
||||
r << std::string(indent, ' ') << "num_short_term_ref_pic_sets: " << shortTermPicSets
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "num_short_term_ref_pic_sets: " << shortTermPicSets << std::endl;
|
||||
for (int i = 0; i < shortTermPicSets; i++){
|
||||
r << std::string(indent, ' ') << "short_term_ref_pic_set(" << i << "):" << std::endl
|
||||
<< printShortTermRefPicSet(bs, i, shortTermPicSets, indent + 1);
|
||||
|
@ -673,12 +637,10 @@ namespace h265{
|
|||
<< "long_term_ref_pics_present_flag: " << (longTermRefPics ? 1 : 0) << std::endl;
|
||||
if (longTermRefPics){WARN_MSG("Implement longTermRefPics");}
|
||||
r << std::string(indent, ' ') << "sps_temporal_mvp_enabled_flag: " << bs.get(1) << std::endl;
|
||||
r << std::string(indent, ' ') << "strong_intra_smoothing_enabled_flag: " << bs.get(1)
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "strong_intra_smoothing_enabled_flag: " << bs.get(1) << std::endl;
|
||||
|
||||
bool vuiParams = bs.get(1);
|
||||
r << std::string(indent, ' ') << "vui_parameters_present_flag: " << (vuiParams ? 1 : 0)
|
||||
<< std::endl;
|
||||
r << std::string(indent, ' ') << "vui_parameters_present_flag: " << (vuiParams ? 1 : 0) << std::endl;
|
||||
if (vuiParams){
|
||||
r << std::string(indent, ' ') << "vui_parameters:" << std::endl
|
||||
<< printVuiParameters(bs, indent + 1);
|
||||
|
@ -694,8 +656,7 @@ namespace h265{
|
|||
|
||||
unsigned int maxSubLayers = bs.get(3) + 1;
|
||||
|
||||
hvccBox.setNumberOfTemporalLayers(
|
||||
std::max((unsigned int)hvccBox.getNumberOfTemporalLayers(), maxSubLayers));
|
||||
hvccBox.setNumberOfTemporalLayers(std::max((unsigned int)hvccBox.getNumberOfTemporalLayers(), maxSubLayers));
|
||||
hvccBox.setTemporalIdNested(bs.get(1));
|
||||
updateProfileTierLevel(bs, hvccBox, maxSubLayers - 1);
|
||||
|
||||
|
@ -858,8 +819,7 @@ namespace h265{
|
|||
if (bs.get(1)){
|
||||
bs.skip(3);
|
||||
int spatialSegmentIdc = bs.getUExpGolomb();
|
||||
hvccBox.setMinSpatialSegmentationIdc(
|
||||
std::min((int)hvccBox.getMinSpatialSegmentationIdc(), spatialSegmentIdc));
|
||||
hvccBox.setMinSpatialSegmentationIdc(std::min((int)hvccBox.getMinSpatialSegmentationIdc(), spatialSegmentIdc));
|
||||
bs.getUExpGolomb();
|
||||
bs.getUExpGolomb();
|
||||
bs.getUExpGolomb();
|
||||
|
@ -868,4 +828,3 @@ namespace h265{
|
|||
}
|
||||
}
|
||||
}// namespace h265
|
||||
|
||||
|
|
|
@ -13,10 +13,8 @@ namespace h265{
|
|||
const char *typeToStr(uint8_t type);
|
||||
bool isKeyframe(const char *data, uint32_t len);
|
||||
|
||||
void updateProfileTierLevel(Utils::bitstream &bs, MP4::HVCC &hvccBox,
|
||||
unsigned long maxSubLayersMinus1);
|
||||
std::string printProfileTierLevel(Utils::bitstream &bs, unsigned long maxSubLayersMinus1,
|
||||
size_t indent);
|
||||
void updateProfileTierLevel(Utils::bitstream &bs, MP4::HVCC &hvccBox, unsigned long maxSubLayersMinus1);
|
||||
std::string printProfileTierLevel(Utils::bitstream &bs, unsigned long maxSubLayersMinus1, size_t indent);
|
||||
|
||||
struct metaInfo{
|
||||
uint64_t width;
|
||||
|
@ -71,4 +69,3 @@ namespace h265{
|
|||
// NOTE: no ppsUnit, as the only information it contains is parallelism mode, which can be set to
|
||||
// 0 for 'unknown'
|
||||
}// namespace h265
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#include "timing.h"
|
||||
#include "url.h"
|
||||
#include "util.h"
|
||||
#include <strings.h>
|
||||
#include <iomanip>
|
||||
#include <strings.h>
|
||||
|
||||
/// This constructor creates an empty HTTP::Parser, ready for use for either reading or writing.
|
||||
/// All this constructor does is call HTTP::Parser::Clean().
|
||||
|
@ -167,7 +167,8 @@ void HTTP::Parser::SendRequest(Socket::Connection &conn, const std::string &reqb
|
|||
sendRequest(conn, reqbody.data(), reqbody.size(), allAtOnce);
|
||||
}
|
||||
|
||||
void HTTP::Parser::sendRequest(Socket::Connection &conn, const void * reqbody, const size_t reqbodyLen, bool allAtOnce){
|
||||
void HTTP::Parser::sendRequest(Socket::Connection &conn, const void *reqbody,
|
||||
const size_t reqbodyLen, bool allAtOnce){
|
||||
/// \todo Include GET/POST variable parsing?
|
||||
if (allAtOnce){
|
||||
/// \TODO Make this less duplicated / more pretty.
|
||||
|
@ -421,9 +422,7 @@ const std::string &HTTP::Parser::GetHeader(const std::string &i) const{
|
|||
if (headers.count(i)){return headers.at(i);}
|
||||
for (std::map<std::string, std::string>::const_iterator it = headers.begin(); it != headers.end(); ++it){
|
||||
if (it->first.length() != i.length()){continue;}
|
||||
if (strncasecmp(it->first.c_str(), i.c_str(), i.length()) == 0){
|
||||
return it->second;
|
||||
}
|
||||
if (strncasecmp(it->first.c_str(), i.c_str(), i.length()) == 0){return it->second;}
|
||||
}
|
||||
// Return empty string if not found
|
||||
static const std::string empty;
|
||||
|
@ -435,9 +434,7 @@ bool HTTP::Parser::hasHeader(const std::string &i) const{
|
|||
if (headers.count(i)){return true;}
|
||||
for (std::map<std::string, std::string>::const_iterator it = headers.begin(); it != headers.end(); ++it){
|
||||
if (it->first.length() != i.length()){continue;}
|
||||
if (strncasecmp(it->first.c_str(), i.c_str(), i.length()) == 0){
|
||||
return true;
|
||||
}
|
||||
if (strncasecmp(it->first.c_str(), i.c_str(), i.length()) == 0){return true;}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -708,9 +705,7 @@ bool HTTP::Parser::parse(std::string &HTTPbuffer, Util::DataCallback &cb){
|
|||
}
|
||||
return false;
|
||||
}else{
|
||||
if (protocol.substr(0, 4) == "RTSP" || method.substr(0,4) == "RTSP"){
|
||||
return true;
|
||||
}
|
||||
if (protocol.substr(0, 4) == "RTSP" || method.substr(0, 4) == "RTSP"){return true;}
|
||||
unsigned int toappend = HTTPbuffer.size();
|
||||
bool shouldAppend = true;
|
||||
if (bodyCallback){
|
||||
|
|
|
@ -39,7 +39,8 @@ namespace HTTP{
|
|||
std::string &BuildResponse();
|
||||
std::string &BuildResponse(std::string code, std::string message);
|
||||
void SendRequest(Socket::Connection &conn, const std::string &reqbody = "", bool allAtOnce = false);
|
||||
void sendRequest(Socket::Connection &conn, const void * body = 0, const size_t bodyLen = 0, bool allAtOnce = false);
|
||||
void sendRequest(Socket::Connection &conn, const void *body = 0, const size_t bodyLen = 0,
|
||||
bool allAtOnce = false);
|
||||
void SendResponse(std::string code, std::string message, Socket::Connection &conn);
|
||||
void StartResponse(std::string code, std::string message, Parser &request,
|
||||
Socket::Connection &conn, bool bufferAllChunks = false);
|
||||
|
|
29
lib/json.cpp
29
lib/json.cpp
|
@ -1,8 +1,8 @@
|
|||
/// \file json.cpp Holds all JSON-related code.
|
||||
|
||||
#include "json.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
#include "json.h"
|
||||
#include <arpa/inet.h> //for htonl
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
@ -274,8 +274,7 @@ std::string JSON::string_escape(const std::string &val){
|
|||
if ((c & 0xC0) == 0xC0){
|
||||
// possible UTF-8 sequence
|
||||
// check for 2-byte sequence
|
||||
if (((c & 0xE0) == 0XC0) && (i + 1 < val.size()) &&
|
||||
((val.data()[i + 1] & 0xC0) == 0x80)){
|
||||
if (((c & 0xE0) == 0XC0) && (i + 1 < val.size()) && ((val.data()[i + 1] & 0xC0) == 0x80)){
|
||||
// valid 2-byte sequence
|
||||
out += UTF16(((c & 0x1F) << 6) | (val.data()[i + 1] & 0x3F));
|
||||
i += 1;
|
||||
|
@ -285,15 +284,13 @@ std::string JSON::string_escape(const std::string &val){
|
|||
if (((c & 0xF0) == 0XE0) && (i + 2 < val.size()) &&
|
||||
((val.data()[i + 1] & 0xC0) == 0x80) && ((val.data()[i + 2] & 0xC0) == 0x80)){
|
||||
// valid 3-byte sequence
|
||||
out += UTF16(((c & 0x1F) << 12) | ((val.data()[i + 1] & 0x3F) << 6) |
|
||||
(val.data()[i + 2] & 0x3F));
|
||||
out += UTF16(((c & 0x1F) << 12) | ((val.data()[i + 1] & 0x3F) << 6) | (val.data()[i + 2] & 0x3F));
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
// check for 4-byte sequence
|
||||
if (((c & 0xF8) == 0XF0) && (i + 3 < val.size()) &&
|
||||
((val.data()[i + 1] & 0xC0) == 0x80) && ((val.data()[i + 2] & 0xC0) == 0x80) &&
|
||||
((val.data()[i + 3] & 0xC0) == 0x80)){
|
||||
if (((c & 0xF8) == 0XF0) && (i + 3 < val.size()) && ((val.data()[i + 1] & 0xC0) == 0x80) &&
|
||||
((val.data()[i + 2] & 0xC0) == 0x80) && ((val.data()[i + 3] & 0xC0) == 0x80)){
|
||||
// valid 4-byte sequence
|
||||
out += UTF16(((c & 0x1F) << 18) | ((val.data()[i + 1] & 0x3F) << 12) |
|
||||
((val.data()[i + 2] & 0x3F) << 6) | (val.data()[i + 3] & 0x3F));
|
||||
|
@ -919,8 +916,7 @@ void JSON::Value::sendTo(Socket::Connection &socket) const{
|
|||
unsigned int size = 16;
|
||||
if (objVal.size() > 0){
|
||||
jsonForEachConst(*this, i){
|
||||
if (i.key().size() > 0 && i.key() != "trackid" && i.key() != "time" &&
|
||||
i.key() != "datatype"){
|
||||
if (i.key().size() > 0 && i.key() != "trackid" && i.key() != "time" && i.key() != "datatype"){
|
||||
size += 2 + i.key().size() + i->packedSize();
|
||||
}
|
||||
}
|
||||
|
@ -937,8 +933,7 @@ void JSON::Value::sendTo(Socket::Connection &socket) const{
|
|||
socket.SendNow("\340", 1);
|
||||
if (objVal.size() > 0){
|
||||
jsonForEachConst(*this, i){
|
||||
if (i.key().size() > 0 && i.key() != "trackid" && i.key() != "time" &&
|
||||
i.key() != "datatype"){
|
||||
if (i.key().size() > 0 && i.key() != "trackid" && i.key() != "time" && i.key() != "datatype"){
|
||||
char sizebuffer[2] ={0, 0};
|
||||
sizebuffer[0] = (i.key().size() >> 8) & 0xFF;
|
||||
sizebuffer[1] = i.key().size() & 0xFF;
|
||||
|
@ -1395,15 +1390,13 @@ void JSON::fromDTMI(const char *data, uint64_t len, uint32_t &i, JSON::Value &re
|
|||
case 0xFF: // also object
|
||||
case 0xE0:{// object
|
||||
++i;
|
||||
while (data[i] + data[i + 1] != 0 &&
|
||||
i < len){// while not encountering 0x0000 (we assume 0x0000EE)
|
||||
while (data[i] + data[i + 1] != 0 && i < len){// while not encountering 0x0000 (we assume 0x0000EE)
|
||||
if (i + 2 >= len){return;}
|
||||
uint16_t tmpi = Bit::btohs(data + i); // set tmpi to the UTF-8 length
|
||||
std::string tmpstr = std::string(data + i + 2, tmpi); // set the string data
|
||||
i += tmpi + 2; // skip length+size forwards
|
||||
ret[tmpstr].null();
|
||||
fromDTMI(
|
||||
data, len, i,
|
||||
fromDTMI(data, len, i,
|
||||
ret[tmpstr]); // add content, recursively parsed, updating i, setting indice to tmpstr
|
||||
}
|
||||
i += 3; // skip 0x0000EE
|
||||
|
@ -1412,8 +1405,7 @@ void JSON::fromDTMI(const char *data, uint64_t len, uint32_t &i, JSON::Value &re
|
|||
}
|
||||
case 0x0A:{// array
|
||||
++i;
|
||||
while (data[i] + data[i + 1] != 0 &&
|
||||
i < len){// while not encountering 0x0000 (we assume 0x0000EE)
|
||||
while (data[i] + data[i + 1] != 0 && i < len){// while not encountering 0x0000 (we assume 0x0000EE)
|
||||
JSON::Value tval;
|
||||
fromDTMI(data, len, i, tval); // add content, recursively parsed, updating i
|
||||
ret.append(tval);
|
||||
|
@ -1471,4 +1463,3 @@ JSON::Value JSON::fromDTMI2(const char *data, uint64_t len, uint32_t &i){
|
|||
fromDTMI2(data, len, i, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,4 +159,3 @@ namespace JSON{
|
|||
#define jsonForEach(val, i) for (JSON::Iter i(val); i; ++i)
|
||||
#define jsonForEachConst(val, i) for (JSON::ConstIter i(val); i; ++i)
|
||||
}// namespace JSON
|
||||
|
||||
|
|
|
@ -1221,4 +1221,3 @@ namespace Encodings{
|
|||
}
|
||||
|
||||
}// namespace Encodings
|
||||
|
||||
|
|
|
@ -9,6 +9,4 @@ namespace Encodings {
|
|||
static std::string encode(const std::string &lang);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
}// namespace Encodings
|
||||
|
|
498
lib/mp4.cpp
498
lib/mp4.cpp
|
@ -1,16 +1,16 @@
|
|||
#include <stdlib.h> //for malloc and free
|
||||
#include <string.h> //for memcpy
|
||||
#include <arpa/inet.h> //for htonl and friends
|
||||
#include "json.h"
|
||||
#include "mp4.h"
|
||||
#include "mp4_adobe.h"
|
||||
#include "mp4_ms.h"
|
||||
#include "mp4_dash.h"
|
||||
#include "mp4_generic.h"
|
||||
#include "mp4_encryption.h" // /*LTS*/
|
||||
#include "json.h"
|
||||
#include "mp4_generic.h"
|
||||
#include "mp4_ms.h"
|
||||
#include <arpa/inet.h> //for htonl and friends
|
||||
#include <stdlib.h> //for malloc and free
|
||||
#include <string.h> //for memcpy
|
||||
|
||||
#include "defines.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
|
||||
/// Contains all MP4 format related code.
|
||||
namespace MP4{
|
||||
|
@ -59,7 +59,6 @@ namespace MP4 {
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/// If managed, this will free the data pointer.
|
||||
Box::~Box(){
|
||||
if (managed && data){
|
||||
|
@ -81,14 +80,10 @@ namespace MP4 {
|
|||
payloadOffset = rs.payloadOffset;
|
||||
}
|
||||
/// Returns the values at byte positions 4 through 7.
|
||||
std::string Box::getType() const {
|
||||
return std::string(data + 4, 4);
|
||||
}
|
||||
std::string Box::getType() const{return std::string(data + 4, 4);}
|
||||
|
||||
/// Returns true if the given 4-byte boxtype is equal to the values at byte positions 4 through 7.
|
||||
bool Box::isType(const char * boxType) const {
|
||||
return !memcmp(boxType, data + 4, 4);
|
||||
}
|
||||
bool Box::isType(const char *boxType) const{return !memcmp(boxType, data + 4, 4);}
|
||||
|
||||
/// Reads the first 8 bytes and returns
|
||||
std::string readBoxType(FILE *newData){
|
||||
|
@ -102,9 +97,7 @@ namespace MP4 {
|
|||
/// Checks box size, offset-aware
|
||||
uint64_t calcBoxSize(const char *p){
|
||||
uint64_t r = ntohl(((int *)p)[0]);
|
||||
if (r == 1){
|
||||
return (((uint64_t)ntohl(((int *)p)[2])) << 32) | ntohl(((int *)p)[3]);
|
||||
}
|
||||
if (r == 1){return (((uint64_t)ntohl(((int *)p)[2])) << 32) | ntohl(((int *)p)[3]);}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -157,12 +150,10 @@ namespace MP4 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Reads out a whole box (if possible) from newData, copying to the internal data storage and removing from the input string.
|
||||
/// \returns True on success, false otherwise.
|
||||
/// Reads out a whole box (if possible) from newData, copying to the internal data storage and
|
||||
/// removing from the input string. \returns True on success, false otherwise.
|
||||
bool Box::read(std::string &newData){
|
||||
if (!managed) {
|
||||
return false;
|
||||
}
|
||||
if (!managed){return false;}
|
||||
if (newData.size() > 4){
|
||||
payloadOffset = 8;
|
||||
uint64_t size = ntohl(((int *)newData.c_str())[0]);
|
||||
|
@ -176,9 +167,7 @@ namespace MP4 {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (size == 0){
|
||||
size = newData.size();
|
||||
}
|
||||
if (size == 0){size = newData.size();}
|
||||
if (newData.size() >= size){
|
||||
data = (char *)realloc(data, size);
|
||||
data_size = size;
|
||||
|
@ -200,26 +189,18 @@ namespace MP4 {
|
|||
|
||||
/// Retruns the size of the payload of thix box, excluding the header.
|
||||
/// This value is defined as boxedSize() - 8.
|
||||
uint64_t Box::payloadSize() const {
|
||||
return boxedSize() - payloadOffset;
|
||||
}
|
||||
uint64_t Box::payloadSize() const{return boxedSize() - payloadOffset;}
|
||||
|
||||
/// Returns a copy of the data pointer.
|
||||
char * Box::asBox() {
|
||||
return data;
|
||||
}
|
||||
char *Box::asBox(){return data;}
|
||||
|
||||
char * Box::payload() {
|
||||
return data + payloadOffset;
|
||||
}
|
||||
char *Box::payload(){return data + payloadOffset;}
|
||||
|
||||
/// Makes this box managed if it wasn't already, resetting the internal storage to 8 bytes (the minimum).
|
||||
/// If this box wasn't managed, the original data is left intact - otherwise it is free'd.
|
||||
/// If it was somehow impossible to allocate 8 bytes (should never happen), this will cause segfaults later.
|
||||
void Box::clear(){
|
||||
if (data && managed) {
|
||||
free(data);
|
||||
}
|
||||
if (data && managed){free(data);}
|
||||
managed = true;
|
||||
payloadOffset = 8;
|
||||
data = (char *)malloc(8);
|
||||
|
@ -235,153 +216,59 @@ namespace MP4 {
|
|||
/// If this failed, it will print out a message saying pretty-printing is not implemented for boxtype.
|
||||
std::string Box::toPrettyString(uint32_t indent) const{
|
||||
switch (ntohl(*((int *)(data + 4)))){// type is at this address
|
||||
case 0x6D666864:
|
||||
return ((MFHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D6F6F66:
|
||||
return ((MOOF *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x61627374:
|
||||
return ((ABST *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x61667274:
|
||||
return ((AFRT *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x61667261:
|
||||
return ((AFRA *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x61737274:
|
||||
return ((ASRT *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x7472756E:
|
||||
return ((TRUN *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x74726166:
|
||||
return ((TRAF *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x74666864:
|
||||
return ((TFHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x68766343:
|
||||
return ((HVCC *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x61766343:
|
||||
return ((AVCC *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73647470:
|
||||
return ((SDTP *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x66747970:
|
||||
return ((FTYP *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73747970:
|
||||
return ((STYP*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D6F6F76:
|
||||
return ((MOOV *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D766578:
|
||||
return ((MVEX *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x74726578:
|
||||
return ((TREX *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D667261:
|
||||
return ((MFRA *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x7472616B:
|
||||
return ((TRAK *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D646961:
|
||||
return ((MDIA *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D696E66:
|
||||
return ((MINF *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x64696E66:
|
||||
return ((DINF *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D66726F:
|
||||
return ((MFRO *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x68646C72:
|
||||
return ((HDLR *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x766D6864:
|
||||
return ((VMHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x736D6864:
|
||||
return ((SMHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x686D6864:
|
||||
return ((HMHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6E6D6864:
|
||||
return ((NMHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D656864:
|
||||
return ((MEHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x7374626C:
|
||||
return ((STBL *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x64726566:
|
||||
return ((DREF *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x75726C20:
|
||||
return ((URL *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x75726E20:
|
||||
return ((URN *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D766864:
|
||||
return ((MVHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x74667261:
|
||||
return ((TFRA *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x746B6864:
|
||||
return ((TKHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D646864:
|
||||
return ((MDHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73747473:
|
||||
return ((STTS *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x63747473:
|
||||
return ((CTTS *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73747363:
|
||||
return ((STSC *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x7374636F:
|
||||
return ((STCO *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x636F3634:
|
||||
return ((CO64 *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x7374737A:
|
||||
return ((STSZ *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73747364:
|
||||
return ((STSD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D666864: return ((MFHD *)this)->toPrettyString(indent); break;
|
||||
case 0x6D6F6F66: return ((MOOF *)this)->toPrettyString(indent); break;
|
||||
case 0x61627374: return ((ABST *)this)->toPrettyString(indent); break;
|
||||
case 0x61667274: return ((AFRT *)this)->toPrettyString(indent); break;
|
||||
case 0x61667261: return ((AFRA *)this)->toPrettyString(indent); break;
|
||||
case 0x61737274: return ((ASRT *)this)->toPrettyString(indent); break;
|
||||
case 0x7472756E: return ((TRUN *)this)->toPrettyString(indent); break;
|
||||
case 0x74726166: return ((TRAF *)this)->toPrettyString(indent); break;
|
||||
case 0x74666864: return ((TFHD *)this)->toPrettyString(indent); break;
|
||||
case 0x68766343: return ((HVCC *)this)->toPrettyString(indent); break;
|
||||
case 0x61766343: return ((AVCC *)this)->toPrettyString(indent); break;
|
||||
case 0x73647470: return ((SDTP *)this)->toPrettyString(indent); break;
|
||||
case 0x66747970: return ((FTYP *)this)->toPrettyString(indent); break;
|
||||
case 0x73747970: return ((STYP *)this)->toPrettyString(indent); break;
|
||||
case 0x6D6F6F76: return ((MOOV *)this)->toPrettyString(indent); break;
|
||||
case 0x6D766578: return ((MVEX *)this)->toPrettyString(indent); break;
|
||||
case 0x74726578: return ((TREX *)this)->toPrettyString(indent); break;
|
||||
case 0x6D667261: return ((MFRA *)this)->toPrettyString(indent); break;
|
||||
case 0x7472616B: return ((TRAK *)this)->toPrettyString(indent); break;
|
||||
case 0x6D646961: return ((MDIA *)this)->toPrettyString(indent); break;
|
||||
case 0x6D696E66: return ((MINF *)this)->toPrettyString(indent); break;
|
||||
case 0x64696E66: return ((DINF *)this)->toPrettyString(indent); break;
|
||||
case 0x6D66726F: return ((MFRO *)this)->toPrettyString(indent); break;
|
||||
case 0x68646C72: return ((HDLR *)this)->toPrettyString(indent); break;
|
||||
case 0x766D6864: return ((VMHD *)this)->toPrettyString(indent); break;
|
||||
case 0x736D6864: return ((SMHD *)this)->toPrettyString(indent); break;
|
||||
case 0x686D6864: return ((HMHD *)this)->toPrettyString(indent); break;
|
||||
case 0x6E6D6864: return ((NMHD *)this)->toPrettyString(indent); break;
|
||||
case 0x6D656864: return ((MEHD *)this)->toPrettyString(indent); break;
|
||||
case 0x7374626C: return ((STBL *)this)->toPrettyString(indent); break;
|
||||
case 0x64726566: return ((DREF *)this)->toPrettyString(indent); break;
|
||||
case 0x75726C20: return ((URL *)this)->toPrettyString(indent); break;
|
||||
case 0x75726E20: return ((URN *)this)->toPrettyString(indent); break;
|
||||
case 0x6D766864: return ((MVHD *)this)->toPrettyString(indent); break;
|
||||
case 0x74667261: return ((TFRA *)this)->toPrettyString(indent); break;
|
||||
case 0x746B6864: return ((TKHD *)this)->toPrettyString(indent); break;
|
||||
case 0x6D646864: return ((MDHD *)this)->toPrettyString(indent); break;
|
||||
case 0x73747473: return ((STTS *)this)->toPrettyString(indent); break;
|
||||
case 0x63747473: return ((CTTS *)this)->toPrettyString(indent); break;
|
||||
case 0x73747363: return ((STSC *)this)->toPrettyString(indent); break;
|
||||
case 0x7374636F: return ((STCO *)this)->toPrettyString(indent); break;
|
||||
case 0x636F3634: return ((CO64 *)this)->toPrettyString(indent); break;
|
||||
case 0x7374737A: return ((STSZ *)this)->toPrettyString(indent); break;
|
||||
case 0x73747364: return ((STSD *)this)->toPrettyString(indent); break;
|
||||
case 0x6D703461: // mp4a
|
||||
case 0x656E6361: // enca
|
||||
case 0x61632D33: // ac-3
|
||||
return ((MP4A *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x64616333:
|
||||
return ((DAC3 *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x61616320:
|
||||
return ((AAC *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x64616333: return ((DAC3 *)this)->toPrettyString(indent); break;
|
||||
case 0x61616320: return ((AAC *)this)->toPrettyString(indent); break;
|
||||
case 0x68766331:
|
||||
case 0x68657631:
|
||||
return ((HEV1 *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x68657631: return ((HEV1 *)this)->toPrettyString(indent); break;
|
||||
case 0x61766331:
|
||||
case 0x656E6376: // encv
|
||||
return ((AVC1 *)this)->toPrettyString(indent);
|
||||
|
@ -389,61 +276,25 @@ namespace MP4 {
|
|||
case 0x68323634: // h264
|
||||
return ((H264 *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6669656C:
|
||||
return ((FIEL *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x74726566:
|
||||
return ((TREF *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x676D6864:
|
||||
return ((GMHD *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x65647473:
|
||||
return ((EDTS *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73747373:
|
||||
return ((STSS *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D657461:
|
||||
return ((META *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x656C7374:
|
||||
return ((ELST *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x65736473:
|
||||
return ((ESDS *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x75647461:
|
||||
return ((UDTA *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x75756964:
|
||||
return ((UUID *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x70617370:
|
||||
return ((PASP*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6669656C: return ((FIEL *)this)->toPrettyString(indent); break;
|
||||
case 0x74726566: return ((TREF *)this)->toPrettyString(indent); break;
|
||||
case 0x676D6864: return ((GMHD *)this)->toPrettyString(indent); break;
|
||||
case 0x65647473: return ((EDTS *)this)->toPrettyString(indent); break;
|
||||
case 0x73747373: return ((STSS *)this)->toPrettyString(indent); break;
|
||||
case 0x6D657461: return ((META *)this)->toPrettyString(indent); break;
|
||||
case 0x656C7374: return ((ELST *)this)->toPrettyString(indent); break;
|
||||
case 0x65736473: return ((ESDS *)this)->toPrettyString(indent); break;
|
||||
case 0x75647461: return ((UDTA *)this)->toPrettyString(indent); break;
|
||||
case 0x75756964: return ((UUID *)this)->toPrettyString(indent); break;
|
||||
case 0x70617370: return ((PASP *)this)->toPrettyString(indent); break;
|
||||
/*LTS-START*/
|
||||
case 0x73696478:
|
||||
return ((SIDX*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x74666474:
|
||||
return ((TFDT*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x696F6473:
|
||||
return ((IODS*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73696E66:
|
||||
return ((SINF *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x66726D61:
|
||||
return ((FRMA *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x7363686D:
|
||||
return ((SCHM *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73636869:
|
||||
return ((SCHI *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73696478: return ((SIDX *)this)->toPrettyString(indent); break;
|
||||
case 0x74666474: return ((TFDT *)this)->toPrettyString(indent); break;
|
||||
case 0x696F6473: return ((IODS *)this)->toPrettyString(indent); break;
|
||||
case 0x73696E66: return ((SINF *)this)->toPrettyString(indent); break;
|
||||
case 0x66726D61: return ((FRMA *)this)->toPrettyString(indent); break;
|
||||
case 0x7363686D: return ((SCHM *)this)->toPrettyString(indent); break;
|
||||
case 0x73636869: return ((SCHI *)this)->toPrettyString(indent); break;
|
||||
case 0x74783367:
|
||||
INFO_MSG("TX3G box found!");
|
||||
return ((TX3G *)this)->toPrettyString(indent);
|
||||
|
@ -452,28 +303,17 @@ namespace MP4 {
|
|||
INFO_MSG("FTAB box found!");
|
||||
return ((FontTableBox *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x70737368:
|
||||
return ((PSSH *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x73656E63:
|
||||
return ((SENC *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x74656E63:
|
||||
return ((TENC *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x7361697A:
|
||||
return ((SAIZ *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x7361696F:
|
||||
return ((SAIO *)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x70737368: return ((PSSH *)this)->toPrettyString(indent); break;
|
||||
case 0x73656E63: return ((SENC *)this)->toPrettyString(indent); break;
|
||||
case 0x74656E63: return ((TENC *)this)->toPrettyString(indent); break;
|
||||
case 0x7361697A: return ((SAIZ *)this)->toPrettyString(indent); break;
|
||||
case 0x7361696F: return ((SAIO *)this)->toPrettyString(indent); break;
|
||||
/*LTS-END*/
|
||||
default:
|
||||
INFO_MSG("no code found: 0x%.8x",Bit::btohl(data + 4));
|
||||
break;
|
||||
default: INFO_MSG("no code found: 0x%.8x", Bit::btohl(data + 4)); break;
|
||||
}
|
||||
std::stringstream retval;
|
||||
retval << std::string(indent, ' ') << "Unimplemented pretty-printing for box " << std::string(data + 4, 4) << " (" << ntohl(((int*)data)[0]) << ")\n";
|
||||
retval << std::string(indent, ' ') << "Unimplemented pretty-printing for box "
|
||||
<< std::string(data + 4, 4) << " (" << ntohl(((int *)data)[0]) << ")\n";
|
||||
/// \todo Implement hexdump for unimplemented boxes?
|
||||
return retval.str();
|
||||
}
|
||||
|
@ -484,9 +324,7 @@ namespace MP4 {
|
|||
void Box::setInt8(char newData, size_t index){
|
||||
index += payloadOffset;
|
||||
if (index >= boxedSize()){
|
||||
if (!reserve(index, 0, 1)) {
|
||||
return;
|
||||
}
|
||||
if (!reserve(index, 0, 1)){return;}
|
||||
}
|
||||
data[index] = newData;
|
||||
}
|
||||
|
@ -497,9 +335,7 @@ namespace MP4 {
|
|||
char Box::getInt8(size_t index){
|
||||
index += payloadOffset;
|
||||
if (index >= boxedSize()){
|
||||
if (!reserve(index, 0, 1)) {
|
||||
return 0;
|
||||
}
|
||||
if (!reserve(index, 0, 1)){return 0;}
|
||||
setInt8(0, index - payloadOffset);
|
||||
}
|
||||
return data[index];
|
||||
|
@ -509,9 +345,7 @@ namespace MP4 {
|
|||
/// Returns zero if out of bounds.
|
||||
char Box::getInt8(size_t index) const{
|
||||
index += payloadOffset;
|
||||
if (index >= boxedSize()) {
|
||||
return 0;
|
||||
}
|
||||
if (index >= boxedSize()){return 0;}
|
||||
return data[index];
|
||||
}
|
||||
|
||||
|
@ -521,9 +355,7 @@ namespace MP4 {
|
|||
void Box::setInt16(short newData, size_t index){
|
||||
index += payloadOffset;
|
||||
if (index + 1 >= boxedSize()){
|
||||
if (!reserve(index, 0, 2)) {
|
||||
return;
|
||||
}
|
||||
if (!reserve(index, 0, 2)){return;}
|
||||
}
|
||||
Bit::htobs(data + index, newData);
|
||||
}
|
||||
|
@ -534,9 +366,7 @@ namespace MP4 {
|
|||
short Box::getInt16(size_t index){
|
||||
index += payloadOffset;
|
||||
if (index + 1 >= boxedSize()){
|
||||
if (!reserve(index, 0, 2)) {
|
||||
return 0;
|
||||
}
|
||||
if (!reserve(index, 0, 2)){return 0;}
|
||||
setInt16(0, index - payloadOffset);
|
||||
}
|
||||
return Bit::btohs(data + index);
|
||||
|
@ -547,9 +377,7 @@ namespace MP4 {
|
|||
/// Returns zero if resizing failed.
|
||||
short Box::getInt16(size_t index) const{
|
||||
index += payloadOffset;
|
||||
if (index + 1 >= boxedSize()) {
|
||||
return 0;
|
||||
}
|
||||
if (index + 1 >= boxedSize()){return 0;}
|
||||
return Bit::btohs(data + index);
|
||||
}
|
||||
|
||||
|
@ -559,9 +387,7 @@ namespace MP4 {
|
|||
void Box::setInt24(uint32_t newData, size_t index){
|
||||
index += payloadOffset;
|
||||
if (index + 2 >= boxedSize()){
|
||||
if (!reserve(index, 0, 3)) {
|
||||
return;
|
||||
}
|
||||
if (!reserve(index, 0, 3)){return;}
|
||||
}
|
||||
Bit::htob24(data + index, newData);
|
||||
}
|
||||
|
@ -572,9 +398,7 @@ namespace MP4 {
|
|||
uint32_t Box::getInt24(size_t index){
|
||||
index += payloadOffset;
|
||||
if (index + 2 >= boxedSize()){
|
||||
if (!reserve(index, 0, 3)) {
|
||||
return 0;
|
||||
}
|
||||
if (!reserve(index, 0, 3)){return 0;}
|
||||
setInt24(0, index - payloadOffset);
|
||||
}
|
||||
return Bit::btoh24(data + index);
|
||||
|
@ -585,9 +409,7 @@ namespace MP4 {
|
|||
/// Returns zero if resizing failed.
|
||||
uint32_t Box::getInt24(size_t index) const{
|
||||
index += payloadOffset;
|
||||
if (index + 2 >= boxedSize()) {
|
||||
return 0;
|
||||
}
|
||||
if (index + 2 >= boxedSize()){return 0;}
|
||||
return Bit::btoh24(data + index);
|
||||
}
|
||||
|
||||
|
@ -597,9 +419,7 @@ namespace MP4 {
|
|||
void Box::setInt32(uint32_t newData, size_t index){
|
||||
index += payloadOffset;
|
||||
if (index + 3 >= boxedSize()){
|
||||
if (!reserve(index, 0, 4)) {
|
||||
return;
|
||||
}
|
||||
if (!reserve(index, 0, 4)){return;}
|
||||
}
|
||||
Bit::htobl(data + index, newData);
|
||||
}
|
||||
|
@ -610,9 +430,7 @@ namespace MP4 {
|
|||
uint32_t Box::getInt32(size_t index){
|
||||
index += payloadOffset;
|
||||
if (index + 3 >= boxedSize()){
|
||||
if (!reserve(index, 0, 4)) {
|
||||
return 0;
|
||||
}
|
||||
if (!reserve(index, 0, 4)){return 0;}
|
||||
setInt32(0, index - payloadOffset);
|
||||
}
|
||||
return Bit::btohl(data + index);
|
||||
|
@ -623,9 +441,7 @@ namespace MP4 {
|
|||
/// Returns zero if resizing failed.
|
||||
uint32_t Box::getInt32(size_t index) const{
|
||||
index += payloadOffset;
|
||||
if (index + 3 >= boxedSize()) {
|
||||
return 0;
|
||||
}
|
||||
if (index + 3 >= boxedSize()){return 0;}
|
||||
return Bit::btohl(data + index);
|
||||
}
|
||||
|
||||
|
@ -635,9 +451,7 @@ namespace MP4 {
|
|||
void Box::setInt64(uint64_t newData, size_t index){
|
||||
index += payloadOffset;
|
||||
if (index + 7 >= boxedSize()){
|
||||
if (!reserve(index, 0, 8)) {
|
||||
return;
|
||||
}
|
||||
if (!reserve(index, 0, 8)){return;}
|
||||
}
|
||||
Bit::htobll(data + index, newData);
|
||||
}
|
||||
|
@ -648,9 +462,7 @@ namespace MP4 {
|
|||
uint64_t Box::getInt64(size_t index){
|
||||
index += payloadOffset;
|
||||
if (index + 7 >= boxedSize()){
|
||||
if (!reserve(index, 0, 8)) {
|
||||
return 0;
|
||||
}
|
||||
if (!reserve(index, 0, 8)){return 0;}
|
||||
setInt64(0, index - payloadOffset);
|
||||
}
|
||||
return Bit::btohll(data + index);
|
||||
|
@ -661,9 +473,7 @@ namespace MP4 {
|
|||
/// Returns zero if resizing failed.
|
||||
uint64_t Box::getInt64(size_t index) const{
|
||||
index += payloadOffset;
|
||||
if (index + 7 >= boxedSize()) {
|
||||
return 0;
|
||||
}
|
||||
if (index + 7 >= boxedSize()){return 0;}
|
||||
return Bit::btohll(data + index);
|
||||
}
|
||||
|
||||
|
@ -680,15 +490,11 @@ namespace MP4 {
|
|||
void Box::setString(char *newData, size_t size, size_t index){
|
||||
index += payloadOffset;
|
||||
if (index >= boxedSize()){
|
||||
if (!reserve(index, 0, 1)) {
|
||||
return;
|
||||
}
|
||||
if (!reserve(index, 0, 1)){return;}
|
||||
data[index] = 0;
|
||||
}
|
||||
if (getStringLen(index) != size){
|
||||
if (!reserve(index, getStringLen(index) + 1, size + 1)) {
|
||||
return;
|
||||
}
|
||||
if (!reserve(index, getStringLen(index) + 1, size + 1)){return;}
|
||||
}
|
||||
memcpy(data + index, newData, size + 1);
|
||||
}
|
||||
|
@ -699,9 +505,7 @@ namespace MP4 {
|
|||
char *Box::getString(size_t index){
|
||||
index += payloadOffset;
|
||||
if (index >= boxedSize()){
|
||||
if (!reserve(index, 0, 1)) {
|
||||
return 0;
|
||||
}
|
||||
if (!reserve(index, 0, 1)){return 0;}
|
||||
data[index] = 0;
|
||||
}
|
||||
return data + index;
|
||||
|
@ -711,9 +515,7 @@ namespace MP4 {
|
|||
/// Returns 0 if out of range.
|
||||
size_t Box::getStringLen(size_t index) const{
|
||||
index += payloadOffset;
|
||||
if (index >= boxedSize()) {
|
||||
return 0;
|
||||
}
|
||||
if (index >= boxedSize()){return 0;}
|
||||
return strlen(data + index);
|
||||
}
|
||||
|
||||
|
@ -739,9 +541,7 @@ namespace MP4 {
|
|||
/// Returns undefined values if there is no box at the given position.
|
||||
/// Returns 0 if out of range.
|
||||
size_t Box::getBoxLen(size_t index) const{
|
||||
if ((index + payloadOffset + 8) >= boxedSize()) {
|
||||
return 0;
|
||||
}
|
||||
if ((index + payloadOffset + 8) >= boxedSize()){return 0;}
|
||||
return calcBoxSize(data + index + payloadOffset);
|
||||
}
|
||||
|
||||
|
@ -750,33 +550,23 @@ namespace MP4 {
|
|||
void Box::setBox(Box &newEntry, size_t index){
|
||||
int oldlen = getBoxLen(index);
|
||||
int newlen = newEntry.boxedSize();
|
||||
if (oldlen != newlen && !reserve(index + payloadOffset, oldlen, newlen)) {
|
||||
return;
|
||||
}
|
||||
if (oldlen != newlen && !reserve(index + payloadOffset, oldlen, newlen)){return;}
|
||||
memcpy(data + index + payloadOffset, newEntry.asBox(), newlen);
|
||||
}
|
||||
|
||||
/// Attempts to reserve enough space for wanted bytes of data at given position, where current bytes of data is now reserved.
|
||||
/// This will move any existing data behind the currently reserved space to the proper location after reserving.
|
||||
/// \returns True on success, false otherwise.
|
||||
/// Attempts to reserve enough space for wanted bytes of data at given position, where current
|
||||
/// bytes of data is now reserved. This will move any existing data behind the currently reserved
|
||||
/// space to the proper location after reserving. \returns True on success, false otherwise.
|
||||
bool Box::reserve(size_t position, size_t current, size_t wanted){
|
||||
if (current == wanted) {
|
||||
return true;
|
||||
}
|
||||
if (position > boxedSize()) {
|
||||
wanted += position - boxedSize();
|
||||
}
|
||||
if (current == wanted){return true;}
|
||||
if (position > boxedSize()){wanted += position - boxedSize();}
|
||||
if (current < wanted){
|
||||
// make bigger
|
||||
if (boxedSize() + (wanted - current) > data_size){
|
||||
// realloc if managed, otherwise fail
|
||||
if (!managed) {
|
||||
return false;
|
||||
}
|
||||
if (!managed){return false;}
|
||||
void *ret = realloc(data, boxedSize() + (wanted - current));
|
||||
if (!ret) {
|
||||
return false;
|
||||
}
|
||||
if (!ret){return false;}
|
||||
data = (char *)ret;
|
||||
memset(data + boxedSize(), 0, wanted - current); // initialize to 0
|
||||
data_size = boxedSize() + (wanted - current);
|
||||
|
@ -794,25 +584,15 @@ namespace MP4 {
|
|||
return true;
|
||||
}
|
||||
|
||||
fullBox::fullBox() {
|
||||
setVersion(0);
|
||||
}
|
||||
fullBox::fullBox(){setVersion(0);}
|
||||
|
||||
void fullBox::setVersion(char newVersion) {
|
||||
setInt8(newVersion, 0);
|
||||
}
|
||||
void fullBox::setVersion(char newVersion){setInt8(newVersion, 0);}
|
||||
|
||||
char fullBox::getVersion() const {
|
||||
return getInt8(0);
|
||||
}
|
||||
char fullBox::getVersion() const{return getInt8(0);}
|
||||
|
||||
void fullBox::setFlags(uint32_t newFlags) {
|
||||
setInt24(newFlags, 1);
|
||||
}
|
||||
void fullBox::setFlags(uint32_t newFlags){setInt24(newFlags, 1);}
|
||||
|
||||
uint32_t fullBox::getFlags() const {
|
||||
return getInt24(1);
|
||||
}
|
||||
uint32_t fullBox::getFlags() const{return getInt24(1);}
|
||||
|
||||
std::string fullBox::toPrettyString(uint32_t indent) const{
|
||||
std::stringstream r;
|
||||
|
@ -821,9 +601,7 @@ namespace MP4 {
|
|||
return r.str();
|
||||
}
|
||||
|
||||
containerBox::containerBox() {
|
||||
|
||||
}
|
||||
containerBox::containerBox(){}
|
||||
|
||||
uint32_t containerBox::getContentCount(){
|
||||
int res = 0;
|
||||
|
@ -842,9 +620,7 @@ namespace MP4 {
|
|||
if (i < contentCount){
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}else{
|
||||
if (!reserve(tempLoc, 0, (no - contentCount) * 8)) {
|
||||
return;
|
||||
};
|
||||
if (!reserve(tempLoc, 0, (no - contentCount) * 8)){return;};
|
||||
memset(data + tempLoc, 0, (no - contentCount) * 8);
|
||||
tempLoc += (no - contentCount) * 8;
|
||||
break;
|
||||
|
@ -855,9 +631,7 @@ namespace MP4 {
|
|||
|
||||
Box &containerBox::getContent(uint32_t no, bool unsafe){
|
||||
static Box ret = Box((char *)"\000\000\000\010erro", false);
|
||||
if (!unsafe && no > getContentCount()) {
|
||||
return ret;
|
||||
}
|
||||
if (!unsafe && no > getContentCount()){return ret;}
|
||||
unsigned int i = 0;
|
||||
int tempLoc = 0;
|
||||
while (i < no){
|
||||
|
@ -871,9 +645,7 @@ namespace MP4 {
|
|||
uint32_t count = getContentCount();
|
||||
for (uint32_t i = 0; i < count; i++){
|
||||
Box &thisChild = getContent(i);
|
||||
if (thisChild.isType(boxName)){
|
||||
return Box(thisChild.asBox(), false);
|
||||
}
|
||||
if (thisChild.isType(boxName)){return Box(thisChild.asBox(), false);}
|
||||
}
|
||||
return Box((char *)"\000\000\000\010erro", false);
|
||||
}
|
||||
|
@ -883,9 +655,7 @@ namespace MP4 {
|
|||
uint32_t count = getContentCount();
|
||||
for (uint32_t i = 0; i < count; i++){
|
||||
Box &thisChild = getContent(i);
|
||||
if (thisChild.isType(boxName)){
|
||||
res.push_back(Box(thisChild.asBox(), false));
|
||||
}
|
||||
if (thisChild.isType(boxName)){res.push_back(Box(thisChild.asBox(), false));}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -921,9 +691,7 @@ namespace MP4 {
|
|||
if (i < contentCount){
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}else{
|
||||
if (!reserve(tempLoc, 0, (no - contentCount) * 8)) {
|
||||
return;
|
||||
};
|
||||
if (!reserve(tempLoc, 0, (no - contentCount) * 8)){return;};
|
||||
memset(data + tempLoc, 0, (no - contentCount) * 8);
|
||||
tempLoc += (no - contentCount) * 8;
|
||||
break;
|
||||
|
@ -934,9 +702,7 @@ namespace MP4 {
|
|||
|
||||
Box &containerFullBox::getContent(uint32_t no){
|
||||
static Box ret = Box((char *)"\000\000\000\010erro", false);
|
||||
if (no > getContentCount()) {
|
||||
return ret;
|
||||
}
|
||||
if (no > getContentCount()){return ret;}
|
||||
unsigned int i = 0;
|
||||
int tempLoc = 4;
|
||||
while (i < no){
|
||||
|
@ -961,4 +727,4 @@ namespace MP4 {
|
|||
return r.str();
|
||||
}
|
||||
|
||||
}
|
||||
}// namespace MP4
|
||||
|
|
35
lib/mp4.h
35
lib/mp4.h
|
@ -1,17 +1,16 @@
|
|||
#pragma once
|
||||
#include "dtsc.h"
|
||||
#include "json.h"
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <deque>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cstdio>
|
||||
#include <stdint.h>
|
||||
#include <sstream>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "json.h"
|
||||
#include "dtsc.h"
|
||||
|
||||
/// Contains all MP4 format related code.
|
||||
namespace MP4{
|
||||
|
@ -19,16 +18,13 @@ namespace MP4 {
|
|||
bool skipBox(FILE *newData);
|
||||
uint64_t calcBoxSize(const char *p);
|
||||
|
||||
|
||||
class Box{
|
||||
public:
|
||||
Box(char *datapointer = 0, bool manage = true);
|
||||
Box(const Box &rs);
|
||||
Box &operator=(const Box &rs);
|
||||
~Box();
|
||||
operator bool() const {
|
||||
return data && data_size >= 8 && !isType("erro");
|
||||
}
|
||||
operator bool() const{return data && data_size >= 8 && !isType("erro");}
|
||||
void copyFrom(const Box &rs);
|
||||
|
||||
std::string getType() const;
|
||||
|
@ -42,6 +38,7 @@ namespace MP4 {
|
|||
char *payload();
|
||||
void clear();
|
||||
std::string toPrettyString(uint32_t indent = 0) const;
|
||||
|
||||
protected:
|
||||
// integer functions
|
||||
void setInt8(char newData, size_t index);
|
||||
|
@ -98,15 +95,13 @@ namespace MP4 {
|
|||
Box &getContent(uint32_t no, bool unsafe = false);
|
||||
std::string toPrettyString(uint32_t indent = 0);
|
||||
Box getChild(const char *boxName);
|
||||
template <typename T>
|
||||
T getChild(){
|
||||
template <typename T> T getChild(){
|
||||
T a;
|
||||
MP4::Box r = getChild(a.getType().c_str());
|
||||
return (T &)r;
|
||||
}
|
||||
std::deque<Box> getChildren(const char *boxName);
|
||||
template <typename T>
|
||||
std::deque<T> getChildren(){
|
||||
template <typename T> std::deque<T> getChildren(){
|
||||
T a;
|
||||
std::deque<Box> tmpRes = getChildren(a.getType().c_str());
|
||||
std::deque<T> res;
|
||||
|
@ -124,4 +119,4 @@ namespace MP4 {
|
|||
Box &getContent(uint32_t no);
|
||||
std::string toPrettyCFBString(uint32_t indent, std::string boxName);
|
||||
};
|
||||
}
|
||||
}// namespace MP4
|
||||
|
|
|
@ -20,89 +20,54 @@ namespace MP4 {
|
|||
setMetaData(empty);
|
||||
}
|
||||
|
||||
void ABST::setVersion(char newVersion) {
|
||||
setInt8(newVersion, 0);
|
||||
}
|
||||
void ABST::setVersion(char newVersion){setInt8(newVersion, 0);}
|
||||
|
||||
char ABST::getVersion() {
|
||||
return getInt8(0);
|
||||
}
|
||||
char ABST::getVersion(){return getInt8(0);}
|
||||
|
||||
void ABST::setFlags(uint32_t newFlags) {
|
||||
setInt24(newFlags, 1);
|
||||
}
|
||||
void ABST::setFlags(uint32_t newFlags){setInt24(newFlags, 1);}
|
||||
|
||||
uint32_t ABST::getFlags() {
|
||||
return getInt24(1);
|
||||
}
|
||||
uint32_t ABST::getFlags(){return getInt24(1);}
|
||||
|
||||
void ABST::setBootstrapinfoVersion(uint32_t newVersion) {
|
||||
setInt32(newVersion, 4);
|
||||
}
|
||||
void ABST::setBootstrapinfoVersion(uint32_t newVersion){setInt32(newVersion, 4);}
|
||||
|
||||
uint32_t ABST::getBootstrapinfoVersion() {
|
||||
return getInt32(4);
|
||||
}
|
||||
uint32_t ABST::getBootstrapinfoVersion(){return getInt32(4);}
|
||||
|
||||
void ABST::setProfile(char newProfile){
|
||||
// profile = bit 1 and 2 of byte 8.
|
||||
setInt8((getInt8(8) & 0x3F) + ((newProfile & 0x03) << 6), 8);
|
||||
}
|
||||
|
||||
char ABST::getProfile() {
|
||||
return (getInt8(8) & 0xC0);
|
||||
}
|
||||
;
|
||||
char ABST::getProfile(){return (getInt8(8) & 0xC0);};
|
||||
|
||||
void ABST::setLive(bool newLive){
|
||||
// live = bit 4 of byte 8.
|
||||
setInt8((getInt8(8) & 0xDF) + (newLive ? 0x10 : 0), 8);
|
||||
}
|
||||
|
||||
bool ABST::getLive() {
|
||||
return (getInt8(8) & 0x10);
|
||||
}
|
||||
bool ABST::getLive(){return (getInt8(8) & 0x10);}
|
||||
|
||||
void ABST::setUpdate(bool newUpdate){
|
||||
// update = bit 5 of byte 8.
|
||||
setInt8((getInt8(8) & 0xEF) + (newUpdate ? 0x08 : 0), 8);
|
||||
}
|
||||
|
||||
bool ABST::getUpdate() {
|
||||
return (getInt8(8) & 0x08);
|
||||
}
|
||||
bool ABST::getUpdate(){return (getInt8(8) & 0x08);}
|
||||
|
||||
void ABST::setTimeScale(uint32_t newScale) {
|
||||
setInt32(newScale, 9);
|
||||
}
|
||||
void ABST::setTimeScale(uint32_t newScale){setInt32(newScale, 9);}
|
||||
|
||||
uint32_t ABST::getTimeScale() {
|
||||
return getInt32(9);
|
||||
}
|
||||
uint32_t ABST::getTimeScale(){return getInt32(9);}
|
||||
|
||||
void ABST::setCurrentMediaTime(uint64_t newTime) {
|
||||
setInt64(newTime, 13);
|
||||
}
|
||||
void ABST::setCurrentMediaTime(uint64_t newTime){setInt64(newTime, 13);}
|
||||
|
||||
uint64_t ABST::getCurrentMediaTime() {
|
||||
return getInt64(13);
|
||||
}
|
||||
uint64_t ABST::getCurrentMediaTime(){return getInt64(13);}
|
||||
|
||||
void ABST::setSmpteTimeCodeOffset(uint64_t newTime) {
|
||||
setInt64(newTime, 21);
|
||||
}
|
||||
void ABST::setSmpteTimeCodeOffset(uint64_t newTime){setInt64(newTime, 21);}
|
||||
|
||||
uint64_t ABST::getSmpteTimeCodeOffset() {
|
||||
return getInt64(21);
|
||||
}
|
||||
uint64_t ABST::getSmpteTimeCodeOffset(){return getInt64(21);}
|
||||
|
||||
void ABST::setMovieIdentifier(std::string & newIdentifier) {
|
||||
setString(newIdentifier, 29);
|
||||
}
|
||||
void ABST::setMovieIdentifier(std::string &newIdentifier){setString(newIdentifier, 29);}
|
||||
|
||||
char * ABST::getMovieIdentifier() {
|
||||
return getString(29);
|
||||
}
|
||||
char *ABST::getMovieIdentifier(){return getString(29);}
|
||||
|
||||
uint32_t ABST::getServerEntryCount(){
|
||||
int countLoc = 29 + getStringLen(29) + 1;
|
||||
|
@ -114,16 +79,12 @@ namespace MP4 {
|
|||
int tempLoc = countLoc + 1;
|
||||
// attempt to reach the wanted position
|
||||
unsigned int i;
|
||||
for (i = 0; i < getInt8(countLoc) && i < no; ++i) {
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
for (i = 0; i < getInt8(countLoc) && i < no; ++i){tempLoc += getStringLen(tempLoc) + 1;}
|
||||
// we are now either at the end, or at the right position
|
||||
// let's reserve any unreserved space...
|
||||
if (no + 1 > getInt8(countLoc)){
|
||||
int amount = no + 1 - getInt8(countLoc);
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount)) {
|
||||
return;
|
||||
};
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount)){return;};
|
||||
memset(data + payloadOffset + tempLoc, 0, amount);
|
||||
setInt8(no + 1, countLoc); // set new qualityEntryCount
|
||||
tempLoc += no - i;
|
||||
|
@ -134,13 +95,9 @@ namespace MP4 {
|
|||
|
||||
///\return Empty string if no > serverEntryCount(), serverEntry[no] otherwise.
|
||||
const char *ABST::getServerEntry(uint32_t no){
|
||||
if (no + 1 > getServerEntryCount()) {
|
||||
return "";
|
||||
}
|
||||
if (no + 1 > getServerEntryCount()){return "";}
|
||||
int tempLoc = 29 + getStringLen(29) + 1 + 1; // position of first entry
|
||||
for (unsigned int i = 0; i < no; i++) {
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
for (unsigned int i = 0; i < no; i++){tempLoc += getStringLen(tempLoc) + 1;}
|
||||
return getString(tempLoc);
|
||||
}
|
||||
|
||||
|
@ -160,16 +117,12 @@ namespace MP4 {
|
|||
int tempLoc = countLoc + 1;
|
||||
// attempt to reach the wanted position
|
||||
unsigned int i;
|
||||
for (i = 0; i < getInt8(countLoc) && i < no; ++i) {
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
for (i = 0; i < getInt8(countLoc) && i < no; ++i){tempLoc += getStringLen(tempLoc) + 1;}
|
||||
// we are now either at the end, or at the right position
|
||||
// let's reserve any unreserved space...
|
||||
if (no + 1 > getInt8(countLoc)){
|
||||
int amount = no + 1 - getInt8(countLoc);
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount)) {
|
||||
return;
|
||||
};
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount)){return;};
|
||||
memset(data + payloadOffset + tempLoc, 0, amount);
|
||||
setInt8(no + 1, countLoc); // set new qualityEntryCount
|
||||
tempLoc += no - i;
|
||||
|
@ -179,17 +132,13 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
const char *ABST::getQualityEntry(uint32_t no){
|
||||
if (no > getQualityEntryCount()) {
|
||||
return "";
|
||||
}
|
||||
if (no > getQualityEntryCount()){return "";}
|
||||
int tempLoc = 29 + getStringLen(29) + 1 + 1; // position of serverentries;
|
||||
for (unsigned int i = 0; i < getServerEntryCount(); i++){
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
tempLoc += 1; // first qualityentry
|
||||
for (unsigned int i = 0; i < no; i++) {
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
for (unsigned int i = 0; i < no; i++){tempLoc += getStringLen(tempLoc) + 1;}
|
||||
return getString(tempLoc);
|
||||
}
|
||||
|
||||
|
@ -272,16 +221,12 @@ namespace MP4 {
|
|||
tempLoc++; // skip segmentRuntableCount
|
||||
// attempt to reach the wanted position
|
||||
unsigned int i;
|
||||
for (i = 0; i < getInt8(countLoc) && i < no; ++i) {
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
for (i = 0; i < getInt8(countLoc) && i < no; ++i){tempLoc += getBoxLen(tempLoc);}
|
||||
// we are now either at the end, or at the right position
|
||||
// let's reserve any unreserved space...
|
||||
if (no + 1 > getInt8(countLoc)){
|
||||
int amount = no + 1 - getInt8(countLoc);
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount * 8)) {
|
||||
return;
|
||||
};
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount * 8)){return;};
|
||||
// set empty erro boxes as contents
|
||||
for (int j = 0; j < amount; ++j){
|
||||
memcpy(data + payloadOffset + tempLoc + j * 8, "\000\000\000\010erro", 8);
|
||||
|
@ -310,9 +255,7 @@ namespace MP4 {
|
|||
tempLoc += getStringLen(tempLoc) + 1; // DrmData
|
||||
tempLoc += getStringLen(tempLoc) + 1; // MetaData
|
||||
tempLoc++; // segmentRuntableCount
|
||||
for (unsigned int i = 0; i < no; ++i) {
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
for (unsigned int i = 0; i < no; ++i){tempLoc += getBoxLen(tempLoc);}
|
||||
return (ASRT &)getBox(tempLoc);
|
||||
}
|
||||
|
||||
|
@ -327,9 +270,7 @@ namespace MP4 {
|
|||
}
|
||||
tempLoc += getStringLen(tempLoc) + 1; // DrmData
|
||||
tempLoc += getStringLen(tempLoc) + 1; // MetaData
|
||||
for (unsigned int i = getInt8(tempLoc++); i != 0; --i) {
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
for (unsigned int i = getInt8(tempLoc++); i != 0; --i){tempLoc += getBoxLen(tempLoc);}
|
||||
return getInt8(tempLoc);
|
||||
}
|
||||
|
||||
|
@ -344,23 +285,17 @@ namespace MP4 {
|
|||
}
|
||||
tempLoc += getStringLen(tempLoc) + 1; // DrmData
|
||||
tempLoc += getStringLen(tempLoc) + 1; // MetaData
|
||||
for (unsigned int i = getInt8(tempLoc++); i != 0; --i) {
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
for (unsigned int i = getInt8(tempLoc++); i != 0; --i){tempLoc += getBoxLen(tempLoc);}
|
||||
int countLoc = tempLoc;
|
||||
tempLoc++;
|
||||
// attempt to reach the wanted position
|
||||
unsigned int i;
|
||||
for (i = 0; i < getInt8(countLoc) && i < no; ++i) {
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
for (i = 0; i < getInt8(countLoc) && i < no; ++i){tempLoc += getBoxLen(tempLoc);}
|
||||
// we are now either at the end, or at the right position
|
||||
// let's reserve any unreserved space...
|
||||
if (no + 1 > getInt8(countLoc)){
|
||||
unsigned int amount = no + 1 - getInt8(countLoc);
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount * 8)) {
|
||||
return;
|
||||
};
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount * 8)){return;};
|
||||
// set empty erro boxes as contents
|
||||
for (unsigned int j = 0; j < amount; ++j){
|
||||
memcpy(data + payloadOffset + tempLoc + j * 8, "\000\000\000\010erro", 8);
|
||||
|
@ -388,13 +323,9 @@ namespace MP4 {
|
|||
}
|
||||
tempLoc += getStringLen(tempLoc) + 1; // DrmData
|
||||
tempLoc += getStringLen(tempLoc) + 1; // MetaData
|
||||
for (unsigned int i = getInt8(tempLoc++); i != 0; --i) {
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
for (unsigned int i = getInt8(tempLoc++); i != 0; --i){tempLoc += getBoxLen(tempLoc);}
|
||||
tempLoc++;
|
||||
for (unsigned int i = 0; i < no; i++) {
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
for (unsigned int i = 0; i < no; i++){tempLoc += getBoxLen(tempLoc);}
|
||||
return (AFRT &)getBox(tempLoc);
|
||||
}
|
||||
|
||||
|
@ -428,11 +359,13 @@ namespace MP4 {
|
|||
}
|
||||
r << std::string(indent + 1, ' ') << "DrmData " << getDrmData() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "MetaData " << getMetaData() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "SegmentRunTableEntries (" << getSegmentRunTableCount() << ")" << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "SegmentRunTableEntries (" << getSegmentRunTableCount()
|
||||
<< ")" << std::endl;
|
||||
for (uint32_t i = 0; i < getSegmentRunTableCount(); i++){
|
||||
r << ((Box)getSegmentRunTable(i)).toPrettyString(indent + 2);
|
||||
}
|
||||
r << std::string(indent + 1, ' ') + "FragmentRunTableEntries (" << getFragmentRunTableCount() << ")" << std::endl;
|
||||
r << std::string(indent + 1, ' ') + "FragmentRunTableEntries (" << getFragmentRunTableCount()
|
||||
<< ")" << std::endl;
|
||||
for (uint32_t i = 0; i < getFragmentRunTableCount(); i++){
|
||||
r << ((Box)getFragmentRunTable(i)).toPrettyString(indent + 2);
|
||||
}
|
||||
|
@ -446,49 +379,31 @@ namespace MP4 {
|
|||
setTimeScale(1000);
|
||||
}
|
||||
|
||||
void AFRT::setVersion(char newVersion) {
|
||||
setInt8(newVersion, 0);
|
||||
}
|
||||
void AFRT::setVersion(char newVersion){setInt8(newVersion, 0);}
|
||||
|
||||
uint32_t AFRT::getVersion() {
|
||||
return getInt8(0);
|
||||
}
|
||||
uint32_t AFRT::getVersion(){return getInt8(0);}
|
||||
|
||||
void AFRT::setUpdate(uint32_t newUpdate) {
|
||||
setInt24(newUpdate, 1);
|
||||
}
|
||||
void AFRT::setUpdate(uint32_t newUpdate){setInt24(newUpdate, 1);}
|
||||
|
||||
uint32_t AFRT::getUpdate() {
|
||||
return getInt24(1);
|
||||
}
|
||||
uint32_t AFRT::getUpdate(){return getInt24(1);}
|
||||
|
||||
void AFRT::setTimeScale(uint32_t newScale) {
|
||||
setInt32(newScale, 4);
|
||||
}
|
||||
void AFRT::setTimeScale(uint32_t newScale){setInt32(newScale, 4);}
|
||||
|
||||
uint32_t AFRT::getTimeScale() {
|
||||
return getInt32(4);
|
||||
}
|
||||
uint32_t AFRT::getTimeScale(){return getInt32(4);}
|
||||
|
||||
uint32_t AFRT::getQualityEntryCount() {
|
||||
return getInt8(8);
|
||||
}
|
||||
uint32_t AFRT::getQualityEntryCount(){return getInt8(8);}
|
||||
|
||||
void AFRT::setQualityEntry(std::string &newEntry, uint32_t no){
|
||||
int countLoc = 8;
|
||||
int tempLoc = countLoc + 1;
|
||||
// attempt to reach the wanted position
|
||||
unsigned int i;
|
||||
for (i = 0; i < getQualityEntryCount() && i < no; ++i) {
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
for (i = 0; i < getQualityEntryCount() && i < no; ++i){tempLoc += getStringLen(tempLoc) + 1;}
|
||||
// we are now either at the end, or at the right position
|
||||
// let's reserve any unreserved space...
|
||||
if (no + 1 > getQualityEntryCount()){
|
||||
int amount = no + 1 - getQualityEntryCount();
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount)) {
|
||||
return;
|
||||
};
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount)){return;};
|
||||
memset(data + payloadOffset + tempLoc, 0, amount);
|
||||
setInt8(no + 1, countLoc); // set new qualityEntryCount
|
||||
tempLoc += no - i;
|
||||
|
@ -498,13 +413,9 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
const char *AFRT::getQualityEntry(uint32_t no){
|
||||
if (no + 1 > getQualityEntryCount()) {
|
||||
return "";
|
||||
}
|
||||
if (no + 1 > getQualityEntryCount()){return "";}
|
||||
int tempLoc = 9; // position of first quality entry
|
||||
for (unsigned int i = 0; i < no; i++) {
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
for (unsigned int i = 0; i < no; i++){tempLoc += getStringLen(tempLoc) + 1;}
|
||||
return getString(tempLoc);
|
||||
}
|
||||
|
||||
|
@ -539,19 +450,13 @@ namespace MP4 {
|
|||
setInt32(newRun.firstFragment, tempLoc);
|
||||
setInt64(newRun.firstTimestamp, tempLoc + 4);
|
||||
setInt32(newRun.duration, tempLoc + 12);
|
||||
if (newRun.duration == 0) {
|
||||
setInt8(newRun.discontinuity, tempLoc + 16);
|
||||
}
|
||||
if (count < no + 1) {
|
||||
setInt32(no + 1, countLoc);
|
||||
}
|
||||
if (newRun.duration == 0){setInt8(newRun.discontinuity, tempLoc + 16);}
|
||||
if (count < no + 1){setInt32(no + 1, countLoc);}
|
||||
}
|
||||
|
||||
afrt_runtable AFRT::getFragmentRun(uint32_t no){
|
||||
afrt_runtable res;
|
||||
if (no > getFragmentRunCount()) {
|
||||
return res;
|
||||
}
|
||||
if (no > getFragmentRunCount()){return res;}
|
||||
int tempLoc = 9;
|
||||
for (unsigned int i = 0; i < getQualityEntryCount(); i++){
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
|
@ -585,7 +490,8 @@ namespace MP4 {
|
|||
r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl;
|
||||
}
|
||||
r << std::string(indent + 1, ' ') << "Timescale " << getTimeScale() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "QualitySegmentUrlModifiers (" << getQualityEntryCount() << ")" << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "QualitySegmentUrlModifiers (" << getQualityEntryCount()
|
||||
<< ")" << std::endl;
|
||||
for (unsigned int i = 0; i < getQualityEntryCount(); i++){
|
||||
r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl;
|
||||
}
|
||||
|
@ -593,11 +499,13 @@ namespace MP4 {
|
|||
for (unsigned int i = 0; i < getFragmentRunCount(); i++){
|
||||
afrt_runtable myRun = getFragmentRun(i);
|
||||
if (myRun.duration){
|
||||
r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at " << ((double)myRun.firstTimestamp / (double)getTimeScale())
|
||||
<< "s, " << ((double)myRun.duration / (double)getTimeScale()) << "s per fragment." << std::endl;
|
||||
r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at "
|
||||
<< ((double)myRun.firstTimestamp / (double)getTimeScale()) << "s, "
|
||||
<< ((double)myRun.duration / (double)getTimeScale()) << "s per fragment." << std::endl;
|
||||
}else{
|
||||
r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at " << ((double)myRun.firstTimestamp / (double)getTimeScale())
|
||||
<< "s, discontinuity type " << myRun.discontinuity << std::endl;
|
||||
r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at "
|
||||
<< ((double)myRun.firstTimestamp / (double)getTimeScale()) << "s, discontinuity type "
|
||||
<< myRun.discontinuity << std::endl;
|
||||
}
|
||||
}
|
||||
return r.str();
|
||||
|
@ -609,41 +517,27 @@ namespace MP4 {
|
|||
setUpdate(0);
|
||||
}
|
||||
|
||||
void ASRT::setVersion(char newVersion) {
|
||||
setInt8(newVersion, 0);
|
||||
}
|
||||
void ASRT::setVersion(char newVersion){setInt8(newVersion, 0);}
|
||||
|
||||
uint32_t ASRT::getVersion() {
|
||||
return getInt8(0);
|
||||
}
|
||||
uint32_t ASRT::getVersion(){return getInt8(0);}
|
||||
|
||||
void ASRT::setUpdate(uint32_t newUpdate) {
|
||||
setInt24(newUpdate, 1);
|
||||
}
|
||||
void ASRT::setUpdate(uint32_t newUpdate){setInt24(newUpdate, 1);}
|
||||
|
||||
uint32_t ASRT::getUpdate() {
|
||||
return getInt24(1);
|
||||
}
|
||||
uint32_t ASRT::getUpdate(){return getInt24(1);}
|
||||
|
||||
uint32_t ASRT::getQualityEntryCount() {
|
||||
return getInt8(4);
|
||||
}
|
||||
uint32_t ASRT::getQualityEntryCount(){return getInt8(4);}
|
||||
|
||||
void ASRT::setQualityEntry(std::string &newEntry, uint32_t no){
|
||||
int countLoc = 4;
|
||||
int tempLoc = countLoc + 1;
|
||||
// attempt to reach the wanted position
|
||||
unsigned int i;
|
||||
for (i = 0; i < getQualityEntryCount() && i < no; ++i) {
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
for (i = 0; i < getQualityEntryCount() && i < no; ++i){tempLoc += getStringLen(tempLoc) + 1;}
|
||||
// we are now either at the end, or at the right position
|
||||
// let's reserve any unreserved space...
|
||||
if (no + 1 > getQualityEntryCount()){
|
||||
int amount = no + 1 - getQualityEntryCount();
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount)) {
|
||||
return;
|
||||
};
|
||||
if (!reserve(payloadOffset + tempLoc, 0, amount)){return;};
|
||||
memset(data + payloadOffset + tempLoc, 0, amount);
|
||||
setInt8(no + 1, countLoc); // set new qualityEntryCount
|
||||
tempLoc += no - i;
|
||||
|
@ -653,13 +547,9 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
const char *ASRT::getQualityEntry(uint32_t no){
|
||||
if (no > getQualityEntryCount()) {
|
||||
return "";
|
||||
}
|
||||
if (no > getQualityEntryCount()){return "";}
|
||||
int tempLoc = 5; // position of qualityentry count;
|
||||
for (unsigned int i = 0; i < no; i++) {
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
}
|
||||
for (unsigned int i = 0; i < no; i++){tempLoc += getStringLen(tempLoc) + 1;}
|
||||
return getString(tempLoc);
|
||||
}
|
||||
|
||||
|
@ -687,9 +577,7 @@ namespace MP4 {
|
|||
|
||||
asrt_runtable ASRT::getSegmentRun(uint32_t no){
|
||||
asrt_runtable res;
|
||||
if (no >= getSegmentRunEntryCount()) {
|
||||
return res;
|
||||
}
|
||||
if (no >= getSegmentRunEntryCount()){return res;}
|
||||
int tempLoc = 5; // position of qualityentry count;
|
||||
for (unsigned int i = 0; i < getQualityEntryCount(); ++i){
|
||||
tempLoc += getStringLen(tempLoc) + 1;
|
||||
|
@ -713,10 +601,11 @@ namespace MP4 {
|
|||
for (unsigned int i = 0; i < getQualityEntryCount(); i++){
|
||||
r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl;
|
||||
}
|
||||
r << std::string(indent + 1, ' ') << "SegmentRunEntryTable (" << getSegmentRunEntryCount() << ")" << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "SegmentRunEntryTable (" << getSegmentRunEntryCount()
|
||||
<< ")" << std::endl;
|
||||
for (unsigned int i = 0; i < getSegmentRunEntryCount(); i++){
|
||||
r << std::string(indent + 2, ' ') << i << ": First=" << getSegmentRun(i).firstSegment << ", FragmentsPerSegment="
|
||||
<< getSegmentRun(i).fragmentsPerSegment << std::endl;
|
||||
r << std::string(indent + 2, ' ') << i << ": First=" << getSegmentRun(i).firstSegment
|
||||
<< ", FragmentsPerSegment=" << getSegmentRun(i).fragmentsPerSegment << std::endl;
|
||||
}
|
||||
return r.str();
|
||||
}
|
||||
|
@ -726,21 +615,13 @@ namespace MP4 {
|
|||
setFlags(0);
|
||||
}
|
||||
|
||||
void AFRA::setVersion(uint32_t newVersion) {
|
||||
setInt8(newVersion, 0);
|
||||
}
|
||||
void AFRA::setVersion(uint32_t newVersion){setInt8(newVersion, 0);}
|
||||
|
||||
uint32_t AFRA::getVersion() {
|
||||
return getInt8(0);
|
||||
}
|
||||
uint32_t AFRA::getVersion(){return getInt8(0);}
|
||||
|
||||
void AFRA::setFlags(uint32_t newFlags) {
|
||||
setInt24(newFlags, 1);
|
||||
}
|
||||
void AFRA::setFlags(uint32_t newFlags){setInt24(newFlags, 1);}
|
||||
|
||||
uint32_t AFRA::getFlags() {
|
||||
return getInt24(1);
|
||||
}
|
||||
uint32_t AFRA::getFlags(){return getInt24(1);}
|
||||
|
||||
void AFRA::setLongIDs(bool newVal){
|
||||
if (newVal){
|
||||
|
@ -750,9 +631,7 @@ namespace MP4 {
|
|||
}
|
||||
}
|
||||
|
||||
bool AFRA::getLongIDs() {
|
||||
return getInt8(4) & 0x80;
|
||||
}
|
||||
bool AFRA::getLongIDs(){return getInt8(4) & 0x80;}
|
||||
|
||||
void AFRA::setLongOffsets(bool newVal){
|
||||
if (newVal){
|
||||
|
@ -762,9 +641,7 @@ namespace MP4 {
|
|||
}
|
||||
}
|
||||
|
||||
bool AFRA::getLongOffsets() {
|
||||
return getInt8(4) & 0x40;
|
||||
}
|
||||
bool AFRA::getLongOffsets(){return getInt8(4) & 0x40;}
|
||||
|
||||
void AFRA::setGlobalEntries(bool newVal){
|
||||
if (newVal){
|
||||
|
@ -774,44 +651,30 @@ namespace MP4 {
|
|||
}
|
||||
}
|
||||
|
||||
bool AFRA::getGlobalEntries() {
|
||||
return getInt8(4) & 0x20;
|
||||
}
|
||||
bool AFRA::getGlobalEntries(){return getInt8(4) & 0x20;}
|
||||
|
||||
void AFRA::setTimeScale(uint32_t newVal) {
|
||||
setInt32(newVal, 5);
|
||||
}
|
||||
void AFRA::setTimeScale(uint32_t newVal){setInt32(newVal, 5);}
|
||||
|
||||
uint32_t AFRA::getTimeScale() {
|
||||
return getInt32(5);
|
||||
}
|
||||
uint32_t AFRA::getTimeScale(){return getInt32(5);}
|
||||
|
||||
uint32_t AFRA::getEntryCount() {
|
||||
return getInt32(9);
|
||||
}
|
||||
uint32_t AFRA::getEntryCount(){return getInt32(9);}
|
||||
|
||||
void AFRA::setEntry(afraentry newEntry, uint32_t no){
|
||||
int entrysize = 12;
|
||||
if (getLongOffsets()) {
|
||||
entrysize = 16;
|
||||
}
|
||||
if (getLongOffsets()){entrysize = 16;}
|
||||
setInt64(newEntry.time, 13 + entrysize * no);
|
||||
if (getLongOffsets()){
|
||||
setInt64(newEntry.offset, 21 + entrysize * no);
|
||||
}else{
|
||||
setInt32(newEntry.offset, 21 + entrysize * no);
|
||||
}
|
||||
if (no + 1 > getEntryCount()) {
|
||||
setInt32(no + 1, 9);
|
||||
}
|
||||
if (no + 1 > getEntryCount()){setInt32(no + 1, 9);}
|
||||
}
|
||||
|
||||
afraentry AFRA::getEntry(uint32_t no){
|
||||
afraentry ret;
|
||||
int entrysize = 12;
|
||||
if (getLongOffsets()) {
|
||||
entrysize = 16;
|
||||
}
|
||||
if (getLongOffsets()){entrysize = 16;}
|
||||
ret.time = getInt64(13 + entrysize * no);
|
||||
if (getLongOffsets()){
|
||||
ret.offset = getInt64(21 + entrysize * no);
|
||||
|
@ -822,28 +685,18 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
uint32_t AFRA::getGlobalEntryCount(){
|
||||
if (!getGlobalEntries()) {
|
||||
return 0;
|
||||
}
|
||||
if (!getGlobalEntries()){return 0;}
|
||||
int entrysize = 12;
|
||||
if (getLongOffsets()) {
|
||||
entrysize = 16;
|
||||
}
|
||||
if (getLongOffsets()){entrysize = 16;}
|
||||
return getInt32(13 + entrysize * getEntryCount());
|
||||
}
|
||||
|
||||
void AFRA::setGlobalEntry(globalafraentry newEntry, uint32_t no){
|
||||
int offset = 13 + 12 * getEntryCount() + 4;
|
||||
if (getLongOffsets()) {
|
||||
offset = 13 + 16 * getEntryCount() + 4;
|
||||
}
|
||||
if (getLongOffsets()){offset = 13 + 16 * getEntryCount() + 4;}
|
||||
int entrysize = 20;
|
||||
if (getLongIDs()) {
|
||||
entrysize += 4;
|
||||
}
|
||||
if (getLongOffsets()) {
|
||||
entrysize += 8;
|
||||
}
|
||||
if (getLongIDs()){entrysize += 4;}
|
||||
if (getLongOffsets()){entrysize += 8;}
|
||||
|
||||
setInt64(newEntry.time, offset + entrysize * no);
|
||||
if (getLongIDs()){
|
||||
|
@ -861,24 +714,16 @@ namespace MP4 {
|
|||
setInt32(newEntry.offsetfromafra, offset + entrysize * no + entrysize - 4);
|
||||
}
|
||||
|
||||
if (getInt32(offset - 4) < no + 1) {
|
||||
setInt32(no + 1, offset - 4);
|
||||
}
|
||||
if (getInt32(offset - 4) < no + 1){setInt32(no + 1, offset - 4);}
|
||||
}
|
||||
|
||||
globalafraentry AFRA::getGlobalEntry(uint32_t no){
|
||||
globalafraentry ret;
|
||||
int offset = 13 + 12 * getEntryCount() + 4;
|
||||
if (getLongOffsets()) {
|
||||
offset = 13 + 16 * getEntryCount() + 4;
|
||||
}
|
||||
if (getLongOffsets()){offset = 13 + 16 * getEntryCount() + 4;}
|
||||
int entrysize = 20;
|
||||
if (getLongIDs()) {
|
||||
entrysize += 4;
|
||||
}
|
||||
if (getLongOffsets()) {
|
||||
entrysize += 8;
|
||||
}
|
||||
if (getLongIDs()){entrysize += 4;}
|
||||
if (getLongOffsets()){entrysize += 8;}
|
||||
|
||||
ret.time = getInt64(offset + entrysize * no);
|
||||
if (getLongIDs()){
|
||||
|
@ -912,7 +757,8 @@ namespace MP4 {
|
|||
r << std::string(indent + 1, ' ') << "Entries (" << count << ") " << std::endl;
|
||||
for (uint32_t i = 0; i < count; ++i){
|
||||
afraentry tmpent = getEntry(i);
|
||||
r << std::string(indent + 1, ' ') << i << ": Time " << tmpent.time << ", Offset " << tmpent.offset << std::endl;
|
||||
r << std::string(indent + 1, ' ') << i << ": Time " << tmpent.time << ", Offset "
|
||||
<< tmpent.offset << std::endl;
|
||||
}
|
||||
|
||||
if (getGlobalEntries()){
|
||||
|
@ -920,10 +766,10 @@ namespace MP4 {
|
|||
r << std::string(indent + 1, ' ') << "Global Entries (" << count << ") " << std::endl;
|
||||
for (uint32_t i = 0; i < count; ++i){
|
||||
globalafraentry tmpent = getGlobalEntry(i);
|
||||
r << std::string(indent + 1, ' ') << i << ": T " << tmpent.time << ", S" << tmpent.segment << "F" << tmpent.fragment << ", "
|
||||
<< tmpent.afraoffset << "/" << tmpent.offsetfromafra << std::endl;
|
||||
r << std::string(indent + 1, ' ') << i << ": T " << tmpent.time << ", S" << tmpent.segment << "F"
|
||||
<< tmpent.fragment << ", " << tmpent.afraoffset << "/" << tmpent.offsetfromafra << std::endl;
|
||||
}
|
||||
}
|
||||
return r.str();
|
||||
}
|
||||
}
|
||||
}// namespace MP4
|
||||
|
|
|
@ -135,5 +135,4 @@ namespace MP4 {
|
|||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}// namespace MP4
|
||||
|
|
137
lib/mp4_dash.cpp
137
lib/mp4_dash.cpp
|
@ -1,5 +1,5 @@
|
|||
#include "mp4_dash.h"
|
||||
#include "defines.h"
|
||||
#include "mp4_dash.h"
|
||||
|
||||
namespace MP4{
|
||||
SIDX::SIDX(){
|
||||
|
@ -8,21 +8,13 @@ namespace MP4 {
|
|||
setFlags(0);
|
||||
}
|
||||
|
||||
void SIDX::setReferenceID(uint32_t newReferenceID) {
|
||||
setInt32(newReferenceID, 4);
|
||||
}
|
||||
void SIDX::setReferenceID(uint32_t newReferenceID){setInt32(newReferenceID, 4);}
|
||||
|
||||
uint32_t SIDX::getReferenceID() {
|
||||
return getInt32(4);
|
||||
}
|
||||
uint32_t SIDX::getReferenceID(){return getInt32(4);}
|
||||
|
||||
void SIDX::setTimescale(uint32_t newTimescale) {
|
||||
setInt32(newTimescale, 8);
|
||||
}
|
||||
void SIDX::setTimescale(uint32_t newTimescale){setInt32(newTimescale, 8);}
|
||||
|
||||
uint32_t SIDX::getTimescale() {
|
||||
return getInt32(8);
|
||||
}
|
||||
uint32_t SIDX::getTimescale(){return getInt32(8);}
|
||||
|
||||
void SIDX::setEarliestPresentationTime(uint64_t newEarliestPresentationTime){
|
||||
if (getVersion() == 0){
|
||||
|
@ -33,9 +25,7 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
uint64_t SIDX::getEarliestPresentationTime(){
|
||||
if (getVersion() == 0) {
|
||||
return getInt32(12);
|
||||
}
|
||||
if (getVersion() == 0){return getInt32(12);}
|
||||
return getInt64(12);
|
||||
}
|
||||
|
||||
|
@ -48,23 +38,17 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
uint64_t SIDX::getFirstOffset(){
|
||||
if (getVersion() == 0) {
|
||||
return getInt32(16);
|
||||
}
|
||||
if (getVersion() == 0){return getInt32(16);}
|
||||
return getInt64(20);
|
||||
}
|
||||
|
||||
uint16_t SIDX::getReferenceCount(){
|
||||
if (getVersion() == 0) {
|
||||
return getInt16(22);
|
||||
}
|
||||
if (getVersion() == 0){return getInt16(22);}
|
||||
return getInt16(30);
|
||||
}
|
||||
|
||||
void SIDX::setReference(sidxReference &newRef, size_t index){
|
||||
if (index >= getReferenceCount()) {
|
||||
setInt16(index + 1, (getVersion() == 0 ? 22 : 30));
|
||||
}
|
||||
if (index >= getReferenceCount()){setInt16(index + 1, (getVersion() == 0 ? 22 : 30));}
|
||||
uint32_t offset = 24 + (index * 12) + (getVersion() == 0 ? 0 : 8);
|
||||
uint32_t tmp = (newRef.referenceType ? 0x80000000 : 0) | newRef.referencedSize;
|
||||
setInt32(tmp, offset);
|
||||
|
@ -97,7 +81,8 @@ namespace MP4 {
|
|||
r << fullBox::toPrettyString(indent);
|
||||
r << std::string(indent + 1, ' ') << "ReferenceID " << getReferenceID() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Timescale " << getTimescale() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "EarliestPresentationTime " << getEarliestPresentationTime() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "EarliestPresentationTime "
|
||||
<< getEarliestPresentationTime() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "FirstOffset " << getFirstOffset() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "References [" << getReferenceCount() << "]" << std::endl;
|
||||
for (int i = 0; i < getReferenceCount(); i++){
|
||||
|
@ -129,15 +114,14 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
uint64_t TFDT::getBaseMediaDecodeTime(){
|
||||
if (getVersion() == 1) {
|
||||
return getInt64(4);
|
||||
}
|
||||
if (getVersion() == 1){return getInt64(4);}
|
||||
return getInt32(4);
|
||||
}
|
||||
|
||||
std::string TFDT::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[tfdt] Track Fragment Base Media Decode Time Box (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[tfdt] Track Fragment Base Media Decode Time Box ("
|
||||
<< boxedSize() << ")" << std::endl;
|
||||
r << fullBox::toPrettyString(indent);
|
||||
r << std::string(indent + 1, ' ') << "BaseMediaDecodeTime " << getBaseMediaDecodeTime() << std::endl;
|
||||
return r.str();
|
||||
|
@ -157,85 +141,58 @@ namespace MP4 {
|
|||
setODGraphicsLevel(0xFF);
|
||||
}
|
||||
|
||||
void IODS::setIODTypeTag(char value) {
|
||||
setInt8(value, 4);
|
||||
}
|
||||
void IODS::setIODTypeTag(char value){setInt8(value, 4);}
|
||||
|
||||
char IODS::getIODTypeTag() {
|
||||
return getInt8(4);
|
||||
}
|
||||
char IODS::getIODTypeTag(){return getInt8(4);}
|
||||
|
||||
void IODS::setDescriptorTypeLength(char length) {
|
||||
setInt8(length, 5);
|
||||
}
|
||||
void IODS::setDescriptorTypeLength(char length){setInt8(length, 5);}
|
||||
|
||||
char IODS::getDescriptorTypeLength() {
|
||||
return getInt8(5);
|
||||
}
|
||||
char IODS::getDescriptorTypeLength(){return getInt8(5);}
|
||||
|
||||
void IODS::setODID(short id) {
|
||||
setInt16(id, 6);
|
||||
}
|
||||
void IODS::setODID(short id){setInt16(id, 6);}
|
||||
|
||||
short IODS::getODID() {
|
||||
return getInt16(6);
|
||||
}
|
||||
short IODS::getODID(){return getInt16(6);}
|
||||
|
||||
void IODS::setODProfileLevel(char value) {
|
||||
setInt8(value, 8);
|
||||
}
|
||||
void IODS::setODProfileLevel(char value){setInt8(value, 8);}
|
||||
|
||||
char IODS::getODProfileLevel() {
|
||||
return getInt8(8);
|
||||
}
|
||||
char IODS::getODProfileLevel(){return getInt8(8);}
|
||||
|
||||
void IODS::setODSceneLevel(char value) {
|
||||
setInt8(value, 9);
|
||||
}
|
||||
void IODS::setODSceneLevel(char value){setInt8(value, 9);}
|
||||
|
||||
char IODS::getODSceneLevel() {
|
||||
return getInt8(9);
|
||||
}
|
||||
char IODS::getODSceneLevel(){return getInt8(9);}
|
||||
|
||||
void IODS::setODAudioLevel(char value) {
|
||||
setInt8(value, 10);
|
||||
}
|
||||
void IODS::setODAudioLevel(char value){setInt8(value, 10);}
|
||||
|
||||
char IODS::getODAudioLevel() {
|
||||
return getInt8(10);
|
||||
}
|
||||
char IODS::getODAudioLevel(){return getInt8(10);}
|
||||
|
||||
void IODS::setODVideoLevel(char value) {
|
||||
setInt8(value, 11);
|
||||
}
|
||||
void IODS::setODVideoLevel(char value){setInt8(value, 11);}
|
||||
|
||||
char IODS::getODVideoLevel() {
|
||||
return getInt8(11);
|
||||
}
|
||||
char IODS::getODVideoLevel(){return getInt8(11);}
|
||||
|
||||
void IODS::setODGraphicsLevel(char value) {
|
||||
setInt8(value, 12);
|
||||
}
|
||||
|
||||
char IODS::getODGraphicsLevel() {
|
||||
return getInt8(12);
|
||||
}
|
||||
void IODS::setODGraphicsLevel(char value){setInt8(value, 12);}
|
||||
|
||||
char IODS::getODGraphicsLevel(){return getInt8(12);}
|
||||
|
||||
std::string IODS::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[iods] IODS Box (" << boxedSize() << ")" << std::endl;
|
||||
r << fullBox::toPrettyString(indent);
|
||||
r << std::string(indent + 2, ' ') << "IOD Type Tag: " << std::hex << std::setw(2) << std::setfill('0') << (int)getIODTypeTag() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "DescriptorTypeLength: " << std::hex << std::setw(2) << std::setfill('0') << (int)getDescriptorTypeLength() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD ID: " << std::hex << std::setw(4) << std::setfill('0') << (int)getODID() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Profile Level: " << std::hex << std::setw(2) << std::setfill('0') << (int)getODProfileLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Scene Level: " << std::hex << std::setw(2) << std::setfill('0') << (int)getODSceneLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Audio Level: " << std::hex << std::setw(2) << std::setfill('0') << (int)getODAudioLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Video Level: " << std::hex << std::setw(2) << std::setfill('0') << (int)getODVideoLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Graphics Level: " << std::hex << std::setw(2) << std::setfill('0') << (int)getODGraphicsLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "IOD Type Tag: " << std::hex << std::setw(2)
|
||||
<< std::setfill('0') << (int)getIODTypeTag() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "DescriptorTypeLength: " << std::hex << std::setw(2)
|
||||
<< std::setfill('0') << (int)getDescriptorTypeLength() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD ID: " << std::hex << std::setw(4) << std::setfill('0')
|
||||
<< (int)getODID() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Profile Level: " << std::hex << std::setw(2)
|
||||
<< std::setfill('0') << (int)getODProfileLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Scene Level: " << std::hex << std::setw(2)
|
||||
<< std::setfill('0') << (int)getODSceneLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Audio Level: " << std::hex << std::setw(2)
|
||||
<< std::setfill('0') << (int)getODAudioLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Video Level: " << std::hex << std::setw(2)
|
||||
<< std::setfill('0') << (int)getODVideoLevel() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "OD Graphics Level: " << std::hex << std::setw(2)
|
||||
<< std::setfill('0') << (int)getODGraphicsLevel() << std::dec << std::endl;
|
||||
return r.str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}// namespace MP4
|
||||
|
|
|
@ -69,5 +69,4 @@ namespace MP4 {
|
|||
|
||||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
}
|
||||
|
||||
}// namespace MP4
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
#include "mp4_encryption.h"
|
||||
#include "defines.h"
|
||||
#include "mp4_encryption.h"
|
||||
|
||||
namespace MP4{
|
||||
|
||||
PSSH::PSSH() {
|
||||
memcpy(data + 4, "pssh", 4);
|
||||
}
|
||||
PSSH::PSSH(){memcpy(data + 4, "pssh", 4);}
|
||||
|
||||
std::string PSSH::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[pssh] Protection System Specific Header Box (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[pssh] Protection System Specific Header Box (" << boxedSize()
|
||||
<< ")" << std::endl;
|
||||
r << fullBox::toPrettyString(indent);
|
||||
r << std::string(indent + 1, ' ') << "SystemID: " << getSystemIDHex() << std::endl;
|
||||
if (getVersion()){
|
||||
|
@ -35,13 +34,9 @@ namespace MP4 {
|
|||
return "0x" + res.str();
|
||||
}
|
||||
|
||||
void PSSH::setSystemIDHex(const std::string & systemID) {
|
||||
setString(systemID, 4);
|
||||
}
|
||||
void PSSH::setSystemIDHex(const std::string &systemID){setString(systemID, 4);}
|
||||
|
||||
size_t PSSH::getKIDCount(){
|
||||
return getVersion() ? getInt32(20) : 0;
|
||||
}
|
||||
size_t PSSH::getKIDCount(){return getVersion() ? getInt32(20) : 0;}
|
||||
|
||||
size_t PSSH::getDataSize(){
|
||||
if (getVersion()){
|
||||
|
@ -64,9 +59,7 @@ namespace MP4 {
|
|||
WARN_MSG("Not implemented yet!");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < data.size(); i++){
|
||||
setInt8(data[i], 24 + i);
|
||||
}
|
||||
for (int i = 0; i < data.size(); i++){setInt8(data[i], 24 + i);}
|
||||
setInt32(data.size(), 20);
|
||||
}
|
||||
|
||||
|
@ -90,23 +83,13 @@ namespace MP4 {
|
|||
setDefaultIsEncrypted(1);
|
||||
setDefaultIVSize(8);
|
||||
}
|
||||
size_t TENC::getDefaultIsEncrypted(){
|
||||
return getInt24(4);
|
||||
}
|
||||
void TENC::setDefaultIsEncrypted(size_t isEncrypted){
|
||||
setInt24(isEncrypted, 4);
|
||||
}
|
||||
size_t TENC::getDefaultIVSize(){
|
||||
return getInt8(7);
|
||||
}
|
||||
void TENC::setDefaultIVSize(uint8_t ivSize){
|
||||
setInt8(ivSize, 7);
|
||||
}
|
||||
size_t TENC::getDefaultIsEncrypted(){return getInt24(4);}
|
||||
void TENC::setDefaultIsEncrypted(size_t isEncrypted){setInt24(isEncrypted, 4);}
|
||||
size_t TENC::getDefaultIVSize(){return getInt8(7);}
|
||||
void TENC::setDefaultIVSize(uint8_t ivSize){setInt8(ivSize, 7);}
|
||||
std::string TENC::getDefaultKID(){
|
||||
std::string result;
|
||||
for (int i = 8; i < 24; i++){
|
||||
result += getInt8(i);
|
||||
}
|
||||
for (int i = 8; i < 24; i++){result += getInt8(i);}
|
||||
return result;
|
||||
}
|
||||
void TENC::setDefaultKID(const std::string &kid){
|
||||
|
@ -123,9 +106,7 @@ namespace MP4 {
|
|||
memcpy(data + 4, "senc", 4);
|
||||
setFlags(2);
|
||||
}
|
||||
uint32_t SENC::getSampleCount() const {
|
||||
return getInt32(4);
|
||||
}
|
||||
uint32_t SENC::getSampleCount() const{return getInt32(4);}
|
||||
|
||||
#define IV_SIZE 8
|
||||
void SENC::setSample(UUID_SampleEncryption_Sample newSample, size_t index){
|
||||
|
@ -141,8 +122,8 @@ namespace MP4 {
|
|||
ERROR_MSG("First fill intermediate entries!");
|
||||
return;
|
||||
/*
|
||||
//we are now at the end of currently reserved space, reserve more and adapt offset accordingly.
|
||||
int reserveSize = ((index - getSampleCount())) * (IV_SIZE + (getFlags() & 0x02));
|
||||
//we are now at the end of currently reserved space, reserve more and adapt offset
|
||||
accordingly. int reserveSize = ((index - getSampleCount())) * (IV_SIZE + (getFlags() & 0x02));
|
||||
reserveSize += IV_SIZE;
|
||||
if (getFlags() & 0x02){
|
||||
reserveSize += 2 + newSample.Entries.size();
|
||||
|
@ -160,22 +141,19 @@ namespace MP4 {
|
|||
if (getFlags() & 0x02){
|
||||
setInt16(newSample.Entries.size(), myOffset);
|
||||
myOffset += 2;
|
||||
for (std::vector<UUID_SampleEncryption_Sample_Entry>::iterator it = newSample.Entries.begin(); it != newSample.Entries.end(); it++) {
|
||||
for (std::vector<UUID_SampleEncryption_Sample_Entry>::iterator it = newSample.Entries.begin();
|
||||
it != newSample.Entries.end(); it++){
|
||||
setInt16(it->BytesClear, myOffset);
|
||||
myOffset += 2;
|
||||
setInt32(it->BytesEncrypted, myOffset);
|
||||
myOffset += 4;
|
||||
}
|
||||
}
|
||||
if (index >= getSampleCount()) {
|
||||
setInt32(index + 1, 4);
|
||||
}
|
||||
if (index >= getSampleCount()){setInt32(index + 1, 4);}
|
||||
}
|
||||
|
||||
UUID_SampleEncryption_Sample SENC::getSample(size_t index) const{
|
||||
if (index >= getSampleCount()) {
|
||||
return UUID_SampleEncryption_Sample();
|
||||
}
|
||||
if (index >= getSampleCount()){return UUID_SampleEncryption_Sample();}
|
||||
int myOffset = 8;
|
||||
for (unsigned int i = 0; i < index; i++){
|
||||
myOffset += IV_SIZE;
|
||||
|
@ -213,7 +191,8 @@ namespace MP4 {
|
|||
r << std::string(indent + 1, ' ') << "[" << i << "]" << std::endl;
|
||||
r << std::string(indent + 3, ' ') << "Initialization Vector: 0x";
|
||||
for (unsigned int j = 0; j < tmpSample.InitializationVector.size(); j++){
|
||||
r << std::hex << std::setw(2) << std::setfill('0') << (int)tmpSample.InitializationVector[j] << std::dec;
|
||||
r << std::hex << std::setw(2) << std::setfill('0') << (int)tmpSample.InitializationVector[j]
|
||||
<< std::dec;
|
||||
}
|
||||
r << std::endl;
|
||||
if (getFlags() & 0x02){
|
||||
|
@ -221,7 +200,8 @@ namespace MP4 {
|
|||
for (unsigned int j = 0; j < tmpSample.NumberOfEntries; j++){
|
||||
r << std::string(indent + 3, ' ') << "[" << j << "]" << std::endl;
|
||||
r << std::string(indent + 5, ' ') << "Bytes clear: " << tmpSample.Entries[j].BytesClear << std::endl;
|
||||
r << std::string(indent + 5, ' ') << "Bytes encrypted: " << tmpSample.Entries[j].BytesEncrypted << std::endl;
|
||||
r << std::string(indent + 5, ' ')
|
||||
<< "Bytes encrypted: " << tmpSample.Entries[j].BytesEncrypted << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -239,13 +219,9 @@ namespace MP4 {
|
|||
}
|
||||
}
|
||||
|
||||
size_t SAIZ::getDefaultSampleSize(){
|
||||
return getInt24(4);
|
||||
}
|
||||
size_t SAIZ::getDefaultSampleSize(){return getInt24(4);}
|
||||
|
||||
size_t SAIZ::getEntryCount(){
|
||||
return getInt16(7);
|
||||
}
|
||||
size_t SAIZ::getEntryCount(){return getInt16(7);}
|
||||
|
||||
size_t SAIZ::getEntrySize(size_t entryNo){
|
||||
if (entryNo >= getEntryCount()){return -1;}
|
||||
|
@ -254,7 +230,8 @@ namespace MP4 {
|
|||
|
||||
std::string SAIZ::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[saiz] Sample Auxiliary Information Size Box (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[saiz] Sample Auxiliary Information Size Box (" << boxedSize()
|
||||
<< ")" << std::endl;
|
||||
r << fullBox::toPrettyString(indent);
|
||||
r << std::string(indent + 1, ' ') << "Default Sample Size: " << getDefaultSampleSize() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Entry Count: " << getEntryCount() << std::endl;
|
||||
|
@ -270,9 +247,7 @@ namespace MP4 {
|
|||
setInt32(offset, 8);
|
||||
}
|
||||
|
||||
size_t SAIO::getEntryCount(){
|
||||
return getInt32(4);
|
||||
}
|
||||
size_t SAIO::getEntryCount(){return getInt32(4);}
|
||||
|
||||
size_t SAIO::getEntrySize(size_t entryNo){
|
||||
if (entryNo >= getEntryCount()){return -1;}
|
||||
|
@ -281,7 +256,8 @@ namespace MP4 {
|
|||
|
||||
std::string SAIO::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[saio] Sample Auxiliary Information Offset Box (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[saio] Sample Auxiliary Information Offset Box ("
|
||||
<< boxedSize() << ")" << std::endl;
|
||||
r << fullBox::toPrettyString(indent);
|
||||
r << std::string(indent + 1, ' ') << "Entry Count: " << getEntryCount() << std::endl;
|
||||
for (size_t i = 0; i < getEntryCount(); ++i){
|
||||
|
@ -299,73 +275,47 @@ namespace MP4 {
|
|||
setVersion(0);
|
||||
setFlags(2);
|
||||
size_t sampleCount = senc.getSampleCount();
|
||||
for (size_t i = 0; i < sampleCount; ++i){
|
||||
setSample(senc.getSample(i), i);
|
||||
}
|
||||
for (size_t i = 0; i < sampleCount; ++i){setSample(senc.getSample(i), i);}
|
||||
}
|
||||
|
||||
void UUID_SampleEncryption::setVersion(uint32_t newVersion) {
|
||||
setInt8(newVersion, 16);
|
||||
}
|
||||
void UUID_SampleEncryption::setVersion(uint32_t newVersion){setInt8(newVersion, 16);}
|
||||
|
||||
uint32_t UUID_SampleEncryption::getVersion() {
|
||||
return getInt8(16);
|
||||
}
|
||||
uint32_t UUID_SampleEncryption::getVersion(){return getInt8(16);}
|
||||
|
||||
void UUID_SampleEncryption::setFlags(uint32_t newFlags) {
|
||||
setInt24(newFlags, 17);
|
||||
}
|
||||
void UUID_SampleEncryption::setFlags(uint32_t newFlags){setInt24(newFlags, 17);}
|
||||
|
||||
uint32_t UUID_SampleEncryption::getFlags() {
|
||||
return getInt24(17);
|
||||
}
|
||||
uint32_t UUID_SampleEncryption::getFlags(){return getInt24(17);}
|
||||
|
||||
void UUID_SampleEncryption::setAlgorithmID(uint32_t newAlgorithmID){
|
||||
if (getFlags() & 0x01) {
|
||||
setInt24(newAlgorithmID, 20);
|
||||
}
|
||||
if (getFlags() & 0x01){setInt24(newAlgorithmID, 20);}
|
||||
}
|
||||
|
||||
uint32_t UUID_SampleEncryption::getAlgorithmID(){
|
||||
if (getFlags() & 0x01) {
|
||||
return getInt24(20);
|
||||
}
|
||||
if (getFlags() & 0x01){return getInt24(20);}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UUID_SampleEncryption::setIVSize(uint32_t newIVSize){
|
||||
if (getFlags() & 0x01) {
|
||||
setInt8(newIVSize, 23);
|
||||
}
|
||||
if (getFlags() & 0x01){setInt8(newIVSize, 23);}
|
||||
}
|
||||
|
||||
uint32_t UUID_SampleEncryption::getIVSize(){
|
||||
if (getFlags() & 0x01) {
|
||||
return getInt8(23);
|
||||
}
|
||||
if (getFlags() & 0x01){return getInt8(23);}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UUID_SampleEncryption::setKID(std::string newKID){
|
||||
if (newKID == "") {
|
||||
return;
|
||||
}
|
||||
if (newKID == ""){return;}
|
||||
if (getFlags() & 0x01){
|
||||
while (newKID.size() < 16) {
|
||||
newKID += (char)0x00;
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
setInt8(newKID[i], 24 + i);
|
||||
}
|
||||
while (newKID.size() < 16){newKID += (char)0x00;}
|
||||
for (int i = 0; i < 16; i++){setInt8(newKID[i], 24 + i);}
|
||||
}
|
||||
}
|
||||
|
||||
std::string UUID_SampleEncryption::getKID(){
|
||||
if (getFlags() & 0x01){
|
||||
std::string result;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
result += (char)getInt8(24 + i);
|
||||
}
|
||||
for (int i = 0; i < 16; i++){result += (char)getInt8(24 + i);}
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
|
@ -373,9 +323,7 @@ namespace MP4 {
|
|||
|
||||
uint32_t UUID_SampleEncryption::getSampleCount(){
|
||||
int myOffset = 20;
|
||||
if (getFlags() & 0x01) {
|
||||
myOffset += 20;
|
||||
}
|
||||
if (getFlags() & 0x01){myOffset += 20;}
|
||||
return getInt32(myOffset);
|
||||
}
|
||||
|
||||
|
@ -402,22 +350,19 @@ namespace MP4 {
|
|||
if (getFlags() & 0x02){
|
||||
setInt16(newSample.Entries.size(), myOffset);
|
||||
myOffset += 2;
|
||||
for (std::vector<UUID_SampleEncryption_Sample_Entry>::iterator it = newSample.Entries.begin(); it != newSample.Entries.end(); it++) {
|
||||
for (std::vector<UUID_SampleEncryption_Sample_Entry>::iterator it = newSample.Entries.begin();
|
||||
it != newSample.Entries.end(); it++){
|
||||
setInt16(it->BytesClear, myOffset);
|
||||
myOffset += 2;
|
||||
setInt32(it->BytesEncrypted, myOffset);
|
||||
myOffset += 4;
|
||||
}
|
||||
}
|
||||
if (index >= getSampleCount()) {
|
||||
setInt32(index + 1, 20 + (20 * (getFlags() & 0x01)));
|
||||
}
|
||||
if (index >= getSampleCount()){setInt32(index + 1, 20 + (20 * (getFlags() & 0x01)));}
|
||||
}
|
||||
|
||||
UUID_SampleEncryption_Sample UUID_SampleEncryption::getSample(size_t index){
|
||||
if (index >= getSampleCount()) {
|
||||
return UUID_SampleEncryption_Sample();
|
||||
}
|
||||
if (index >= getSampleCount()){return UUID_SampleEncryption_Sample();}
|
||||
int myOffset = 20;
|
||||
myOffset += 20 * (getFlags() & 0x01);
|
||||
myOffset += 4; // sampleCount is here
|
||||
|
@ -449,7 +394,8 @@ namespace MP4 {
|
|||
|
||||
std::string UUID_SampleEncryption::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[a2394f52-5a9b-4f14-a244-6c427c648df4] Sample Encryption Box (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[a2394f52-5a9b-4f14-a244-6c427c648df4] Sample Encryption Box ("
|
||||
<< boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Flags: " << getFlags() << std::endl;
|
||||
if (getFlags() & 0x01){
|
||||
|
@ -463,7 +409,8 @@ namespace MP4 {
|
|||
r << std::string(indent + 1, ' ') << "[" << i << "]" << std::endl;
|
||||
r << std::string(indent + 3, ' ') << "Initialization Vector: 0x";
|
||||
for (unsigned int j = 0; j < tmpSample.InitializationVector.size(); j++){
|
||||
r << std::hex << std::setw(2) << std::setfill('0') << (int)tmpSample.InitializationVector[j] << std::dec;
|
||||
r << std::hex << std::setw(2) << std::setfill('0') << (int)tmpSample.InitializationVector[j]
|
||||
<< std::dec;
|
||||
}
|
||||
r << std::endl;
|
||||
if (getFlags() & 0x02){
|
||||
|
@ -471,7 +418,8 @@ namespace MP4 {
|
|||
for (unsigned int j = 0; j < tmpSample.NumberOfEntries; j++){
|
||||
r << std::string(indent + 3, ' ') << "[" << j << "]" << std::endl;
|
||||
r << std::string(indent + 5, ' ') << "Bytes clear: " << tmpSample.Entries[j].BytesClear << std::endl;
|
||||
r << std::string(indent + 5, ' ') << "Bytes encrypted: " << tmpSample.Entries[j].BytesEncrypted << std::endl;
|
||||
r << std::string(indent + 5, ' ')
|
||||
<< "Bytes encrypted: " << tmpSample.Entries[j].BytesEncrypted << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -482,37 +430,21 @@ namespace MP4 {
|
|||
setUUID((std::string) "8974dbce-7be7-4c51-84f9-7148f9882554");
|
||||
}
|
||||
|
||||
void UUID_TrackEncryption::setVersion(uint32_t newVersion) {
|
||||
setInt8(newVersion, 16);
|
||||
}
|
||||
void UUID_TrackEncryption::setVersion(uint32_t newVersion){setInt8(newVersion, 16);}
|
||||
|
||||
uint32_t UUID_TrackEncryption::getVersion() {
|
||||
return getInt8(16);
|
||||
}
|
||||
uint32_t UUID_TrackEncryption::getVersion(){return getInt8(16);}
|
||||
|
||||
void UUID_TrackEncryption::setFlags(uint32_t newFlags) {
|
||||
setInt24(newFlags, 17);
|
||||
}
|
||||
void UUID_TrackEncryption::setFlags(uint32_t newFlags){setInt24(newFlags, 17);}
|
||||
|
||||
uint32_t UUID_TrackEncryption::getFlags() {
|
||||
return getInt24(17);
|
||||
}
|
||||
uint32_t UUID_TrackEncryption::getFlags(){return getInt24(17);}
|
||||
|
||||
void UUID_TrackEncryption::setDefaultAlgorithmID(uint32_t newID) {
|
||||
setInt24(newID, 20);
|
||||
}
|
||||
void UUID_TrackEncryption::setDefaultAlgorithmID(uint32_t newID){setInt24(newID, 20);}
|
||||
|
||||
uint32_t UUID_TrackEncryption::getDefaultAlgorithmID() {
|
||||
return getInt24(20);
|
||||
}
|
||||
uint32_t UUID_TrackEncryption::getDefaultAlgorithmID(){return getInt24(20);}
|
||||
|
||||
void UUID_TrackEncryption::setDefaultIVSize(uint8_t newIVSize) {
|
||||
setInt8(newIVSize, 23);
|
||||
}
|
||||
void UUID_TrackEncryption::setDefaultIVSize(uint8_t newIVSize){setInt8(newIVSize, 23);}
|
||||
|
||||
uint8_t UUID_TrackEncryption::getDefaultIVSize() {
|
||||
return getInt8(23);
|
||||
}
|
||||
uint8_t UUID_TrackEncryption::getDefaultIVSize(){return getInt8(23);}
|
||||
|
||||
void UUID_TrackEncryption::setDefaultKID(std::string newKID){
|
||||
for (unsigned int i = 0; i < 16; i++){
|
||||
|
@ -526,18 +458,18 @@ namespace MP4 {
|
|||
|
||||
std::string UUID_TrackEncryption::getDefaultKID(){
|
||||
std::string result;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
result += getInt8(24 + i);
|
||||
}
|
||||
for (int i = 0; i < 16; i++){result += getInt8(24 + i);}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string UUID_TrackEncryption::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[8974dbce-7be7-4c51-84f9-7148f9882554] Track Encryption Box (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[8974dbce-7be7-4c51-84f9-7148f9882554] Track Encryption Box ("
|
||||
<< boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Version: " << getVersion() << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Flags: " << getFlags() << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Default Algorithm ID: " << std::hex << getDefaultAlgorithmID() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Default Algorithm ID: " << std::hex
|
||||
<< getDefaultAlgorithmID() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Default IV Size: " << (int)getDefaultIVSize() << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Default KID: 16 bytes of binary data." << std::endl;
|
||||
return r.str();
|
||||
|
@ -551,17 +483,11 @@ namespace MP4 {
|
|||
setInt8(newVersion, 16);
|
||||
}
|
||||
|
||||
uint32_t UUID_ProtectionSystemSpecificHeader::getVersion() {
|
||||
return getInt8(16);
|
||||
}
|
||||
uint32_t UUID_ProtectionSystemSpecificHeader::getVersion(){return getInt8(16);}
|
||||
|
||||
void UUID_ProtectionSystemSpecificHeader::setFlags(uint32_t newFlags) {
|
||||
setInt24(newFlags, 17);
|
||||
}
|
||||
void UUID_ProtectionSystemSpecificHeader::setFlags(uint32_t newFlags){setInt24(newFlags, 17);}
|
||||
|
||||
uint32_t UUID_ProtectionSystemSpecificHeader::getFlags() {
|
||||
return getInt24(17);
|
||||
}
|
||||
uint32_t UUID_ProtectionSystemSpecificHeader::getFlags(){return getInt24(17);}
|
||||
|
||||
void UUID_ProtectionSystemSpecificHeader::setSystemID(std::string newID){
|
||||
for (unsigned int i = 0; i < 16; i++){
|
||||
|
@ -575,34 +501,27 @@ namespace MP4 {
|
|||
|
||||
std::string UUID_ProtectionSystemSpecificHeader::getSystemID(){
|
||||
std::string result;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
result += getInt8(20 + i);
|
||||
}
|
||||
for (int i = 0; i < 16; i++){result += getInt8(20 + i);}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t UUID_ProtectionSystemSpecificHeader::getDataSize() {
|
||||
return getInt32(36);
|
||||
}
|
||||
uint32_t UUID_ProtectionSystemSpecificHeader::getDataSize(){return getInt32(36);}
|
||||
|
||||
void UUID_ProtectionSystemSpecificHeader::setData(std::string newData){
|
||||
setInt32(newData.size(), 36);
|
||||
for (unsigned int i = 0; i < newData.size(); i++) {
|
||||
setInt8(newData[i], 40 + i);
|
||||
}
|
||||
for (unsigned int i = 0; i < newData.size(); i++){setInt8(newData[i], 40 + i);}
|
||||
}
|
||||
|
||||
std::string UUID_ProtectionSystemSpecificHeader::getData(){
|
||||
std::string result;
|
||||
for (unsigned int i = 0; i < getDataSize(); i++) {
|
||||
result += getInt8(40 + i);
|
||||
}
|
||||
for (unsigned int i = 0; i < getDataSize(); i++){result += getInt8(40 + i);}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string UUID_ProtectionSystemSpecificHeader::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[d08a4f18-10f3-4a82-b6c8-32d8aba183d3] Protection System Specific Header Box (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[d08a4f18-10f3-4a82-b6c8-32d8aba183d3] Protection System Specific Header Box ("
|
||||
<< boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Version: " << getVersion() << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Flags: " << getFlags() << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "System ID: " << getSystemID() << std::endl;
|
||||
|
@ -611,14 +530,10 @@ namespace MP4 {
|
|||
return r.str();
|
||||
}
|
||||
|
||||
SINF::SINF() {
|
||||
memcpy(data + 4, "sinf", 4);
|
||||
}
|
||||
SINF::SINF(){memcpy(data + 4, "sinf", 4);}
|
||||
|
||||
void SINF::setEntry(Box &newEntry, uint32_t no){
|
||||
if (no > 4) {
|
||||
return;
|
||||
}
|
||||
if (no > 4){return;}
|
||||
int tempLoc = 0;
|
||||
for (unsigned int i = 0; i < no; i++){
|
||||
tempLoc += Box(getBox(tempLoc).asBox(), false).boxedSize();
|
||||
|
@ -628,13 +543,9 @@ namespace MP4 {
|
|||
|
||||
Box &SINF::getEntry(uint32_t no){
|
||||
static Box ret = Box((char *)"\000\000\000\010erro", false);
|
||||
if (no > 4) {
|
||||
return ret;
|
||||
}
|
||||
if (no > 4){return ret;}
|
||||
int tempLoc = 0;
|
||||
for (unsigned int i = 0; i < no; i++) {
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
for (unsigned int i = 0; i < no; i++){tempLoc += getBoxLen(tempLoc);}
|
||||
return getBox(tempLoc);
|
||||
}
|
||||
|
||||
|
@ -643,9 +554,7 @@ namespace MP4 {
|
|||
std::cerr << payloadOffset << std::endl;
|
||||
r << std::string(indent, ' ') << "[sinf] Protection Scheme Info Box (" << boxedSize() << ")" << std::endl;
|
||||
for (int i = 0; i < 4; i++){
|
||||
if (!getEntry(i).isType("erro")) {
|
||||
r << getEntry(i).toPrettyString(indent + 2);
|
||||
}
|
||||
if (!getEntry(i).isType("erro")){r << getEntry(i).toPrettyString(indent + 2);}
|
||||
}
|
||||
r << std::endl;
|
||||
return r.str();
|
||||
|
@ -666,9 +575,7 @@ namespace MP4 {
|
|||
}
|
||||
}
|
||||
|
||||
std::string FRMA::getOriginalFormat() {
|
||||
return std::string(payload(), 4);
|
||||
}
|
||||
std::string FRMA::getOriginalFormat(){return std::string(payload(), 4);}
|
||||
|
||||
std::string FRMA::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
|
@ -683,21 +590,13 @@ namespace MP4 {
|
|||
setSchemeVersion(schemeVersion);
|
||||
}
|
||||
|
||||
void SCHM::setSchemeType(uint32_t newType) {
|
||||
setInt32(htonl(newType), 4);
|
||||
}
|
||||
void SCHM::setSchemeType(uint32_t newType){setInt32(htonl(newType), 4);}
|
||||
|
||||
uint32_t SCHM::getSchemeType() {
|
||||
return ntohl(getInt32(4));
|
||||
}
|
||||
uint32_t SCHM::getSchemeType(){return ntohl(getInt32(4));}
|
||||
|
||||
void SCHM::setSchemeVersion(uint32_t newVersion) {
|
||||
setInt32(htonl(newVersion), 8);
|
||||
}
|
||||
void SCHM::setSchemeVersion(uint32_t newVersion){setInt32(htonl(newVersion), 8);}
|
||||
|
||||
uint32_t SCHM::getSchemeVersion() {
|
||||
return ntohl(getInt32(8));
|
||||
}
|
||||
uint32_t SCHM::getSchemeVersion(){return ntohl(getInt32(8));}
|
||||
|
||||
void SCHM::setSchemeURI(std::string newURI){
|
||||
setFlags(getFlags() | 0x01);
|
||||
|
@ -705,9 +604,7 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
std::string SCHM::getSchemeURI(){
|
||||
if (getFlags() & 0x01) {
|
||||
return getString(12);
|
||||
}
|
||||
if (getFlags() & 0x01){return getString(12);}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -718,24 +615,19 @@ namespace MP4 {
|
|||
int tmpInt = getSchemeType();
|
||||
sprintf(tmpStr, "%.4s", (char *)&tmpInt);
|
||||
r << std::string(indent + 2, ' ') << "SchemeType: " << std::string(tmpStr, 4) << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "SchemeVersion: 0x" << std::hex << std::setw(8) << std::setfill('0') << getSchemeVersion() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "SchemeVersion: 0x" << std::hex << std::setw(8)
|
||||
<< std::setfill('0') << getSchemeVersion() << std::dec << std::endl;
|
||||
if (getFlags() & 0x01){
|
||||
r << std::string(indent + 2, ' ') << "SchemeURI: " << getSchemeURI() << std::endl;
|
||||
}
|
||||
return r.str();
|
||||
}
|
||||
|
||||
SCHI::SCHI() {
|
||||
memcpy(data + 4, "schi", 4);
|
||||
}
|
||||
SCHI::SCHI(){memcpy(data + 4, "schi", 4);}
|
||||
|
||||
void SCHI::setContent(Box & newContent) {
|
||||
setBox(newContent, 0);
|
||||
}
|
||||
void SCHI::setContent(Box &newContent){setBox(newContent, 0);}
|
||||
|
||||
Box & SCHI::getContent() {
|
||||
return getBox(0);
|
||||
}
|
||||
Box &SCHI::getContent(){return getBox(0);}
|
||||
|
||||
std::string SCHI::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
|
@ -744,4 +636,4 @@ namespace MP4 {
|
|||
return r.str();
|
||||
}
|
||||
|
||||
}
|
||||
}// namespace MP4
|
||||
|
|
|
@ -152,4 +152,4 @@ namespace MP4 {
|
|||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
|
||||
}
|
||||
}// namespace MP4
|
||||
|
|
1652
lib/mp4_generic.cpp
1652
lib/mp4_generic.cpp
File diff suppressed because it is too large
Load diff
|
@ -102,7 +102,6 @@ namespace MP4 {
|
|||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
|
||||
|
||||
class AVCC : public Box{
|
||||
public:
|
||||
AVCC();
|
||||
|
@ -236,11 +235,8 @@ namespace MP4 {
|
|||
std::string toPrettyString(uint32_t indent = 0); ///< put it into a pretty string
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Implements ISO 14496-1 SLConfigDescrTag
|
||||
class SLCDescriptor: public Descriptor{
|
||||
};
|
||||
class SLCDescriptor : public Descriptor{};
|
||||
|
||||
class ESDS : public fullBox{
|
||||
public:
|
||||
|
@ -316,7 +312,6 @@ namespace MP4 {
|
|||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
|
||||
|
||||
class MFRA : public containerBox{
|
||||
public:
|
||||
MFRA();
|
||||
|
@ -525,6 +520,7 @@ namespace MP4 {
|
|||
void setHeight(double newHeight);
|
||||
double getHeight();
|
||||
std::string toPrettyString(uint32_t indent = 0);
|
||||
|
||||
protected:
|
||||
void initialize();
|
||||
};
|
||||
|
@ -789,21 +785,15 @@ namespace MP4 {
|
|||
FontTableBox getFontTableBox();
|
||||
void setFontTableBox(FontTableBox f);
|
||||
|
||||
|
||||
|
||||
std::string toPrettyTextString(uint32_t indent = 0, std::string name = "");
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TX3G : public TextSampleEntry{
|
||||
public:
|
||||
TX3G();
|
||||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MP4A : public AudioSampleEntry{
|
||||
public:
|
||||
MP4A();
|
||||
|
@ -905,5 +895,4 @@ namespace MP4 {
|
|||
uint16_t getMediaRateFraction(uint32_t cnt);
|
||||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
}
|
||||
|
||||
}// namespace MP4
|
||||
|
|
138
lib/mp4_ms.cpp
138
lib/mp4_ms.cpp
|
@ -1,5 +1,5 @@
|
|||
#include "mp4_ms.h"
|
||||
#include "mp4_encryption.h" /*LTS*/
|
||||
#include "mp4_ms.h"
|
||||
|
||||
namespace MP4{
|
||||
|
||||
|
@ -10,26 +10,15 @@ namespace MP4 {
|
|||
return 0;
|
||||
}
|
||||
|
||||
SDTP::SDTP(){memcpy(data + 4, "sdtp", 4);}
|
||||
|
||||
SDTP::SDTP() {
|
||||
memcpy(data + 4, "sdtp", 4);
|
||||
}
|
||||
void SDTP::setVersion(uint32_t newVersion){setInt8(newVersion, 0);}
|
||||
|
||||
void SDTP::setVersion(uint32_t newVersion) {
|
||||
setInt8(newVersion, 0);
|
||||
}
|
||||
uint32_t SDTP::getVersion(){return getInt8(0);}
|
||||
|
||||
uint32_t SDTP::getVersion() {
|
||||
return getInt8(0);
|
||||
}
|
||||
void SDTP::setValue(uint32_t newValue, size_t index){setInt8(newValue, index);}
|
||||
|
||||
void SDTP::setValue(uint32_t newValue, size_t index) {
|
||||
setInt8(newValue, index);
|
||||
}
|
||||
|
||||
uint32_t SDTP::getValue(size_t index) {
|
||||
return getInt8(index);
|
||||
}
|
||||
uint32_t SDTP::getValue(size_t index){return getInt8(index);}
|
||||
|
||||
std::string SDTP::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
|
@ -39,46 +28,22 @@ namespace MP4 {
|
|||
uint32_t val = getValue(i + 3);
|
||||
r << std::string(indent + 2, ' ') << "[" << i << "] = ";
|
||||
switch (val & 3){
|
||||
case 0:
|
||||
r << " ";
|
||||
break;
|
||||
case 1:
|
||||
r << "Redundant, ";
|
||||
break;
|
||||
case 2:
|
||||
r << "Not redundant, ";
|
||||
break;
|
||||
case 3:
|
||||
r << "Error, ";
|
||||
break;
|
||||
case 0: r << " "; break;
|
||||
case 1: r << "Redundant, "; break;
|
||||
case 2: r << "Not redundant, "; break;
|
||||
case 3: r << "Error, "; break;
|
||||
}
|
||||
switch (val & 12){
|
||||
case 0:
|
||||
r << " ";
|
||||
break;
|
||||
case 4:
|
||||
r << "Not disposable, ";
|
||||
break;
|
||||
case 8:
|
||||
r << "Disposable, ";
|
||||
break;
|
||||
case 12:
|
||||
r << "Error, ";
|
||||
break;
|
||||
case 0: r << " "; break;
|
||||
case 4: r << "Not disposable, "; break;
|
||||
case 8: r << "Disposable, "; break;
|
||||
case 12: r << "Error, "; break;
|
||||
}
|
||||
switch (val & 48){
|
||||
case 0:
|
||||
r << " ";
|
||||
break;
|
||||
case 16:
|
||||
r << "IFrame, ";
|
||||
break;
|
||||
case 32:
|
||||
r << "Not IFrame, ";
|
||||
break;
|
||||
case 48:
|
||||
r << "Error, ";
|
||||
break;
|
||||
case 0: r << " "; break;
|
||||
case 16: r << "IFrame, "; break;
|
||||
case 32: r << "Not IFrame, "; break;
|
||||
case 48: r << "Error, "; break;
|
||||
}
|
||||
r << "(" << val << ")" << std::endl;
|
||||
}
|
||||
|
@ -95,9 +60,7 @@ namespace MP4 {
|
|||
std::stringstream r;
|
||||
r << std::hex;
|
||||
for (int i = 0; i < 16; ++i){
|
||||
if (i == 4 || i == 6 || i == 8 || i == 10) {
|
||||
r << "-";
|
||||
}
|
||||
if (i == 4 || i == 6 || i == 8 || i == 10){r << "-";}
|
||||
r << std::setfill('0') << std::setw(2) << std::right << (int)(data[8 + i]);
|
||||
}
|
||||
return r.str();
|
||||
|
@ -105,23 +68,17 @@ namespace MP4 {
|
|||
|
||||
void UUID::setUUID(const std::string &uuid_string){
|
||||
// reset UUID to zero
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
((uint32_t *)(data + 8))[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 4; ++i){((uint32_t *)(data + 8))[i] = 0;}
|
||||
// set the UUID from the string, char by char
|
||||
int i = 0;
|
||||
for (size_t j = 0; j < uuid_string.size(); ++j){
|
||||
if (uuid_string[j] == '-') {
|
||||
continue;
|
||||
}
|
||||
if (uuid_string[j] == '-'){continue;}
|
||||
data[8 + i / 2] |= (c2hex(uuid_string[j]) << ((~i & 1) << 2));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void UUID::setUUID(const char * raw_uuid) {
|
||||
memcpy(data + 8, raw_uuid, 16);
|
||||
}
|
||||
void UUID::setUUID(const char *raw_uuid){memcpy(data + 8, raw_uuid, 16);}
|
||||
|
||||
std::string UUID::toPrettyString(uint32_t indent){
|
||||
std::string UUID = getUUID();
|
||||
|
@ -153,29 +110,17 @@ namespace MP4 {
|
|||
setUUID((std::string) "d4807ef2-ca39-4695-8e54-26cb9e46a79f");
|
||||
}
|
||||
|
||||
void UUID_TrackFragmentReference::setVersion(uint32_t newVersion) {
|
||||
setInt8(newVersion, 16);
|
||||
}
|
||||
void UUID_TrackFragmentReference::setVersion(uint32_t newVersion){setInt8(newVersion, 16);}
|
||||
|
||||
uint32_t UUID_TrackFragmentReference::getVersion() {
|
||||
return getInt8(16);
|
||||
}
|
||||
uint32_t UUID_TrackFragmentReference::getVersion(){return getInt8(16);}
|
||||
|
||||
void UUID_TrackFragmentReference::setFlags(uint32_t newFlags) {
|
||||
setInt24(newFlags, 17);
|
||||
}
|
||||
void UUID_TrackFragmentReference::setFlags(uint32_t newFlags){setInt24(newFlags, 17);}
|
||||
|
||||
uint32_t UUID_TrackFragmentReference::getFlags() {
|
||||
return getInt24(17);
|
||||
}
|
||||
uint32_t UUID_TrackFragmentReference::getFlags(){return getInt24(17);}
|
||||
|
||||
void UUID_TrackFragmentReference::setFragmentCount(uint32_t newCount) {
|
||||
setInt8(newCount, 20);
|
||||
}
|
||||
void UUID_TrackFragmentReference::setFragmentCount(uint32_t newCount){setInt8(newCount, 20);}
|
||||
|
||||
uint32_t UUID_TrackFragmentReference::getFragmentCount() {
|
||||
return getInt8(20);
|
||||
}
|
||||
uint32_t UUID_TrackFragmentReference::getFragmentCount(){return getInt8(20);}
|
||||
|
||||
void UUID_TrackFragmentReference::setTime(size_t num, uint64_t newTime){
|
||||
if (getVersion() == 0){
|
||||
|
@ -211,12 +156,14 @@ namespace MP4 {
|
|||
|
||||
std::string UUID_TrackFragmentReference::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[d4807ef2-ca39-4695-8e54-26cb9e46a79f] Track Fragment Reference (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[d4807ef2-ca39-4695-8e54-26cb9e46a79f] Track Fragment Reference ("
|
||||
<< boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Fragments: " << getFragmentCount() << std::endl;
|
||||
int j = getFragmentCount();
|
||||
for (int i = 0; i < j; ++i){
|
||||
r << std::string(indent + 2, ' ') << "[" << i << "] Time = " << getTime(i) << ", Duration = " << getDuration(i) << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "[" << i << "] Time = " << getTime(i)
|
||||
<< ", Duration = " << getDuration(i) << std::endl;
|
||||
}
|
||||
return r.str();
|
||||
}
|
||||
|
@ -227,21 +174,13 @@ namespace MP4 {
|
|||
setFlags(0);
|
||||
}
|
||||
|
||||
void UUID_TFXD::setVersion(uint32_t newVersion) {
|
||||
setInt8(newVersion, 16);
|
||||
}
|
||||
void UUID_TFXD::setVersion(uint32_t newVersion){setInt8(newVersion, 16);}
|
||||
|
||||
uint32_t UUID_TFXD::getVersion() {
|
||||
return getInt8(16);
|
||||
}
|
||||
uint32_t UUID_TFXD::getVersion(){return getInt8(16);}
|
||||
|
||||
void UUID_TFXD::setFlags(uint32_t newFlags) {
|
||||
setInt24(newFlags, 17);
|
||||
}
|
||||
void UUID_TFXD::setFlags(uint32_t newFlags){setInt24(newFlags, 17);}
|
||||
|
||||
uint32_t UUID_TFXD::getFlags() {
|
||||
return getInt24(17);
|
||||
}
|
||||
uint32_t UUID_TFXD::getFlags(){return getInt24(17);}
|
||||
|
||||
void UUID_TFXD::setTime(uint64_t newTime){
|
||||
if (getVersion() == 0){
|
||||
|
@ -278,10 +217,11 @@ namespace MP4 {
|
|||
std::string UUID_TFXD::toPrettyString(uint32_t indent){
|
||||
std::stringstream r;
|
||||
setUUID((std::string) "6d1d9b05-42d5-44e6-80e2-141daff757b2");
|
||||
r << std::string(indent, ' ') << "[6d1d9b05-42d5-44e6-80e2-141daff757b2] TFXD Box (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent, ' ') << "[6d1d9b05-42d5-44e6-80e2-141daff757b2] TFXD Box ("
|
||||
<< boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Time = " << getTime() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "Duration = " << getDuration() << std::endl;
|
||||
return r.str();
|
||||
}
|
||||
}
|
||||
}// namespace MP4
|
||||
|
|
|
@ -50,4 +50,4 @@ namespace MP4 {
|
|||
uint64_t getDuration();
|
||||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
}
|
||||
}// namespace MP4
|
||||
|
|
|
@ -81,4 +81,3 @@ namespace Mpeg{
|
|||
return res;
|
||||
}
|
||||
}// namespace Mpeg
|
||||
|
||||
|
|
|
@ -42,4 +42,3 @@ namespace Mpeg{
|
|||
void parseMPEG2Headers(const char *hdr, uint32_t len, MPEG2Info &mpInfo);
|
||||
MPEG2Info parseMPEG2Headers(const char *hdr, uint32_t len);
|
||||
}// namespace Mpeg
|
||||
|
||||
|
|
|
@ -34,8 +34,7 @@ namespace nalu{
|
|||
size_t dataLen = data.size();
|
||||
size_t resPtr = 2;
|
||||
while (dataPtr + 2 < dataLen){
|
||||
if (!data[dataPtr] && !data[dataPtr + 1] &&
|
||||
data[dataPtr + 2] == 3){// We have found an emulation prevention
|
||||
if (!data[dataPtr] && !data[dataPtr + 1] && data[dataPtr + 2] == 3){// We have found an emulation prevention
|
||||
result[resPtr++] = data[dataPtr++];
|
||||
result[resPtr++] = data[dataPtr++];
|
||||
dataPtr++; // Skip the emulation prevention byte
|
||||
|
@ -129,4 +128,3 @@ namespace nalu{
|
|||
return newOffset;
|
||||
}
|
||||
}// namespace nalu
|
||||
|
||||
|
|
|
@ -18,4 +18,3 @@ namespace nalu{
|
|||
const char *scanAnnexB(const char *data, uint32_t dataSize);
|
||||
const char *nalEndPosition(const char *data, uint32_t dataSize);
|
||||
}// namespace nalu
|
||||
|
||||
|
|
270
lib/ogg.cpp
270
lib/ogg.cpp
|
@ -1,11 +1,11 @@
|
|||
#include "ogg.h"
|
||||
#include "bitstream.h"
|
||||
#include "defines.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
#include "ogg.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <iomanip>
|
||||
#include "bitstream.h"
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace OGG{
|
||||
|
||||
|
@ -21,13 +21,9 @@ namespace OGG {
|
|||
res.push_back(0);
|
||||
for (unsigned int i = 0; i < len; i++){
|
||||
*res.rbegin() += data[i];
|
||||
if (data[i] != 0xFF){
|
||||
res.push_back(0);
|
||||
}
|
||||
}
|
||||
if (*res.rbegin() == 0){
|
||||
res.resize(res.size() - 1);
|
||||
if (data[i] != 0xFF){res.push_back(0);}
|
||||
}
|
||||
if (*res.rbegin() == 0){res.resize(res.size() - 1);}
|
||||
return res;
|
||||
}
|
||||
inline long long unsigned int get_64(char *data){
|
||||
|
@ -55,7 +51,6 @@ namespace OGG {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
inline void set_32(char *data, long unsigned int val){
|
||||
for (int i = 0; i < 4; ++i){
|
||||
data[i] = val & 0xFF;
|
||||
|
@ -63,7 +58,6 @@ namespace OGG {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Page::Page(){
|
||||
framesSeen = 0;
|
||||
lastKeyFrame = 0;
|
||||
|
@ -98,9 +92,7 @@ namespace OGG {
|
|||
|
||||
unsigned int Page::calcPayloadSize(){
|
||||
unsigned int retVal = 0;
|
||||
for (unsigned int i = 0; i < segments.size(); i++){
|
||||
retVal += segments[i].size();
|
||||
}
|
||||
for (unsigned int i = 0; i < segments.size(); i++){retVal += segments[i].size();}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -109,9 +101,7 @@ namespace OGG {
|
|||
int len = newData.size();
|
||||
int total = 0;
|
||||
segments.clear();
|
||||
if (newData.size() < 27){
|
||||
return false;
|
||||
}
|
||||
if (newData.size() < 27){return false;}
|
||||
if (newData.substr(0, 4) != "OggS"){
|
||||
FAIL_MSG("Invalid Ogg page encountered (magic number wrong: %s) - cannot continue", newData.c_str());
|
||||
return false;
|
||||
|
@ -129,9 +119,7 @@ namespace OGG {
|
|||
total += 27;
|
||||
// return false if the segment is not complete
|
||||
total += getPageSegments();
|
||||
if(total >= len){
|
||||
return false;
|
||||
}
|
||||
if (total >= len){return false;}
|
||||
|
||||
newData.erase(0, getPageSegments() + 27);
|
||||
for (std::deque<unsigned int>::iterator it = segSizes.begin(); it != segSizes.end(); it++){
|
||||
|
@ -143,7 +131,6 @@ namespace OGG {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Page::read(FILE *inFile){
|
||||
segments.clear();
|
||||
int oriPos = ftell(inFile);
|
||||
|
@ -166,11 +153,10 @@ namespace OGG {
|
|||
for (std::deque<unsigned int>::iterator it = segSizes.begin(); it != segSizes.end(); it++){
|
||||
if (*it){
|
||||
char *thisSeg = (char *)malloc(*it * sizeof(char));
|
||||
if (!thisSeg){
|
||||
WARN_MSG("malloc failed");
|
||||
}
|
||||
if (!thisSeg){WARN_MSG("malloc failed");}
|
||||
if (!fread(thisSeg, *it, 1, inFile)){
|
||||
WARN_MSG("Unable to read a segment @ pos %d segment size: %d getPageSegments: %d", oriPos, *it, getPageSegments());
|
||||
WARN_MSG("Unable to read a segment @ pos %d segment size: %d getPageSegments: %d", oriPos,
|
||||
*it, getPageSegments());
|
||||
fseek(inFile, oriPos, SEEK_SET);
|
||||
return false;
|
||||
}
|
||||
|
@ -179,7 +165,6 @@ namespace OGG {
|
|||
}else{
|
||||
segments.push_back(std::string("", 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -195,79 +180,47 @@ namespace OGG {
|
|||
}
|
||||
|
||||
const char *Page::getSegment(unsigned int index){
|
||||
if (index >= segments.size()){
|
||||
return 0;
|
||||
}
|
||||
if (index >= segments.size()){return 0;}
|
||||
return segments[index].data();
|
||||
}
|
||||
|
||||
unsigned long Page::getSegmentLen(unsigned int index){
|
||||
if (index >= segments.size()){
|
||||
return 0;
|
||||
}
|
||||
if (index >= segments.size()){return 0;}
|
||||
return segments[index].size();
|
||||
}
|
||||
|
||||
void Page::setMagicNumber(){
|
||||
memcpy(data, "OggS", 4);
|
||||
}
|
||||
void Page::setMagicNumber(){memcpy(data, "OggS", 4);}
|
||||
|
||||
char Page::getVersion(){
|
||||
return data[4];
|
||||
}
|
||||
char Page::getVersion(){return data[4];}
|
||||
|
||||
void Page::setVersion(char newVal){
|
||||
data[4] = newVal;
|
||||
}
|
||||
void Page::setVersion(char newVal){data[4] = newVal;}
|
||||
|
||||
char Page::getHeaderType(){
|
||||
return data[5];
|
||||
}
|
||||
char Page::getHeaderType(){return data[5];}
|
||||
|
||||
void Page::setHeaderType(char newVal){
|
||||
data[5] = newVal;
|
||||
}
|
||||
void Page::setHeaderType(char newVal){data[5] = newVal;}
|
||||
|
||||
long long unsigned int Page::getGranulePosition(){
|
||||
return get_64(data + 6);
|
||||
}
|
||||
long long unsigned int Page::getGranulePosition(){return get_64(data + 6);}
|
||||
|
||||
void Page::setGranulePosition(long long unsigned int newVal){
|
||||
set_64(data + 6, newVal);
|
||||
}
|
||||
void Page::setGranulePosition(long long unsigned int newVal){set_64(data + 6, newVal);}
|
||||
|
||||
long unsigned int Page::getBitstreamSerialNumber(){
|
||||
// return ntohl(((long unsigned int*)(data+14))[0]);
|
||||
return get_32(data + 14);
|
||||
}
|
||||
|
||||
void Page::setBitstreamSerialNumber(long unsigned int newVal){
|
||||
set_32(data + 14, newVal);
|
||||
}
|
||||
void Page::setBitstreamSerialNumber(long unsigned int newVal){set_32(data + 14, newVal);}
|
||||
|
||||
long unsigned int Page::getPageSequenceNumber(){
|
||||
return get_32(data + 18);
|
||||
}
|
||||
long unsigned int Page::getPageSequenceNumber(){return get_32(data + 18);}
|
||||
|
||||
void Page::setPageSequenceNumber(long unsigned int newVal){
|
||||
set_32(data + 18, newVal);
|
||||
}
|
||||
void Page::setPageSequenceNumber(long unsigned int newVal){set_32(data + 18, newVal);}
|
||||
|
||||
long unsigned int Page::getCRCChecksum(){
|
||||
return get_32(data + 22);
|
||||
}
|
||||
long unsigned int Page::getCRCChecksum(){return get_32(data + 22);}
|
||||
|
||||
void Page::setCRCChecksum(long unsigned int newVal){
|
||||
set_32(data + 22, newVal);
|
||||
}
|
||||
void Page::setCRCChecksum(long unsigned int newVal){set_32(data + 22, newVal);}
|
||||
|
||||
char Page::getPageSegments(){
|
||||
return data[26];
|
||||
}
|
||||
char Page::getPageSegments(){return data[26];}
|
||||
|
||||
inline void Page::setPageSegments(char newVal){
|
||||
data[26] = newVal;
|
||||
}
|
||||
inline void Page::setPageSegments(char newVal){data[26] = newVal;}
|
||||
|
||||
bool Page::verifyChecksum(){
|
||||
if (getCRCChecksum() == calcChecksum()){// NOTE: calcChecksum is currently not functional (it will always return 0)
|
||||
|
@ -279,9 +232,7 @@ namespace OGG {
|
|||
|
||||
bool Page::possiblyContinued(){
|
||||
if (getPageSegments() == 255){
|
||||
if (data[281] == 255){
|
||||
return true;
|
||||
}
|
||||
if (data[281] == 255){return true;}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -294,18 +245,13 @@ namespace OGG {
|
|||
if (!getHeaderType()){
|
||||
r << " Normal";
|
||||
}else{
|
||||
if (getHeaderType() & Continued){
|
||||
r << " Continued";
|
||||
}
|
||||
if (getHeaderType() & BeginOfStream){
|
||||
r << " BeginOfStream";
|
||||
}
|
||||
if (getHeaderType() & EndOfStream){
|
||||
r << " EndOfStream";
|
||||
}
|
||||
if (getHeaderType() & Continued){r << " Continued";}
|
||||
if (getHeaderType() & BeginOfStream){r << " BeginOfStream";}
|
||||
if (getHeaderType() & EndOfStream){r << " EndOfStream";}
|
||||
}
|
||||
r << " (" << (int)getHeaderType() << ")" << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Granule position: " << std::hex << std::setw(16) << std::setfill('0') << getGranulePosition() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Granule position: " << std::hex << std::setw(16)
|
||||
<< std::setfill('0') << getGranulePosition() << std::dec << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Bitstream number: " << getBitstreamSerialNumber() << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Sequence number: " << getPageSequenceNumber() << std::endl;
|
||||
r << std::string(indent + 2, ' ') << "Checksum Correct: " << verifyChecksum() << std::endl;
|
||||
|
@ -313,78 +259,49 @@ namespace OGG {
|
|||
r << std::string(indent + 2, ' ') << "Checksum: " << getCRCChecksum() << std::endl;
|
||||
r << std::string(indent + 2, ' ') << (int)getPageSegments() << " segments:" << std::endl;
|
||||
r << std::string(indent + 3, ' ');
|
||||
for (unsigned int i = 0; i < segments.size(); i++){
|
||||
r << " " << segments[i].size();
|
||||
}
|
||||
for (unsigned int i = 0; i < segments.size(); i++){r << " " << segments[i].size();}
|
||||
r << std::endl;
|
||||
return r.str();
|
||||
}
|
||||
|
||||
inline unsigned int crc32(unsigned int crc, const char *data, size_t len){
|
||||
static const unsigned int table[256] ={
|
||||
0x00000000U, 0x04C11DB7U, 0x09823B6EU, 0x0D4326D9U,
|
||||
0x130476DCU, 0x17C56B6BU, 0x1A864DB2U, 0x1E475005U,
|
||||
0x2608EDB8U, 0x22C9F00FU, 0x2F8AD6D6U, 0x2B4BCB61U,
|
||||
0x350C9B64U, 0x31CD86D3U, 0x3C8EA00AU, 0x384FBDBDU,
|
||||
0x4C11DB70U, 0x48D0C6C7U, 0x4593E01EU, 0x4152FDA9U,
|
||||
0x5F15ADACU, 0x5BD4B01BU, 0x569796C2U, 0x52568B75U,
|
||||
0x6A1936C8U, 0x6ED82B7FU, 0x639B0DA6U, 0x675A1011U,
|
||||
0x791D4014U, 0x7DDC5DA3U, 0x709F7B7AU, 0x745E66CDU,
|
||||
0x9823B6E0U, 0x9CE2AB57U, 0x91A18D8EU, 0x95609039U,
|
||||
0x8B27C03CU, 0x8FE6DD8BU, 0x82A5FB52U, 0x8664E6E5U,
|
||||
0xBE2B5B58U, 0xBAEA46EFU, 0xB7A96036U, 0xB3687D81U,
|
||||
0xAD2F2D84U, 0xA9EE3033U, 0xA4AD16EAU, 0xA06C0B5DU,
|
||||
0xD4326D90U, 0xD0F37027U, 0xDDB056FEU, 0xD9714B49U,
|
||||
0xC7361B4CU, 0xC3F706FBU, 0xCEB42022U, 0xCA753D95U,
|
||||
0xF23A8028U, 0xF6FB9D9FU, 0xFBB8BB46U, 0xFF79A6F1U,
|
||||
0xE13EF6F4U, 0xE5FFEB43U, 0xE8BCCD9AU, 0xEC7DD02DU,
|
||||
0x34867077U, 0x30476DC0U, 0x3D044B19U, 0x39C556AEU,
|
||||
0x278206ABU, 0x23431B1CU, 0x2E003DC5U, 0x2AC12072U,
|
||||
0x128E9DCFU, 0x164F8078U, 0x1B0CA6A1U, 0x1FCDBB16U,
|
||||
0x018AEB13U, 0x054BF6A4U, 0x0808D07DU, 0x0CC9CDCAU,
|
||||
0x7897AB07U, 0x7C56B6B0U, 0x71159069U, 0x75D48DDEU,
|
||||
0x6B93DDDBU, 0x6F52C06CU, 0x6211E6B5U, 0x66D0FB02U,
|
||||
0x5E9F46BFU, 0x5A5E5B08U, 0x571D7DD1U, 0x53DC6066U,
|
||||
0x4D9B3063U, 0x495A2DD4U, 0x44190B0DU, 0x40D816BAU,
|
||||
0xACA5C697U, 0xA864DB20U, 0xA527FDF9U, 0xA1E6E04EU,
|
||||
0xBFA1B04BU, 0xBB60ADFCU, 0xB6238B25U, 0xB2E29692U,
|
||||
0x8AAD2B2FU, 0x8E6C3698U, 0x832F1041U, 0x87EE0DF6U,
|
||||
0x99A95DF3U, 0x9D684044U, 0x902B669DU, 0x94EA7B2AU,
|
||||
0xE0B41DE7U, 0xE4750050U, 0xE9362689U, 0xEDF73B3EU,
|
||||
0xF3B06B3BU, 0xF771768CU, 0xFA325055U, 0xFEF34DE2U,
|
||||
0xC6BCF05FU, 0xC27DEDE8U, 0xCF3ECB31U, 0xCBFFD686U,
|
||||
0xD5B88683U, 0xD1799B34U, 0xDC3ABDEDU, 0xD8FBA05AU,
|
||||
0x690CE0EEU, 0x6DCDFD59U, 0x608EDB80U, 0x644FC637U,
|
||||
0x7A089632U, 0x7EC98B85U, 0x738AAD5CU, 0x774BB0EBU,
|
||||
0x4F040D56U, 0x4BC510E1U, 0x46863638U, 0x42472B8FU,
|
||||
0x5C007B8AU, 0x58C1663DU, 0x558240E4U, 0x51435D53U,
|
||||
0x251D3B9EU, 0x21DC2629U, 0x2C9F00F0U, 0x285E1D47U,
|
||||
0x36194D42U, 0x32D850F5U, 0x3F9B762CU, 0x3B5A6B9BU,
|
||||
0x0315D626U, 0x07D4CB91U, 0x0A97ED48U, 0x0E56F0FFU,
|
||||
0x1011A0FAU, 0x14D0BD4DU, 0x19939B94U, 0x1D528623U,
|
||||
0xF12F560EU, 0xF5EE4BB9U, 0xF8AD6D60U, 0xFC6C70D7U,
|
||||
0xE22B20D2U, 0xE6EA3D65U, 0xEBA91BBCU, 0xEF68060BU,
|
||||
0xD727BBB6U, 0xD3E6A601U, 0xDEA580D8U, 0xDA649D6FU,
|
||||
0xC423CD6AU, 0xC0E2D0DDU, 0xCDA1F604U, 0xC960EBB3U,
|
||||
0xBD3E8D7EU, 0xB9FF90C9U, 0xB4BCB610U, 0xB07DABA7U,
|
||||
0xAE3AFBA2U, 0xAAFBE615U, 0xA7B8C0CCU, 0xA379DD7BU,
|
||||
0x9B3660C6U, 0x9FF77D71U, 0x92B45BA8U, 0x9675461FU,
|
||||
0x8832161AU, 0x8CF30BADU, 0x81B02D74U, 0x857130C3U,
|
||||
0x5D8A9099U, 0x594B8D2EU, 0x5408ABF7U, 0x50C9B640U,
|
||||
0x4E8EE645U, 0x4A4FFBF2U, 0x470CDD2BU, 0x43CDC09CU,
|
||||
0x7B827D21U, 0x7F436096U, 0x7200464FU, 0x76C15BF8U,
|
||||
0x68860BFDU, 0x6C47164AU, 0x61043093U, 0x65C52D24U,
|
||||
0x119B4BE9U, 0x155A565EU, 0x18197087U, 0x1CD86D30U,
|
||||
0x029F3D35U, 0x065E2082U, 0x0B1D065BU, 0x0FDC1BECU,
|
||||
0x3793A651U, 0x3352BBE6U, 0x3E119D3FU, 0x3AD08088U,
|
||||
0x2497D08DU, 0x2056CD3AU, 0x2D15EBE3U, 0x29D4F654U,
|
||||
0xC5A92679U, 0xC1683BCEU, 0xCC2B1D17U, 0xC8EA00A0U,
|
||||
0xD6AD50A5U, 0xD26C4D12U, 0xDF2F6BCBU, 0xDBEE767CU,
|
||||
0xE3A1CBC1U, 0xE760D676U, 0xEA23F0AFU, 0xEEE2ED18U,
|
||||
0xF0A5BD1DU, 0xF464A0AAU, 0xF9278673U, 0xFDE69BC4U,
|
||||
0x89B8FD09U, 0x8D79E0BEU, 0x803AC667U, 0x84FBDBD0U,
|
||||
0x9ABC8BD5U, 0x9E7D9662U, 0x933EB0BBU, 0x97FFAD0CU,
|
||||
0xAFB010B1U, 0xAB710D06U, 0xA6322BDFU, 0xA2F33668U,
|
||||
0x00000000U, 0x04C11DB7U, 0x09823B6EU, 0x0D4326D9U, 0x130476DCU, 0x17C56B6BU, 0x1A864DB2U,
|
||||
0x1E475005U, 0x2608EDB8U, 0x22C9F00FU, 0x2F8AD6D6U, 0x2B4BCB61U, 0x350C9B64U, 0x31CD86D3U,
|
||||
0x3C8EA00AU, 0x384FBDBDU, 0x4C11DB70U, 0x48D0C6C7U, 0x4593E01EU, 0x4152FDA9U, 0x5F15ADACU,
|
||||
0x5BD4B01BU, 0x569796C2U, 0x52568B75U, 0x6A1936C8U, 0x6ED82B7FU, 0x639B0DA6U, 0x675A1011U,
|
||||
0x791D4014U, 0x7DDC5DA3U, 0x709F7B7AU, 0x745E66CDU, 0x9823B6E0U, 0x9CE2AB57U, 0x91A18D8EU,
|
||||
0x95609039U, 0x8B27C03CU, 0x8FE6DD8BU, 0x82A5FB52U, 0x8664E6E5U, 0xBE2B5B58U, 0xBAEA46EFU,
|
||||
0xB7A96036U, 0xB3687D81U, 0xAD2F2D84U, 0xA9EE3033U, 0xA4AD16EAU, 0xA06C0B5DU, 0xD4326D90U,
|
||||
0xD0F37027U, 0xDDB056FEU, 0xD9714B49U, 0xC7361B4CU, 0xC3F706FBU, 0xCEB42022U, 0xCA753D95U,
|
||||
0xF23A8028U, 0xF6FB9D9FU, 0xFBB8BB46U, 0xFF79A6F1U, 0xE13EF6F4U, 0xE5FFEB43U, 0xE8BCCD9AU,
|
||||
0xEC7DD02DU, 0x34867077U, 0x30476DC0U, 0x3D044B19U, 0x39C556AEU, 0x278206ABU, 0x23431B1CU,
|
||||
0x2E003DC5U, 0x2AC12072U, 0x128E9DCFU, 0x164F8078U, 0x1B0CA6A1U, 0x1FCDBB16U, 0x018AEB13U,
|
||||
0x054BF6A4U, 0x0808D07DU, 0x0CC9CDCAU, 0x7897AB07U, 0x7C56B6B0U, 0x71159069U, 0x75D48DDEU,
|
||||
0x6B93DDDBU, 0x6F52C06CU, 0x6211E6B5U, 0x66D0FB02U, 0x5E9F46BFU, 0x5A5E5B08U, 0x571D7DD1U,
|
||||
0x53DC6066U, 0x4D9B3063U, 0x495A2DD4U, 0x44190B0DU, 0x40D816BAU, 0xACA5C697U, 0xA864DB20U,
|
||||
0xA527FDF9U, 0xA1E6E04EU, 0xBFA1B04BU, 0xBB60ADFCU, 0xB6238B25U, 0xB2E29692U, 0x8AAD2B2FU,
|
||||
0x8E6C3698U, 0x832F1041U, 0x87EE0DF6U, 0x99A95DF3U, 0x9D684044U, 0x902B669DU, 0x94EA7B2AU,
|
||||
0xE0B41DE7U, 0xE4750050U, 0xE9362689U, 0xEDF73B3EU, 0xF3B06B3BU, 0xF771768CU, 0xFA325055U,
|
||||
0xFEF34DE2U, 0xC6BCF05FU, 0xC27DEDE8U, 0xCF3ECB31U, 0xCBFFD686U, 0xD5B88683U, 0xD1799B34U,
|
||||
0xDC3ABDEDU, 0xD8FBA05AU, 0x690CE0EEU, 0x6DCDFD59U, 0x608EDB80U, 0x644FC637U, 0x7A089632U,
|
||||
0x7EC98B85U, 0x738AAD5CU, 0x774BB0EBU, 0x4F040D56U, 0x4BC510E1U, 0x46863638U, 0x42472B8FU,
|
||||
0x5C007B8AU, 0x58C1663DU, 0x558240E4U, 0x51435D53U, 0x251D3B9EU, 0x21DC2629U, 0x2C9F00F0U,
|
||||
0x285E1D47U, 0x36194D42U, 0x32D850F5U, 0x3F9B762CU, 0x3B5A6B9BU, 0x0315D626U, 0x07D4CB91U,
|
||||
0x0A97ED48U, 0x0E56F0FFU, 0x1011A0FAU, 0x14D0BD4DU, 0x19939B94U, 0x1D528623U, 0xF12F560EU,
|
||||
0xF5EE4BB9U, 0xF8AD6D60U, 0xFC6C70D7U, 0xE22B20D2U, 0xE6EA3D65U, 0xEBA91BBCU, 0xEF68060BU,
|
||||
0xD727BBB6U, 0xD3E6A601U, 0xDEA580D8U, 0xDA649D6FU, 0xC423CD6AU, 0xC0E2D0DDU, 0xCDA1F604U,
|
||||
0xC960EBB3U, 0xBD3E8D7EU, 0xB9FF90C9U, 0xB4BCB610U, 0xB07DABA7U, 0xAE3AFBA2U, 0xAAFBE615U,
|
||||
0xA7B8C0CCU, 0xA379DD7BU, 0x9B3660C6U, 0x9FF77D71U, 0x92B45BA8U, 0x9675461FU, 0x8832161AU,
|
||||
0x8CF30BADU, 0x81B02D74U, 0x857130C3U, 0x5D8A9099U, 0x594B8D2EU, 0x5408ABF7U, 0x50C9B640U,
|
||||
0x4E8EE645U, 0x4A4FFBF2U, 0x470CDD2BU, 0x43CDC09CU, 0x7B827D21U, 0x7F436096U, 0x7200464FU,
|
||||
0x76C15BF8U, 0x68860BFDU, 0x6C47164AU, 0x61043093U, 0x65C52D24U, 0x119B4BE9U, 0x155A565EU,
|
||||
0x18197087U, 0x1CD86D30U, 0x029F3D35U, 0x065E2082U, 0x0B1D065BU, 0x0FDC1BECU, 0x3793A651U,
|
||||
0x3352BBE6U, 0x3E119D3FU, 0x3AD08088U, 0x2497D08DU, 0x2056CD3AU, 0x2D15EBE3U, 0x29D4F654U,
|
||||
0xC5A92679U, 0xC1683BCEU, 0xCC2B1D17U, 0xC8EA00A0U, 0xD6AD50A5U, 0xD26C4D12U, 0xDF2F6BCBU,
|
||||
0xDBEE767CU, 0xE3A1CBC1U, 0xE760D676U, 0xEA23F0AFU, 0xEEE2ED18U, 0xF0A5BD1DU, 0xF464A0AAU,
|
||||
0xF9278673U, 0xFDE69BC4U, 0x89B8FD09U, 0x8D79E0BEU, 0x803AC667U, 0x84FBDBD0U, 0x9ABC8BD5U,
|
||||
0x9E7D9662U, 0x933EB0BBU, 0x97FFAD0CU, 0xAFB010B1U, 0xAB710D06U, 0xA6322BDFU, 0xA2F33668U,
|
||||
0xBCB4666DU, 0xB8757BDAU, 0xB5365D03U, 0xB1F740B4U,
|
||||
};
|
||||
|
||||
|
@ -417,15 +334,11 @@ namespace OGG {
|
|||
|
||||
int Page::getPayloadSize(){
|
||||
size_t res = 0;
|
||||
for (unsigned int i = 0; i < segments.size(); i++){
|
||||
res += segments[i].size();
|
||||
}
|
||||
for (unsigned int i = 0; i < segments.size(); i++){res += segments[i].size();}
|
||||
return res;
|
||||
}
|
||||
|
||||
const std::deque<std::string> & Page::getAllSegments(){
|
||||
return segments;
|
||||
}
|
||||
const std::deque<std::string> &Page::getAllSegments(){return segments;}
|
||||
|
||||
void Page::prepareNext(bool continueMe){
|
||||
clear(0, -1, getBitstreamSerialNumber(), getPageSequenceNumber() + 1);
|
||||
|
@ -444,7 +357,6 @@ namespace OGG {
|
|||
setPageSequenceNumber(PSN);
|
||||
}
|
||||
|
||||
|
||||
unsigned int Page::addSegment(const std::string &payload){// returns added bytes
|
||||
segments.push_back(payload);
|
||||
return payload.size();
|
||||
|
@ -462,7 +374,8 @@ namespace OGG {
|
|||
for (unsigned int i = 0; i < segments.size(); i++){
|
||||
segAmount = (segments[i].size() / 255) + 1;
|
||||
if (segAmount + curSegNum > 255){
|
||||
retVal += ((segAmount - (255 - curSegNum + 1)) * 255) + (segments[i].size() % 255);//calculate the extra bytes that overflow
|
||||
retVal += ((segAmount - (255 - curSegNum + 1)) * 255) +
|
||||
(segments[i].size() % 255); // calculate the extra bytes that overflow
|
||||
curSegNum = 255; // making sure the segment numbers are at maximum
|
||||
}else{
|
||||
curSegNum += segAmount;
|
||||
|
@ -510,19 +423,12 @@ namespace OGG {
|
|||
return tempGranule;
|
||||
}
|
||||
|
||||
|
||||
bool Page::shouldSend(){
|
||||
unsigned int totalSegmentSize = 0;
|
||||
if (!oggSegments.size()){
|
||||
return false;
|
||||
}
|
||||
if (oggSegments.rbegin()->isKeyframe){
|
||||
return true;
|
||||
}
|
||||
if (!oggSegments.size()){return false;}
|
||||
if (oggSegments.rbegin()->isKeyframe){return true;}
|
||||
if (codec == OGG::VORBIS){
|
||||
if (lastKeyFrame - firstSample >= sampleRate){
|
||||
return true;
|
||||
}
|
||||
if (lastKeyFrame - firstSample >= sampleRate){return true;}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < oggSegments.size(); i++){
|
||||
|
@ -539,9 +445,7 @@ namespace OGG {
|
|||
HIGH_MSG("!segments.size()");
|
||||
return;
|
||||
}
|
||||
if (codec == OGG::VORBIS){
|
||||
firstSample = lastKeyFrame;
|
||||
}
|
||||
if (codec == OGG::VORBIS){firstSample = lastKeyFrame;}
|
||||
int temp = 0;
|
||||
long unsigned int checksum = 0; // reset checksum
|
||||
setCRCChecksum(0);
|
||||
|
@ -585,9 +489,7 @@ namespace OGG {
|
|||
granules = -1;
|
||||
}else{
|
||||
unsigned int tempIndex = numSegments - 1;
|
||||
if (bytesLeft != 0){
|
||||
tempIndex = numSegments - 2;
|
||||
}
|
||||
if (bytesLeft != 0){tempIndex = numSegments - 2;}
|
||||
granules = calculateGranule(oggSegments[tempIndex]);
|
||||
}
|
||||
}else{
|
||||
|
@ -617,7 +519,6 @@ namespace OGG {
|
|||
destination.SendNow(&tableSize, 1);
|
||||
destination.SendNow(table, tableSize);
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < numSegments; i++){
|
||||
if (bytesLeft != 0 && ((i + 1) == numSegments)){
|
||||
destination.SendNow(oggSegments.begin()->dataString.data(), bytesLeft);
|
||||
|
@ -631,7 +532,6 @@ namespace OGG {
|
|||
oggSegments.erase(oggSegments.begin());
|
||||
setHeaderType(OGG::Plain); // not a continuation
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// done sending, assume start of new page.
|
||||
|
@ -641,11 +541,5 @@ namespace OGG {
|
|||
// granule still requires setting!
|
||||
free(table);
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}// namespace OGG
|
||||
|
|
28
lib/ogg.h
28
lib/ogg.h
|
@ -1,13 +1,13 @@
|
|||
#pragma once
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <sstream>
|
||||
#include "dtsc.h"
|
||||
#include "socket.h"
|
||||
#include "theora.h"
|
||||
#include "vorbis.h"
|
||||
#include "socket.h"
|
||||
#include <cstdlib>
|
||||
#include <deque>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace OGG{
|
||||
|
||||
|
@ -24,18 +24,10 @@ namespace OGG {
|
|||
|
||||
enum oggCodec{THEORA, VORBIS, OPUS};
|
||||
|
||||
enum HeaderType {
|
||||
Plain = 0,
|
||||
Continued = 1,
|
||||
BeginOfStream = 2,
|
||||
EndOfStream = 4
|
||||
};
|
||||
enum HeaderType{Plain = 0, Continued = 1, BeginOfStream = 2, EndOfStream = 4};
|
||||
|
||||
std::deque<unsigned int> decodeXiphSize(char *data, size_t len);
|
||||
|
||||
|
||||
|
||||
|
||||
class Page{
|
||||
public:
|
||||
Page();
|
||||
|
@ -101,8 +93,6 @@ namespace OGG {
|
|||
private:
|
||||
char data[282]; // Fulldata
|
||||
std::deque<std::string> segments;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class oggTrack{
|
||||
|
@ -136,6 +126,4 @@ namespace OGG {
|
|||
std::map<long long unsigned int, unsigned int> DTSCID2seqNum;
|
||||
std::string parsedPages;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}// namespace OGG
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
|
||||
namespace Opus{
|
||||
|
||||
|
||||
uint16_t getPreSkip(const char * initData){
|
||||
return initData[10] + initData[11]* 256;
|
||||
}
|
||||
uint16_t getPreSkip(const char *initData){return initData[10] + initData[11] * 256;}
|
||||
|
||||
unsigned int Opus_getDuration(const char *part){
|
||||
const char config = part[0] >> 3;
|
||||
|
@ -107,5 +104,4 @@ namespace Opus{
|
|||
r << ": " << packets << " packets (VBR = " << VBR << ", padding = " << pad << ")";
|
||||
return r.str();
|
||||
}
|
||||
}
|
||||
|
||||
}// namespace Opus
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
namespace Opus{
|
||||
uint16_t getPreSkip(const char *initData);
|
||||
unsigned int Opus_getDuration(const char *part);
|
||||
std::string Opus_prettyPacket(const char *part, int len);
|
||||
}
|
||||
|
||||
}// namespace Opus
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
/// \file procs.cpp
|
||||
/// Contains generic functions for managing processes.
|
||||
|
||||
#include "procs.h"
|
||||
#include "defines.h"
|
||||
#include "procs.h"
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__MACH__)
|
||||
#include <sys/wait.h>
|
||||
#else
|
||||
#include <wait.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "timing.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
std::set<pid_t> Util::Procs::plist;
|
||||
std::set<int> Util::Procs::socketList;
|
||||
|
@ -28,7 +28,6 @@ bool Util::Procs::thread_handler = false;
|
|||
tthread::mutex Util::Procs::plistMutex;
|
||||
tthread::thread *Util::Procs::reaper_thread = 0;
|
||||
|
||||
|
||||
/// Local-only function. Attempts to reap child and returns current running status.
|
||||
bool Util::Procs::childRunning(pid_t p){
|
||||
int status;
|
||||
|
@ -49,9 +48,7 @@ bool Util::Procs::childRunning(pid_t p) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
if (ret < 0 && errno == EINTR) {
|
||||
return childRunning(p);
|
||||
}
|
||||
if (ret < 0 && errno == EINTR){return childRunning(p);}
|
||||
return !kill(p, 0);
|
||||
}
|
||||
|
||||
|
@ -79,9 +76,7 @@ void Util::Procs::exit_handler() {
|
|||
reaper_thread = 0;
|
||||
}
|
||||
std::set<pid_t>::iterator it;
|
||||
if (listcopy.empty()) {
|
||||
return;
|
||||
}
|
||||
if (listcopy.empty()){return;}
|
||||
|
||||
// wait up to 0.5 second for applications to shut down
|
||||
while (!listcopy.empty() && waiting <= 25){
|
||||
|
@ -96,11 +91,10 @@ void Util::Procs::exit_handler() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (listcopy.empty()) {
|
||||
return;
|
||||
}
|
||||
if (listcopy.empty()){return;}
|
||||
|
||||
INFO_MSG("Sending SIGINT and waiting up to 10 seconds for %d children to terminate.", (int)listcopy.size());
|
||||
INFO_MSG("Sending SIGINT and waiting up to 10 seconds for %d children to terminate.",
|
||||
(int)listcopy.size());
|
||||
waiting = 0;
|
||||
// wait up to 10 seconds for applications to shut down
|
||||
while (!listcopy.empty() && waiting <= 500){
|
||||
|
@ -123,9 +117,7 @@ void Util::Procs::exit_handler() {
|
|||
++waiting;
|
||||
}
|
||||
}
|
||||
if (listcopy.empty()) {
|
||||
return;
|
||||
}
|
||||
if (listcopy.empty()){return;}
|
||||
|
||||
ERROR_MSG("Sending SIGKILL to remaining %d children", (int)listcopy.size());
|
||||
// send sigkill to all remaining
|
||||
|
@ -151,9 +143,7 @@ void Util::Procs::exit_handler() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (listcopy.empty()) {
|
||||
return;
|
||||
}
|
||||
if (listcopy.empty()){return;}
|
||||
FAIL_MSG("Giving up with %d children left.", (int)listcopy.size());
|
||||
}
|
||||
|
||||
|
@ -210,9 +200,7 @@ void Util::Procs::grim_reaper(void * n){
|
|||
while (ret != 0){
|
||||
ret = waitpid(-1, &status, WNOHANG);
|
||||
if (ret <= 0){// ignore, would block otherwise
|
||||
if (ret == 0 || errno != EINTR) {
|
||||
break;
|
||||
}
|
||||
if (ret == 0 || errno != EINTR){break;}
|
||||
continue;
|
||||
}
|
||||
int exitcode;
|
||||
|
@ -241,15 +229,12 @@ void Util::Procs::childsig_handler(int signum) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/// Runs the given command and returns the stdout output as a string.
|
||||
std::string Util::Procs::getOutputOf(char *const *argv){
|
||||
std::string ret;
|
||||
int fin = 0, fout = -1, ferr = 0;
|
||||
pid_t myProc = StartPiped(argv, &fin, &fout, &ferr);
|
||||
while (childRunning(myProc)) {
|
||||
Util::sleep(100);
|
||||
}
|
||||
while (childRunning(myProc)){Util::sleep(100);}
|
||||
FILE *outFile = fdopen(fout, "r");
|
||||
char *fileBuf = 0;
|
||||
size_t fileBufLen = 0;
|
||||
|
@ -261,13 +246,10 @@ std::string Util::Procs::getOutputOf(char * const * argv) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/// This function prepares a deque for getOutputOf and automatically inserts a NULL at the end of the char* const*
|
||||
char *const *Util::Procs::dequeToArgv(std::deque<std::string> &argDeq){
|
||||
char **ret = (char **)malloc((argDeq.size() + 1) * sizeof(char *));
|
||||
for (int i = 0; i<argDeq.size(); i++){
|
||||
ret[i] = (char*)argDeq[i].c_str();
|
||||
}
|
||||
for (int i = 0; i < argDeq.size(); i++){ret[i] = (char *)argDeq[i].c_str();}
|
||||
ret[argDeq.size()] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
@ -289,9 +271,9 @@ pid_t Util::Procs::StartPiped(std::deque<std::string> & argDeq, int * fdin, int
|
|||
/// Starts a new process with given fds if the name is not already active.
|
||||
/// \return 0 if process was not started, process PID otherwise.
|
||||
/// \arg argv Command for this process.
|
||||
/// \arg fdin Standard input file descriptor. If null, /dev/null is assumed. Otherwise, if arg contains -1, a new fd is automatically allocated and written into this arg. Then the arg will be used as fd.
|
||||
/// \arg fdout Same as fdin, but for stdout.
|
||||
/// \arg fdout Same as fdin, but for stderr.
|
||||
/// \arg fdin Standard input file descriptor. If null, /dev/null is assumed. Otherwise, if arg
|
||||
/// contains -1, a new fd is automatically allocated and written into this arg. Then the arg will be
|
||||
/// used as fd. \arg fdout Same as fdin, but for stdout. \arg fdout Same as fdin, but for stderr.
|
||||
pid_t Util::Procs::StartPiped(const char *const *argv, int *fdin, int *fdout, int *fderr){
|
||||
pid_t pid;
|
||||
int pipein[2], pipeout[2], pipeerr[2];
|
||||
|
@ -344,7 +326,8 @@ pid_t Util::Procs::StartPiped(const char * const * argv, int * fdin, int * fdout
|
|||
if (pid == 0){// child
|
||||
handler_set = false;
|
||||
// Close all sockets in the socketList
|
||||
for (std::set<int>::iterator it = Util::Procs::socketList.begin(); it != Util::Procs::socketList.end(); ++it){
|
||||
for (std::set<int>::iterator it = Util::Procs::socketList.begin();
|
||||
it != Util::Procs::socketList.end(); ++it){
|
||||
close(*it);
|
||||
}
|
||||
if (!fdin){
|
||||
|
@ -374,18 +357,10 @@ pid_t Util::Procs::StartPiped(const char * const * argv, int * fdin, int * fdout
|
|||
}else if (*fderr != STDERR_FILENO){
|
||||
dup2(*fderr, STDERR_FILENO);
|
||||
}
|
||||
if (fdin && *fdin != -1 && *fdin != STDIN_FILENO) {
|
||||
close(*fdin);
|
||||
}
|
||||
if (fdout && *fdout != -1 && *fdout != STDOUT_FILENO) {
|
||||
close(*fdout);
|
||||
}
|
||||
if (fderr && *fderr != -1 && *fderr != STDERR_FILENO) {
|
||||
close(*fderr);
|
||||
}
|
||||
if (devnull != -1) {
|
||||
close(devnull);
|
||||
}
|
||||
if (fdin && *fdin != -1 && *fdin != STDIN_FILENO){close(*fdin);}
|
||||
if (fdout && *fdout != -1 && *fdout != STDOUT_FILENO){close(*fdout);}
|
||||
if (fderr && *fderr != -1 && *fderr != STDERR_FILENO){close(*fderr);}
|
||||
if (devnull != -1){close(devnull);}
|
||||
// Because execvp requires a char* const* and we have a const char* const*
|
||||
execvp(argv[0], (char *const *)argv);
|
||||
/*LTS-START*/
|
||||
|
@ -417,9 +392,7 @@ pid_t Util::Procs::StartPiped(const char * const * argv, int * fdin, int * fdout
|
|||
close(pipeerr[0]);
|
||||
close(pipeerr[1]);
|
||||
}
|
||||
if (devnull != -1) {
|
||||
close(devnull);
|
||||
}
|
||||
if (devnull != -1){close(devnull);}
|
||||
return 0;
|
||||
}else{// parent
|
||||
{
|
||||
|
@ -427,9 +400,7 @@ pid_t Util::Procs::StartPiped(const char * const * argv, int * fdin, int * fdout
|
|||
plist.insert(pid);
|
||||
}
|
||||
HIGH_MSG("Piped process %s started, PID %d", argv[0], pid);
|
||||
if (devnull != -1) {
|
||||
close(devnull);
|
||||
}
|
||||
if (devnull != -1){close(devnull);}
|
||||
if (fdin && *fdin == -1){
|
||||
close(pipein[0]); // close unused end end
|
||||
*fdin = pipein[1];
|
||||
|
@ -466,9 +437,7 @@ void Util::Procs::StopAll() {
|
|||
listcopy = plist;
|
||||
}
|
||||
std::set<pid_t>::iterator it;
|
||||
for (it = listcopy.begin(); it != listcopy.end(); it++) {
|
||||
Stop(*it);
|
||||
}
|
||||
for (it = listcopy.begin(); it != listcopy.end(); it++){Stop(*it);}
|
||||
}
|
||||
|
||||
/// Returns the number of active child processes.
|
||||
|
@ -494,4 +463,3 @@ void Util::Procs::remember(pid_t pid) {
|
|||
tthread::lock_guard<tthread::mutex> guard(plistMutex);
|
||||
plist.insert(pid);
|
||||
}
|
||||
|
||||
|
|
14
lib/procs.h
14
lib/procs.h
|
@ -2,12 +2,12 @@
|
|||
/// Contains generic function headers for managing processes.
|
||||
|
||||
#pragma once
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include "tinythread.h"
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
/// Contains utility code, not directly related to streaming media
|
||||
namespace Util{
|
||||
|
@ -22,6 +22,7 @@ namespace Util {
|
|||
static void exit_handler();
|
||||
static char *const *dequeToArgv(std::deque<std::string> &argDeq);
|
||||
static void grim_reaper(void *n);
|
||||
|
||||
public:
|
||||
static bool childRunning(pid_t p);
|
||||
static tthread::thread *reaper_thread;
|
||||
|
@ -43,5 +44,4 @@ namespace Util {
|
|||
static void remember(pid_t pid);
|
||||
static std::set<int> socketList; ///< Holds sockets that should be closed before forking
|
||||
};
|
||||
}
|
||||
|
||||
}// namespace Util
|
||||
|
|
22
lib/riff.cpp
22
lib/riff.cpp
|
@ -5,8 +5,8 @@ namespace RIFF{
|
|||
Chunk::Chunk(const void *_p, uint32_t len){
|
||||
p = (const char *)_p;
|
||||
if (len && len < getPayloadSize() + 8){
|
||||
FAIL_MSG("Chunk %s (%" PRIu32 "b) does not fit in %" PRIu32 " bytes length!", getType().c_str(),
|
||||
getPayloadSize() + 8, len);
|
||||
FAIL_MSG("Chunk %s (%" PRIu32 "b) does not fit in %" PRIu32 " bytes length!",
|
||||
getType().c_str(), getPayloadSize() + 8, len);
|
||||
p = 0;
|
||||
}
|
||||
}
|
||||
|
@ -109,11 +109,9 @@ namespace RIFF{
|
|||
return std::string(p + 32, 16);
|
||||
}
|
||||
void fmt::toPrettyString(std::ostream &o, size_t indent) const{
|
||||
o << std::string(indent, ' ') << "[" << getType() << "] (" << (getPayloadSize() + 8)
|
||||
<< "b):" << std::endl;
|
||||
o << std::string(indent, ' ') << "[" << getType() << "] (" << (getPayloadSize() + 8) << "b):" << std::endl;
|
||||
indent += 1;
|
||||
o << std::string(indent, ' ') << "Codec: " << getCodec() << " (" << getFormat() << ")"
|
||||
<< std::endl;
|
||||
o << std::string(indent, ' ') << "Codec: " << getCodec() << " (" << getFormat() << ")" << std::endl;
|
||||
o << std::string(indent, ' ') << "Channels: " << getChannels() << std::endl;
|
||||
o << std::string(indent, ' ') << "Sample rate: " << getHz() << "Hz" << std::endl;
|
||||
o << std::string(indent, ' ') << "Bytes/s: " << getBPS() << std::endl;
|
||||
|
@ -132,7 +130,8 @@ namespace RIFF{
|
|||
}
|
||||
}
|
||||
}
|
||||
std::string fmt::generate(uint16_t format, uint16_t channels, uint32_t hz, uint32_t bps, uint16_t blocksize, uint16_t size){
|
||||
std::string fmt::generate(uint16_t format, uint16_t channels, uint32_t hz, uint32_t bps,
|
||||
uint16_t blocksize, uint16_t size){
|
||||
std::string ret("fmt \022\000\000\000", 8);
|
||||
ret.append(std::string((size_t)18, '\000'));
|
||||
Bit::htobs_le((char *)ret.data() + 8, format);
|
||||
|
@ -150,8 +149,7 @@ namespace RIFF{
|
|||
return Bit::btohl_le(p + 8);
|
||||
}
|
||||
void fact::toPrettyString(std::ostream &o, size_t indent) const{
|
||||
o << std::string(indent, ' ') << "[" << getType() << "] (" << (getPayloadSize() + 8)
|
||||
<< "b):" << std::endl;
|
||||
o << std::string(indent, ' ') << "[" << getType() << "] (" << (getPayloadSize() + 8) << "b):" << std::endl;
|
||||
indent += 1;
|
||||
o << std::string(indent, ' ') << "Samples per channel: " << getSamplesPerChannel() << std::endl;
|
||||
}
|
||||
|
@ -166,10 +164,8 @@ namespace RIFF{
|
|||
return std::string(p + 8, getPayloadSize());
|
||||
}
|
||||
void ISFT::toPrettyString(std::ostream &o, size_t indent) const{
|
||||
o << std::string(indent, ' ') << "[" << getType() << "] (" << (getPayloadSize() + 8)
|
||||
<< "b):" << std::endl;
|
||||
o << std::string(indent, ' ') << "[" << getType() << "] (" << (getPayloadSize() + 8) << "b):" << std::endl;
|
||||
indent += 1;
|
||||
o << std::string(indent, ' ') << "Software: " << getSoftware() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}// namespace RIFF
|
||||
|
|
|
@ -41,7 +41,8 @@ namespace RIFF{
|
|||
/// WAVE "fmt " class.
|
||||
class fmt : public Chunk{
|
||||
public:
|
||||
static std::string generate(uint16_t format, uint16_t channels, uint32_t hz, uint32_t bps, uint16_t blocksize, uint16_t size);
|
||||
static std::string generate(uint16_t format, uint16_t channels, uint32_t hz, uint32_t bps,
|
||||
uint16_t blocksize, uint16_t size);
|
||||
fmt(const void *_p = 0, uint32_t len = 0) : Chunk(_p, len){}
|
||||
uint16_t getFormat() const;
|
||||
std::string getCodec() const;
|
||||
|
@ -74,6 +75,4 @@ namespace RIFF{
|
|||
virtual void toPrettyString(std::ostream &o, size_t indent = 0) const;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
}// namespace RIFF
|
||||
|
|
543
lib/rijndael.cpp
543
lib/rijndael.cpp
|
@ -1,168 +1,349 @@
|
|||
// This entire file is public domain and comes with no warranties.
|
||||
// Based on work by Vincent Rijmen, Antoon Bosselaers and Paulo Barreto.
|
||||
#include "rijndael.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
#include "rijndael.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
static const unsigned int Te0[256] ={
|
||||
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
|
||||
0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
|
||||
0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
|
||||
0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
|
||||
0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
|
||||
0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
|
||||
0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
|
||||
0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
|
||||
0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
|
||||
0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
|
||||
0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
|
||||
0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
|
||||
0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
|
||||
0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
|
||||
0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
|
||||
0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
|
||||
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U,
|
||||
0x91c5c554U, 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U,
|
||||
0x4dababe6U, 0xec76769aU, 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 0xeffafa15U,
|
||||
0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
|
||||
0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU,
|
||||
0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, 0x6834345cU, 0x51a5a5f4U,
|
||||
0xd1e5e534U, 0xf9f1f108U, 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, 0x0804040cU,
|
||||
0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
|
||||
0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU,
|
||||
0xea75759fU, 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U,
|
||||
0xb45a5aeeU, 0x5ba0a0fbU, 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 0x5229297bU,
|
||||
0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
|
||||
0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U,
|
||||
0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, 0xbbd0d06bU, 0xc5efef2aU,
|
||||
0x4faaaae5U, 0xedfbfb16U, 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 0x8a4545cfU,
|
||||
0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
|
||||
0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U,
|
||||
0xf1f5f504U, 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U, 0xe5ffff1aU,
|
||||
0xfdf3f30eU, 0xbfd2d26dU, 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U,
|
||||
0x359797a2U, 0x884444ccU, 0x2e171739U, 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
|
||||
0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U,
|
||||
0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, 0x8c4646caU, 0xc7eeee29U,
|
||||
0x6bb8b8d3U, 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, 0xdbe0e03bU,
|
||||
0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
|
||||
0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U,
|
||||
0xf279798bU, 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 0x018d8d8cU, 0xb1d5d564U,
|
||||
0x9c4e4ed2U, 0x49a9a9e0U, 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU,
|
||||
0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
|
||||
0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU,
|
||||
0x3e1f1f21U, 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 0xe0707090U, 0x7c3e3e42U,
|
||||
0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, 0xc26161a3U,
|
||||
0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
|
||||
0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U,
|
||||
0x339494a7U, 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU,
|
||||
0x50282878U, 0xa5dfdf7aU, 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU,
|
||||
0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
|
||||
0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
|
||||
};
|
||||
static const unsigned int Te1[256] ={
|
||||
0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
|
||||
0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
|
||||
0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
|
||||
0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
|
||||
0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
|
||||
0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
|
||||
0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
|
||||
0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
|
||||
0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
|
||||
0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
|
||||
0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
|
||||
0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
|
||||
0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
|
||||
0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
|
||||
0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
|
||||
0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
|
||||
0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU,
|
||||
0x5491c5c5U, 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U,
|
||||
0xe64dababU, 0x9aec7676U, 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 0x15effafaU,
|
||||
0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
|
||||
0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U,
|
||||
0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, 0x5c683434U, 0xf451a5a5U,
|
||||
0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 0x0c080404U,
|
||||
0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
|
||||
0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U,
|
||||
0x9fea7575U, 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU,
|
||||
0xeeb45a5aU, 0xfb5ba0a0U, 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 0x7b522929U,
|
||||
0x3edde3e3U, 0x715e2f2fU, 0x97138484U, 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
|
||||
0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU,
|
||||
0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, 0x6bbbd0d0U, 0x2ac5efefU,
|
||||
0xe54faaaaU, 0x16edfbfbU, 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 0xcf8a4545U,
|
||||
0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
|
||||
0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U,
|
||||
0x04f1f5f5U, 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U, 0x1ae5ffffU,
|
||||
0x0efdf3f3U, 0x6dbfd2d2U, 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU,
|
||||
0xa2359797U, 0xcc884444U, 0x392e1717U, 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
|
||||
0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 0xa0c06060U, 0x98198181U, 0xd19e4f4fU,
|
||||
0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, 0xca8c4646U, 0x29c7eeeeU,
|
||||
0xd36bb8b8U, 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, 0x3bdbe0e0U,
|
||||
0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
|
||||
0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U,
|
||||
0x8bf27979U, 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 0x8c018d8dU, 0x64b1d5d5U,
|
||||
0xd29c4e4eU, 0xe049a9a9U, 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U,
|
||||
0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
|
||||
0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U,
|
||||
0x213e1f1fU, 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 0x90e07070U, 0x427c3e3eU,
|
||||
0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, 0xa3c26161U,
|
||||
0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
|
||||
0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU,
|
||||
0xa7339494U, 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U,
|
||||
0x78502828U, 0x7aa5dfdfU, 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU,
|
||||
0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
|
||||
0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
|
||||
};
|
||||
static const unsigned int Te2[256] ={
|
||||
0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
|
||||
0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
|
||||
0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
|
||||
0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
|
||||
0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
|
||||
0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
|
||||
0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
|
||||
0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
|
||||
0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
|
||||
0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
|
||||
0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
|
||||
0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
|
||||
0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
|
||||
0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
|
||||
0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
|
||||
0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
|
||||
0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU,
|
||||
0xc55491c5U, 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U,
|
||||
0xabe64dabU, 0x769aec76U, 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 0xfa15effaU,
|
||||
0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
|
||||
0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U,
|
||||
0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, 0x345c6834U, 0xa5f451a5U,
|
||||
0xe534d1e5U, 0xf108f9f1U, 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, 0x040c0804U,
|
||||
0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
|
||||
0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U,
|
||||
0x759fea75U, 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU,
|
||||
0x5aeeb45aU, 0xa0fb5ba0U, 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 0x297b5229U,
|
||||
0xe33edde3U, 0x2f715e2fU, 0x84971384U, 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
|
||||
0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 0x6abed46aU, 0xcb468dcbU, 0xbed967beU,
|
||||
0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, 0xd06bbbd0U, 0xef2ac5efU,
|
||||
0xaae54faaU, 0xfb16edfbU, 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 0x45cf8a45U,
|
||||
0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
|
||||
0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U,
|
||||
0xf504f1f5U, 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U, 0xff1ae5ffU,
|
||||
0xf30efdf3U, 0xd26dbfd2U, 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU,
|
||||
0x97a23597U, 0x44cc8844U, 0x17392e17U, 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
|
||||
0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 0x60a0c060U, 0x81981981U, 0x4fd19e4fU,
|
||||
0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, 0x46ca8c46U, 0xee29c7eeU,
|
||||
0xb8d36bb8U, 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, 0xe03bdbe0U,
|
||||
0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
|
||||
0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U,
|
||||
0x798bf279U, 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 0x8d8c018dU, 0xd564b1d5U,
|
||||
0x4ed29c4eU, 0xa9e049a9U, 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U,
|
||||
0x7a8ef47aU, 0xaee947aeU, 0x08181008U, 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
|
||||
0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U,
|
||||
0x1f213e1fU, 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 0x7090e070U, 0x3e427c3eU,
|
||||
0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, 0x61a3c261U,
|
||||
0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
|
||||
0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU,
|
||||
0x94a73394U, 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U,
|
||||
0x28785028U, 0xdf7aa5dfU, 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU,
|
||||
0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
|
||||
0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
|
||||
};
|
||||
static const unsigned int Te3[256] ={
|
||||
0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
|
||||
0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
|
||||
0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
|
||||
0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
|
||||
0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
|
||||
0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
|
||||
0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
|
||||
0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
|
||||
0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
|
||||
0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
|
||||
0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
|
||||
0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
|
||||
0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
|
||||
0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
|
||||
0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
|
||||
0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
|
||||
0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU,
|
||||
0xc5c55491U, 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U,
|
||||
0xababe64dU, 0x76769aecU, 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 0xfafa15efU,
|
||||
0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
|
||||
0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU,
|
||||
0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, 0x34345c68U, 0xa5a5f451U,
|
||||
0xe5e534d1U, 0xf1f108f9U, 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, 0x04040c08U,
|
||||
0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
|
||||
0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU,
|
||||
0x75759feaU, 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU,
|
||||
0x5a5aeeb4U, 0xa0a0fb5bU, 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 0x29297b52U,
|
||||
0xe3e33eddU, 0x2f2f715eU, 0x84849713U, 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
|
||||
0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U,
|
||||
0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, 0xd0d06bbbU, 0xefef2ac5U,
|
||||
0xaaaae54fU, 0xfbfb16edU, 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 0x4545cf8aU,
|
||||
0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
|
||||
0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U,
|
||||
0xf5f504f1U, 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U, 0xffff1ae5U,
|
||||
0xf3f30efdU, 0xd2d26dbfU, 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU,
|
||||
0x9797a235U, 0x4444cc88U, 0x1717392eU, 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
|
||||
0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU,
|
||||
0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, 0x4646ca8cU, 0xeeee29c7U,
|
||||
0xb8b8d36bU, 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, 0xe0e03bdbU,
|
||||
0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
|
||||
0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U,
|
||||
0x79798bf2U, 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 0x8d8d8c01U, 0xd5d564b1U,
|
||||
0x4e4ed29cU, 0xa9a9e049U, 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU,
|
||||
0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
|
||||
0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U,
|
||||
0x1f1f213eU, 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 0x707090e0U, 0x3e3e427cU,
|
||||
0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, 0x6161a3c2U,
|
||||
0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
|
||||
0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U,
|
||||
0x9494a733U, 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU,
|
||||
0x28287850U, 0xdfdf7aa5U, 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U,
|
||||
0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
|
||||
0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
|
||||
};
|
||||
|
||||
static const unsigned int Td0[256] ={
|
||||
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
|
||||
0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
|
||||
0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
|
||||
0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
|
||||
0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
|
||||
0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
|
||||
0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
|
||||
0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
|
||||
0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
|
||||
0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
|
||||
0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
|
||||
0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
|
||||
0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
|
||||
0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
|
||||
0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
|
||||
0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
|
||||
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU,
|
||||
0x4be30393U, 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U,
|
||||
0x26354480U, 0xb562a38fU, 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 0xc32f7502U,
|
||||
0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
|
||||
0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, 0x75c2896aU, 0xf48e7978U, 0x99583e6bU,
|
||||
0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, 0x63df4a18U, 0xe51a3182U,
|
||||
0x97513360U, 0x62537f45U, 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 0x70486858U,
|
||||
0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
|
||||
0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 0x302887f2U, 0x23bfa5b2U, 0x02036abaU,
|
||||
0xed16825cU, 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U,
|
||||
0xd134621fU, 0xc4a6fe8aU, 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 0x0b83ec39U,
|
||||
0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
|
||||
0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 0x1998fb24U, 0xd6bde997U, 0x894043ccU,
|
||||
0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, 0xa17c0a47U, 0x7c420fe9U,
|
||||
0xf8841ec9U, 0x00000000U, 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 0xfd0efffbU,
|
||||
0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
|
||||
0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U,
|
||||
0x1c121a16U, 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU, 0xf28bc7adU,
|
||||
0x2db6a8b9U, 0x141ea9c8U, 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU,
|
||||
0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
|
||||
0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 0x854a247dU, 0xd2bb3df8U, 0xaef93211U,
|
||||
0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, 0x2bb3166cU, 0xa970b999U,
|
||||
0x119448faU, 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, 0x87494ec7U,
|
||||
0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
|
||||
0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU,
|
||||
0x82c3aff5U, 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 0xc8ac993bU, 0x10187da7U,
|
||||
0xe89c636eU, 0xdb3bbb7bU, 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U,
|
||||
0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
|
||||
0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U,
|
||||
0x33a7d815U, 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 0x764dd68dU, 0x43efb04dU,
|
||||
0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, 0x9d5eea04U,
|
||||
0x018c355dU, 0xfa877473U, 0xfb0b412eU, 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
|
||||
0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U, 0xe11ce5edU,
|
||||
0x7a47b13cU, 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU,
|
||||
0xdf3d6f14U, 0x7844db86U, 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U,
|
||||
0xbce2250cU, 0x283c498bU, 0xff0d9541U, 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
|
||||
0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
|
||||
};
|
||||
static const unsigned int Td1[256] ={
|
||||
0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
|
||||
0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
|
||||
0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
|
||||
0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
|
||||
0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
|
||||
0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
|
||||
0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
|
||||
0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
|
||||
0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
|
||||
0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
|
||||
0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
|
||||
0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
|
||||
0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
|
||||
0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
|
||||
0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
|
||||
0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
|
||||
0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U,
|
||||
0x934be303U, 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU,
|
||||
0x80263544U, 0x8fb562a3U, 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 0x02c32f75U,
|
||||
0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
|
||||
0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, 0x6a75c289U, 0x78f48e79U, 0x6b99583eU,
|
||||
0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, 0x1863df4aU, 0x82e51a31U,
|
||||
0x60975133U, 0x4562537fU, 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 0x58704868U,
|
||||
0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
|
||||
0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 0xf2302887U, 0xb223bfa5U, 0xba02036aU,
|
||||
0x5ced1682U, 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU,
|
||||
0x1fd13462U, 0x8ac4a6feU, 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 0x390b83ecU,
|
||||
0xaa4060efU, 0x065e719fU, 0x51bd6e10U, 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
|
||||
0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 0x241998fbU, 0x97d6bde9U, 0xcc894043U,
|
||||
0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, 0x47a17c0aU, 0xe97c420fU,
|
||||
0xc9f8841eU, 0x00000000U, 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 0xfbfd0effU,
|
||||
0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
|
||||
0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU,
|
||||
0x161c121aU, 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU, 0xadf28bc7U,
|
||||
0xb92db6a8U, 0xc8141ea9U, 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U,
|
||||
0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
|
||||
0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U,
|
||||
0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, 0x6c2bb316U, 0x99a970b9U,
|
||||
0xfa119448U, 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, 0xc787494eU,
|
||||
0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
|
||||
0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U,
|
||||
0xf582c3afU, 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 0x3bc8ac99U, 0xa710187dU,
|
||||
0x6ee89c63U, 0x7bdb3bbbU, 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU,
|
||||
0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
|
||||
0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U,
|
||||
0x1533a7d8U, 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 0x8d764dd6U, 0x4d43efb0U,
|
||||
0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, 0x049d5eeaU,
|
||||
0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
|
||||
0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U, 0xede11ce5U,
|
||||
0x3c7a47b1U, 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU,
|
||||
0x14df3d6fU, 0x867844dbU, 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U,
|
||||
0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
|
||||
0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
|
||||
};
|
||||
static const unsigned int Td2[256] ={
|
||||
0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
|
||||
0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
|
||||
0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
|
||||
0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
|
||||
0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
|
||||
0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
|
||||
0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
|
||||
0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
|
||||
0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
|
||||
0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
|
||||
0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
|
||||
0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
|
||||
0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
|
||||
0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
|
||||
0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
|
||||
0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
|
||||
0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU,
|
||||
0x03934be3U, 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU,
|
||||
0x44802635U, 0xa38fb562U, 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 0x7502c32fU,
|
||||
0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
|
||||
0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U,
|
||||
0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, 0x4a1863dfU, 0x3182e51aU,
|
||||
0x33609751U, 0x7f456253U, 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 0x68587048U,
|
||||
0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
|
||||
0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 0x87f23028U, 0xa5b223bfU, 0x6aba0203U,
|
||||
0x825ced16U, 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U,
|
||||
0x621fd134U, 0xfe8ac4a6U, 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 0xec390b83U,
|
||||
0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
|
||||
0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 0xfb241998U, 0xe997d6bdU, 0x43cc8940U,
|
||||
0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, 0x0a47a17cU, 0x0fe97c42U,
|
||||
0x1ec9f884U, 0x00000000U, 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 0xfffbfd0eU,
|
||||
0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
|
||||
0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U,
|
||||
0x1a161c12U, 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U, 0xc7adf28bU,
|
||||
0xa8b92db6U, 0xa9c8141eU, 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 0x269ff701U,
|
||||
0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
|
||||
0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U,
|
||||
0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, 0x166c2bb3U, 0xb999a970U,
|
||||
0x48fa1194U, 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, 0x4ec78749U,
|
||||
0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
|
||||
0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U,
|
||||
0xaff582c3U, 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 0x993bc8acU, 0x7da71018U,
|
||||
0x636ee89cU, 0xbb7bdb3bU, 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U,
|
||||
0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
|
||||
0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U,
|
||||
0xd81533a7U, 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 0xd68d764dU, 0xb04d43efU,
|
||||
0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, 0xea049d5eU,
|
||||
0x355d018cU, 0x7473fa87U, 0x412efb0bU, 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
|
||||
0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U, 0xe5ede11cU,
|
||||
0xb13c7a47U, 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU,
|
||||
0x6f14df3dU, 0xdb867844U, 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU,
|
||||
0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
|
||||
0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
|
||||
};
|
||||
static const unsigned int Td3[256] ={
|
||||
0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
|
||||
0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
|
||||
0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
|
||||
0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
|
||||
0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
|
||||
0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
|
||||
0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
|
||||
0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
|
||||
0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
|
||||
0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
|
||||
0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
|
||||
0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
|
||||
0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
|
||||
0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
|
||||
0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
|
||||
0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
|
||||
0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU,
|
||||
0xe303934bU, 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U,
|
||||
0x35448026U, 0x62a38fb5U, 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 0x2f7502c3U,
|
||||
0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
|
||||
0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U,
|
||||
0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, 0xdf4a1863U, 0x1a3182e5U,
|
||||
0x51336097U, 0x537f4562U, 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 0x48685870U,
|
||||
0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
|
||||
0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 0x2887f230U, 0xbfa5b223U, 0x036aba02U,
|
||||
0x16825cedU, 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U,
|
||||
0x34621fd1U, 0xa6fe8ac4U, 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 0x83ec390bU,
|
||||
0x60efaa40U, 0x719f065eU, 0x6e1051bdU, 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
|
||||
0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 0x98fb2419U, 0xbde997d6U, 0x4043cc89U,
|
||||
0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, 0x7c0a47a1U, 0x420fe97cU,
|
||||
0x841ec9f8U, 0x00000000U, 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 0x0efffbfdU,
|
||||
0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
|
||||
0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU,
|
||||
0x121a161cU, 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU, 0x8bc7adf2U,
|
||||
0xb6a8b92dU, 0x1ea9c814U, 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U,
|
||||
0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
|
||||
0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU,
|
||||
0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, 0xb3166c2bU, 0x70b999a9U,
|
||||
0x9448fa11U, 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, 0x494ec787U,
|
||||
0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
|
||||
0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU,
|
||||
0xc3aff582U, 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 0xac993bc8U, 0x187da710U,
|
||||
0x9c636ee8U, 0x3bbb7bdbU, 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U,
|
||||
0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
|
||||
0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U,
|
||||
0xa7d81533U, 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 0x4dd68d76U, 0xefb04d43U,
|
||||
0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, 0x5eea049dU,
|
||||
0x8c355d01U, 0x877473faU, 0x0b412efbU, 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
|
||||
0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U,
|
||||
0x47b13c7aU, 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU,
|
||||
0x3d6f14dfU, 0x44db8678U, 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U,
|
||||
0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
|
||||
0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
|
||||
};
|
||||
static const char Td4[256] ={
|
||||
0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
|
||||
0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
|
||||
0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
|
||||
0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
|
||||
0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
|
||||
0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
|
||||
0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
|
||||
0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
|
||||
0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U,
|
||||
0xf3U, 0xd7U, 0xfbU, 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, 0x34U, 0x8eU,
|
||||
0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U,
|
||||
0x3dU, 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, 0x08U, 0x2eU, 0xa1U, 0x66U,
|
||||
0x28U, 0xd9U, 0x24U, 0xb2U, 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, 0x72U,
|
||||
0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U,
|
||||
0xb6U, 0x92U, 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, 0x5eU, 0x15U, 0x46U,
|
||||
0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
|
||||
0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU,
|
||||
0x3fU, 0x0fU, 0x02U, 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, 0x3aU, 0x91U,
|
||||
0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U,
|
||||
0x73U, 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 0xe2U, 0xf9U, 0x37U, 0xe8U,
|
||||
0x1cU, 0x75U, 0xdfU, 0x6eU, 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, 0x6fU,
|
||||
0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U,
|
||||
0x79U, 0x20U, 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, 0x1fU, 0xddU, 0xa8U,
|
||||
0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
|
||||
0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U,
|
||||
0xc9U, 0x9cU, 0xefU, 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, 0xc8U, 0xebU,
|
||||
0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U,
|
||||
0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
|
||||
};
|
||||
static const unsigned int rcon[] = {0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000};
|
||||
static const unsigned int rcon[] ={0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
||||
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000};
|
||||
|
||||
// Expand the cipher key into the encryption key schedule.
|
||||
void AES_set_encrypt_key(const char *userKey, const int bits, char *key){
|
||||
|
@ -177,7 +358,8 @@ void AES_set_encrypt_key(const char * userKey, const int bits, char * key) {
|
|||
if (bits == 128){
|
||||
while (1){
|
||||
temp = rk[3];
|
||||
rk[4] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
|
||||
rk[4] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp)&0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
|
||||
rk[5] = rk[1] ^ rk[4];
|
||||
rk[6] = rk[2] ^ rk[5];
|
||||
rk[7] = rk[3] ^ rk[6];
|
||||
|
@ -193,7 +375,8 @@ void AES_set_encrypt_key(const char * userKey, const int bits, char * key) {
|
|||
if (bits == 192){
|
||||
while (1){
|
||||
temp = rk[5];
|
||||
rk[ 6] = rk[ 0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
|
||||
rk[6] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp)&0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
|
||||
rk[7] = rk[1] ^ rk[6];
|
||||
rk[8] = rk[2] ^ rk[7];
|
||||
rk[9] = rk[3] ^ rk[8];
|
||||
|
@ -211,7 +394,8 @@ void AES_set_encrypt_key(const char * userKey, const int bits, char * key) {
|
|||
if (bits == 256){
|
||||
while (1){
|
||||
temp = rk[7];
|
||||
rk[ 8] = rk[ 0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
|
||||
rk[8] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp)&0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
|
||||
rk[9] = rk[1] ^ rk[8];
|
||||
rk[10] = rk[2] ^ rk[9];
|
||||
rk[11] = rk[3] ^ rk[10];
|
||||
|
@ -220,7 +404,8 @@ void AES_set_encrypt_key(const char * userKey, const int bits, char * key) {
|
|||
return;
|
||||
}
|
||||
temp = rk[11];
|
||||
rk[12] = rk[ 4] ^ (Te2[(temp >> 24)] & 0xff000000) ^ (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(temp) & 0xff] & 0x000000ff);
|
||||
rk[12] = rk[4] ^ (Te2[(temp >> 24)] & 0xff000000) ^ (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(temp)&0xff] & 0x000000ff);
|
||||
rk[13] = rk[5] ^ rk[12];
|
||||
rk[14] = rk[6] ^ rk[13];
|
||||
rk[15] = rk[7] ^ rk[14];
|
||||
|
@ -235,9 +420,7 @@ void AES_set_encrypt_key(const char * userKey, const int bits, char * key) {
|
|||
void printInverted(const unsigned int *data, unsigned int len){
|
||||
for (int i = 0; i < len; i++){
|
||||
std::cout << "0x" << std::hex << std::setw(8) << std::setfill('0') << data[i] << ", ";
|
||||
if (i % 4 == 3){
|
||||
std::cout << std::endl;
|
||||
}
|
||||
if (i % 4 == 3){std::cout << std::endl;}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
@ -252,12 +435,8 @@ void AES_set_decrypt_key(const char * userKey, const int bits, char * key) {
|
|||
AES_set_encrypt_key(userKey, bits, key);
|
||||
|
||||
unsigned int rounds = 10;
|
||||
if (bits > 128) {
|
||||
rounds = 12;
|
||||
}
|
||||
if (bits > 192) {
|
||||
rounds = 14;
|
||||
}
|
||||
if (bits > 128){rounds = 12;}
|
||||
if (bits > 192){rounds = 14;}
|
||||
|
||||
/* invert the order of the round keys: */
|
||||
for (i = 0, j = 4 * rounds; i < j; i += 4, j -= 4){
|
||||
|
@ -277,10 +456,14 @@ void AES_set_decrypt_key(const char * userKey, const int bits, char * key) {
|
|||
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
|
||||
for (i = 1; i < rounds; i++){
|
||||
rk += 4;
|
||||
rk[0] = Td0[Te1[(rk[0] >> 24)] & 0xff] ^ Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[0]) & 0xff] & 0xff];
|
||||
rk[1] = Td0[Te1[(rk[1] >> 24)] & 0xff] ^ Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[1]) & 0xff] & 0xff];
|
||||
rk[2] = Td0[Te1[(rk[2] >> 24)] & 0xff] ^ Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[2]) & 0xff] & 0xff];
|
||||
rk[3] = Td0[Te1[(rk[3] >> 24)] & 0xff] ^ Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[3]) & 0xff] & 0xff];
|
||||
rk[0] = Td0[Te1[(rk[0] >> 24)] & 0xff] ^ Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[0]) & 0xff] & 0xff];
|
||||
rk[1] = Td0[Te1[(rk[1] >> 24)] & 0xff] ^ Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[1]) & 0xff] & 0xff];
|
||||
rk[2] = Td0[Te1[(rk[2] >> 24)] & 0xff] ^ Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[2]) & 0xff] & 0xff];
|
||||
rk[3] = Td0[Te1[(rk[3] >> 24)] & 0xff] ^ Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[3]) & 0xff] & 0xff];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,20 +547,20 @@ void AES_encrypt(const char * in, char * out, const int bits, const char * key)
|
|||
}
|
||||
}
|
||||
rk += 40;
|
||||
if (bits > 128) {
|
||||
rk += 8;
|
||||
}
|
||||
if (bits > 192) {
|
||||
rk += 8;
|
||||
}
|
||||
if (bits > 128){rk += 8;}
|
||||
if (bits > 192){rk += 8;}
|
||||
// apply last round and map cipher state to byte array block
|
||||
s0 = (Te2[(t0 >> 24)] & 0xff000000) ^ (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t3) & 0xff] & 0x000000ff) ^ rk[0];
|
||||
s0 = (Te2[(t0 >> 24)] & 0xff000000) ^ (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t3)&0xff] & 0x000000ff) ^ rk[0];
|
||||
Bit::htobl(out, s0);
|
||||
s1 = (Te2[(t1 >> 24)] & 0xff000000) ^ (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t0) & 0xff] & 0x000000ff) ^ rk[1];
|
||||
s1 = (Te2[(t1 >> 24)] & 0xff000000) ^ (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t0)&0xff] & 0x000000ff) ^ rk[1];
|
||||
Bit::htobl(out + 4, s1);
|
||||
s2 = (Te2[(t2 >> 24)] & 0xff000000) ^ (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t1) & 0xff] & 0x000000ff) ^ rk[2];
|
||||
s2 = (Te2[(t2 >> 24)] & 0xff000000) ^ (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t1)&0xff] & 0x000000ff) ^ rk[2];
|
||||
Bit::htobl(out + 8, s2);
|
||||
s3 = (Te2[(t3 >> 24)] & 0xff000000) ^ (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t2) & 0xff] & 0x000000ff) ^ rk[3];
|
||||
s3 = (Te2[(t3 >> 24)] & 0xff000000) ^ (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t2)&0xff] & 0x000000ff) ^ rk[3];
|
||||
Bit::htobl(out + 12, s3);
|
||||
}
|
||||
|
||||
|
@ -459,32 +642,30 @@ void AES_decrypt(const char * in, char * out, const char * key, unsigned int bit
|
|||
}
|
||||
}
|
||||
rk += 40;
|
||||
if (bits > 128) {
|
||||
rk += 8;
|
||||
}
|
||||
if (bits > 192) {
|
||||
rk += 8;
|
||||
}
|
||||
s0 = ((unsigned long)Td4[(t0 >> 24)] << 24) ^ ((unsigned long)Td4[(t3 >> 16) & 0xff] << 16) ^ ((unsigned long)Td4[(t2 >> 8) & 0xff] << 8) ^ ((unsigned long)Td4[(t1) & 0xff]) ^ rk[0];
|
||||
if (bits > 128){rk += 8;}
|
||||
if (bits > 192){rk += 8;}
|
||||
s0 = ((unsigned long)Td4[(t0 >> 24)] << 24) ^ ((unsigned long)Td4[(t3 >> 16) & 0xff] << 16) ^
|
||||
((unsigned long)Td4[(t2 >> 8) & 0xff] << 8) ^ ((unsigned long)Td4[(t1)&0xff]) ^ rk[0];
|
||||
Bit::htobl(out, s0);
|
||||
s1 = ((unsigned long)Td4[(t1 >> 24)] << 24) ^ ((unsigned long)Td4[(t0 >> 16) & 0xff] << 16) ^ ((unsigned long)Td4[(t3 >> 8) & 0xff] << 8) ^ ((unsigned long)Td4[(t2) & 0xff]) ^ rk[1];
|
||||
s1 = ((unsigned long)Td4[(t1 >> 24)] << 24) ^ ((unsigned long)Td4[(t0 >> 16) & 0xff] << 16) ^
|
||||
((unsigned long)Td4[(t3 >> 8) & 0xff] << 8) ^ ((unsigned long)Td4[(t2)&0xff]) ^ rk[1];
|
||||
Bit::htobl(out + 4, s1);
|
||||
s2 = ((unsigned long)Td4[(t2 >> 24)] << 24) ^ ((unsigned long)Td4[(t1 >> 16) & 0xff] << 16) ^ ((unsigned long)Td4[(t0 >> 8) & 0xff] << 8) ^ ((unsigned long)Td4[(t3) & 0xff]) ^ rk[2];
|
||||
s2 = ((unsigned long)Td4[(t2 >> 24)] << 24) ^ ((unsigned long)Td4[(t1 >> 16) & 0xff] << 16) ^
|
||||
((unsigned long)Td4[(t0 >> 8) & 0xff] << 8) ^ ((unsigned long)Td4[(t3)&0xff]) ^ rk[2];
|
||||
Bit::htobl(out + 8, s2);
|
||||
s3 = ((unsigned long)Td4[(t3 >> 24)] << 24) ^ ((unsigned long)Td4[(t2 >> 16) & 0xff] << 16) ^ ((unsigned long)Td4[(t1 >> 8) & 0xff] << 8) ^ ((unsigned long)Td4[(t0) & 0xff]) ^ rk[3];
|
||||
s3 = ((unsigned long)Td4[(t3 >> 24)] << 24) ^ ((unsigned long)Td4[(t2 >> 16) & 0xff] << 16) ^
|
||||
((unsigned long)Td4[(t1 >> 8) & 0xff] << 8) ^ ((unsigned long)Td4[(t0)&0xff]) ^ rk[3];
|
||||
Bit::htobl(out + 12, s3);
|
||||
}
|
||||
|
||||
|
||||
static void increaseCounter(char *counter){
|
||||
for (int i = 15; i >= 0; i--){
|
||||
if (++counter[i]) {
|
||||
return;
|
||||
}
|
||||
if (++counter[i]){return;}
|
||||
}
|
||||
}
|
||||
|
||||
void AES_CTR128_crypt(const char * in, char * out, unsigned int len, const char * key, char ivec[16], char ecount_buf[16], unsigned int & num) {
|
||||
void AES_CTR128_crypt(const char *in, char *out, unsigned int len, const char *key, char ivec[16],
|
||||
char ecount_buf[16], unsigned int &num){
|
||||
unsigned int l = 0;
|
||||
|
||||
while (l < len){
|
||||
|
|
|
@ -5,5 +5,6 @@ void AES_set_decrypt_key(const char * userKey, const int bits, char * key);
|
|||
void AES_encrypt(const char *in, char *out, const int bits, const char *key);
|
||||
void AES_decrypt(const char *in, char *out, const char *key, unsigned int bits);
|
||||
static void increaseCounter(char *counter);
|
||||
void AES_CTR128_crypt(const char * in, char * out, unsigned int len, const char * key, char ivec[16], char ecount_buf[16], unsigned int & num);
|
||||
void AES_CTR128_crypt(const char *in, char *out, unsigned int len, const char *key, char ivec[16],
|
||||
char ecount_buf[16], unsigned int &num);
|
||||
void printInverted(const unsigned int *data, unsigned int len);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/// \file rtmpchunks.cpp
|
||||
/// Holds all code for the RTMPStream namespace.
|
||||
|
||||
#include "rtmpchunks.h"
|
||||
#include "auth.h"
|
||||
#include "defines.h"
|
||||
#include "flv_tag.h"
|
||||
#include "rtmpchunks.h"
|
||||
#include "timing.h"
|
||||
|
||||
std::string RTMPStream::handshake_in; ///< Input for the handshake.
|
||||
|
@ -41,8 +41,7 @@ char genuineFMSKey[] ={
|
|||
0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec, 0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab,
|
||||
0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae}; // 68
|
||||
|
||||
char genuineFPKey[] ={
|
||||
0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65,
|
||||
char genuineFPKey[] ={0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65,
|
||||
0x20, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x20, 0x50, 0x6c, 0x61,
|
||||
0x79, // Genuine Adobe Flash Player 001
|
||||
0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe,
|
||||
|
@ -61,8 +60,7 @@ bool ValidateClientScheme(uint8_t *pBuffer, uint8_t scheme){
|
|||
uint32_t clientDigestOffset = GetDigestOffset(pBuffer, scheme);
|
||||
uint8_t pTempBuffer[1536 - 32];
|
||||
memcpy(pTempBuffer, pBuffer, clientDigestOffset);
|
||||
memcpy(pTempBuffer + clientDigestOffset, pBuffer + clientDigestOffset + 32,
|
||||
1536 - clientDigestOffset - 32);
|
||||
memcpy(pTempBuffer + clientDigestOffset, pBuffer + clientDigestOffset + 32, 1536 - clientDigestOffset - 32);
|
||||
char pTempHash[32];
|
||||
Secure::hmac_sha256bin((char *)pTempBuffer, 1536 - 32, genuineFPKey, 30, pTempHash);
|
||||
bool result = (memcmp(pBuffer + clientDigestOffset, pTempHash, 32) == 0);
|
||||
|
@ -217,8 +215,7 @@ std::string &RTMPStream::SendChunk(unsigned int cs_id, unsigned char msg_type_id
|
|||
/// \param data Contents of the media data.
|
||||
/// \param len Length of the media data, in bytes.
|
||||
/// \param ts Timestamp of the media data, relative to current system time.
|
||||
std::string &RTMPStream::SendMedia(unsigned char msg_type_id, unsigned char *data, int len,
|
||||
unsigned int ts){
|
||||
std::string &RTMPStream::SendMedia(unsigned char msg_type_id, unsigned char *data, int len, unsigned int ts){
|
||||
static RTMPStream::Chunk ch;
|
||||
ch.cs_id = msg_type_id + 42;
|
||||
ch.timestamp = ts;
|
||||
|
@ -353,8 +350,7 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer &buffer){
|
|||
// process the rest of the header, for each chunk type
|
||||
headertype = chunktype & 0xC0;
|
||||
|
||||
DONTEVEN_MSG("Parsing RTMP chunk header (%#.2hhX) at offset %#zx", chunktype,
|
||||
RTMPStream::rec_cnt);
|
||||
DONTEVEN_MSG("Parsing RTMP chunk header (%#.2hhX) at offset %#zx", chunktype, RTMPStream::rec_cnt);
|
||||
|
||||
switch (headertype){
|
||||
case 0x00:
|
||||
|
@ -512,8 +508,7 @@ bool RTMPStream::doHandshake(){
|
|||
// FIRST 1536 bytes for server response
|
||||
char pTempBuffer[1504];
|
||||
memcpy(pTempBuffer, Server, serverDigestOffset);
|
||||
memcpy(pTempBuffer + serverDigestOffset, Server + serverDigestOffset + 32,
|
||||
1504 - serverDigestOffset);
|
||||
memcpy(pTempBuffer + serverDigestOffset, Server + serverDigestOffset + 32, 1504 - serverDigestOffset);
|
||||
Secure::hmac_sha256bin(pTempBuffer, 1504, genuineFMSKey, 36, (char *)Server + serverDigestOffset);
|
||||
|
||||
// SECOND 1536 bytes for server response
|
||||
|
@ -523,12 +518,10 @@ bool RTMPStream::doHandshake(){
|
|||
}else{
|
||||
char pTempHash[32];
|
||||
Secure::hmac_sha256bin((char *)Client + keyChallengeIndex, 32, genuineFMSKey, 68, pTempHash);
|
||||
Secure::hmac_sha256bin((char *)Server + 1536, 1536 - 32, pTempHash, 32,
|
||||
(char *)Server + 1536 * 2 - 32);
|
||||
Secure::hmac_sha256bin((char *)Server + 1536, 1536 - 32, pTempHash, 32, (char *)Server + 1536 * 2 - 32);
|
||||
}
|
||||
|
||||
Server[-1] = Version;
|
||||
RTMPStream::snd_cnt += 3073;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,4 +86,3 @@ namespace RTMPStream{
|
|||
/// Does the handshake. Expects handshake_in to be filled, and fills handshake_out.
|
||||
bool doHandshake();
|
||||
}// namespace RTMPStream
|
||||
|
||||
|
|
74
lib/rtp.cpp
74
lib/rtp.cpp
|
@ -1,10 +1,10 @@
|
|||
#include "rtp.h"
|
||||
#include "adts.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
#include "encode.h"
|
||||
#include "h264.h"
|
||||
#include "mpeg.h"
|
||||
#include "rtp.h"
|
||||
#include "sdp.h"
|
||||
#include "timing.h"
|
||||
#include <arpa/inet.h>
|
||||
|
@ -15,9 +15,7 @@ namespace RTP{
|
|||
|
||||
unsigned int Packet::getHsize() const{
|
||||
unsigned int r = 12 + 4 * getContribCount();
|
||||
if (getExtension()){
|
||||
r += (1+Bit::btohs(data+r+2)) * 4;
|
||||
}
|
||||
if (getExtension()){r += (1 + Bit::btohs(data + r + 2)) * 4;}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -75,8 +73,7 @@ namespace RTP{
|
|||
}else{
|
||||
data[1] &= 0x7F; // setting the RTP marker bit to 0
|
||||
unsigned int sent = 0;
|
||||
unsigned int sending =
|
||||
maxDataLen - getHsize() - 2; // packages are of size MAX_SEND, except for the final one
|
||||
unsigned int sending = maxDataLen - getHsize() - 2; // packages are of size MAX_SEND, except for the final one
|
||||
char initByte = (payload[0] & 0xE0) | 0x1C;
|
||||
char serByte = payload[0] & 0x1F; // ser is now 000
|
||||
data[getHsize()] = initByte;
|
||||
|
@ -118,15 +115,10 @@ namespace RTP{
|
|||
chunkSize = std::min<size_t>(1200, payloadlen);
|
||||
payloadlen -= chunkSize;
|
||||
|
||||
data[1] =
|
||||
(0 != payloadlen) ? (data[1] & 0x7F) : (data[1] | 0x80); // marker bit, 1 for last chunk.
|
||||
data[1] = (0 != payloadlen) ? (data[1] & 0x7F) : (data[1] | 0x80); // marker bit, 1 for last chunk.
|
||||
data[headerSize] = 0x00; // reset
|
||||
data[headerSize] |=
|
||||
(isStartOfPartition) ? 0x10 : 0x00; // first chunk is always start of a partition.
|
||||
data[headerSize] |=
|
||||
(isKeyframe)
|
||||
? 0x00
|
||||
: 0x20; // non-reference frame. 0 = frame is needed, 1 = frame can be disgarded.
|
||||
data[headerSize] |= (isStartOfPartition) ? 0x10 : 0x00; // first chunk is always start of a partition.
|
||||
data[headerSize] |= (isKeyframe) ? 0x00 : 0x20; // non-reference frame. 0 = frame is needed, 1 = frame can be disgarded.
|
||||
|
||||
memcpy(data + headerSize + 1, payload + bytesWritten, chunkSize);
|
||||
callBack(socket, data, headerSize + 1 + chunkSize, channel);
|
||||
|
@ -154,8 +146,7 @@ namespace RTP{
|
|||
}else{
|
||||
data[1] &= 0x7F; // setting the RTP marker bit to 0
|
||||
unsigned int sent = 0;
|
||||
unsigned int sending =
|
||||
maxDataLen - getHsize() - 3; // packages are of size MAX_SEND, except for the final one
|
||||
unsigned int sending = maxDataLen - getHsize() - 3; // packages are of size MAX_SEND, except for the final one
|
||||
char initByteA = (payload[0] & 0x81) | 0x62;
|
||||
char initByteB = payload[1];
|
||||
char serByte = (payload[0] & 0x7E) >> 1; // SE is now 00
|
||||
|
@ -205,8 +196,7 @@ namespace RTP{
|
|||
}else{
|
||||
data[1] &= 0x7F; // setting the RTP marker bit to 0
|
||||
unsigned int sent = 0;
|
||||
unsigned int sending =
|
||||
maxDataLen - getHsize() - 4; // packages are of size MAX_SEND, except for the final one
|
||||
unsigned int sending = maxDataLen - getHsize() - 4; // packages are of size MAX_SEND, except for the final one
|
||||
Mpeg::MPEG2Info mInfo;
|
||||
MPEGVideoHeader mHead(data + getHsize());
|
||||
while (sent < payloadlen){
|
||||
|
@ -234,13 +224,13 @@ namespace RTP{
|
|||
}
|
||||
|
||||
void Packet::sendData(void *socket, void callBack(void *, char *, unsigned int, unsigned int),
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel,
|
||||
std::string codec){
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel, std::string codec){
|
||||
if (codec == "H264"){
|
||||
unsigned long sent = 0;
|
||||
while (sent < payloadlen){
|
||||
unsigned long nalSize = ntohl(*((unsigned long *)(payload + sent)));
|
||||
sendH264(socket, callBack, payload + sent + 4, nalSize, channel, (sent + nalSize + 4) >= payloadlen ? true : false);
|
||||
sendH264(socket, callBack, payload + sent + 4, nalSize, channel,
|
||||
(sent + nalSize + 4) >= payloadlen ? true : false);
|
||||
sent += nalSize + 4;
|
||||
}
|
||||
return;
|
||||
|
@ -299,8 +289,7 @@ namespace RTP{
|
|||
increaseSequence();
|
||||
}
|
||||
|
||||
void Packet::sendRTCP_SR(long long &connectedAt, void *socket, unsigned int tid,
|
||||
DTSC::Meta &metadata,
|
||||
void Packet::sendRTCP_SR(long long &connectedAt, void *socket, unsigned int tid, DTSC::Meta &metadata,
|
||||
void callBack(void *, char *, unsigned int, unsigned int)){
|
||||
char *rtcpData = (char *)malloc(32);
|
||||
if (!rtcpData){
|
||||
|
@ -322,8 +311,7 @@ namespace RTP{
|
|||
free(rtcpData);
|
||||
}
|
||||
|
||||
void Packet::sendRTCP_RR(long long &connectedAt, SDP::Track &sTrk, unsigned int tid,
|
||||
DTSC::Meta &metadata,
|
||||
void Packet::sendRTCP_RR(long long &connectedAt, SDP::Track &sTrk, unsigned int tid, DTSC::Meta &metadata,
|
||||
void callBack(void *, char *, unsigned int, unsigned int)){
|
||||
char *rtcpData = (char *)malloc(32);
|
||||
if (!rtcpData){
|
||||
|
@ -336,12 +324,9 @@ namespace RTP{
|
|||
Bit::htobs(rtcpData + 2, 7); // 7 4-byte words follow the header
|
||||
Bit::htobl(rtcpData + 4, sTrk.mySSRC); // set receiver identifier
|
||||
Bit::htobl(rtcpData + 8, sTrk.theirSSRC); // set source identifier
|
||||
rtcpData[12] =
|
||||
(sTrk.sorter.lostCurrent * 255) /
|
||||
(sTrk.sorter.lostCurrent + sTrk.sorter.packCurrent); // fraction lost since prev RR
|
||||
rtcpData[12] = (sTrk.sorter.lostCurrent * 255) / (sTrk.sorter.lostCurrent + sTrk.sorter.packCurrent); // fraction lost since prev RR
|
||||
Bit::htob24(rtcpData + 13, sTrk.sorter.lostTotal); // cumulative packets lost since start
|
||||
Bit::htobl(rtcpData + 16, sTrk.sorter.rtpSeq | (sTrk.sorter.packTotal &
|
||||
0xFFFF0000ul)); // highest sequence received
|
||||
Bit::htobl(rtcpData + 16, sTrk.sorter.rtpSeq | (sTrk.sorter.packTotal & 0xFFFF0000ul)); // highest sequence received
|
||||
Bit::htobl(rtcpData + 20, 0); /// \TODO jitter (diff in timestamp vs packet arrival)
|
||||
Bit::htobl(rtcpData + 24, 0); /// \TODO last SR (middle 32 bits of last SR or zero)
|
||||
Bit::htobl(rtcpData + 28, 0); /// \TODO delay since last SR in 2b seconds + 2b fraction
|
||||
|
@ -362,8 +347,7 @@ namespace RTP{
|
|||
Packet::Packet(unsigned int payloadType, unsigned int sequence, unsigned int timestamp,
|
||||
unsigned int ssrc, unsigned int csrcCount){
|
||||
managed = true;
|
||||
data = new char[12 + 4 * csrcCount + 2 +
|
||||
MAX_SEND]; // headerSize, 2 for FU-A, MAX_SEND for maximum sent size
|
||||
data = new char[12 + 4 * csrcCount + 2 + MAX_SEND]; // headerSize, 2 for FU-A, MAX_SEND for maximum sent size
|
||||
if (data){
|
||||
maxDataLen = 12 + 4 * csrcCount + 2 + MAX_SEND;
|
||||
data[0] = ((2) << 6) | ((0 & 1) << 5) | ((0 & 1) << 4) |
|
||||
|
@ -397,7 +381,6 @@ namespace RTP{
|
|||
}
|
||||
sentBytes = o.sentBytes;
|
||||
sentPackets = o.sentPackets;
|
||||
|
||||
}
|
||||
|
||||
void Packet::operator=(const Packet &o){
|
||||
|
@ -613,7 +596,8 @@ namespace RTP{
|
|||
int64_t pTime = pkt.getTimeStamp();
|
||||
if (!firstTime){
|
||||
firstTime = pTime + 1;
|
||||
INFO_MSG("RTP timestamp rollover expected in " PRETTY_PRINT_TIME, PRETTY_ARG_TIME((0xFFFFFFFFul - firstTime) / multiplier / 1000));
|
||||
INFO_MSG("RTP timestamp rollover expected in " PRETTY_PRINT_TIME,
|
||||
PRETTY_ARG_TIME((0xFFFFFFFFul - firstTime) / multiplier / 1000));
|
||||
}else{
|
||||
if (prevTime > pTime && pTime < 0x40000000lu && prevTime > 0x80000000lu){
|
||||
++wrapArounds;
|
||||
|
@ -657,8 +641,7 @@ namespace RTP{
|
|||
void toDTSC::handleAAC(uint64_t msTime, char *pl, uint32_t plSize){
|
||||
// assume AAC packets are single AU units
|
||||
/// \todo Support other input than single AU units
|
||||
unsigned int headLen =
|
||||
(Bit::btohs(pl) >> 3) + 2; // in bits, so /8, plus two for the prepended size
|
||||
unsigned int headLen = (Bit::btohs(pl) >> 3) + 2; // in bits, so /8, plus two for the prepended size
|
||||
DTSC::Packet nextPack;
|
||||
uint16_t samples = aac::AudSpecConf::samples(init);
|
||||
uint32_t sampleOffset = 0;
|
||||
|
@ -808,8 +791,7 @@ namespace RTP{
|
|||
isKey ? "key" : "i", frameNo, fps, packCount, (frameNo - packCount), offset);
|
||||
}else{
|
||||
// For non-steady frame rate, assume no offsets are used and the timestamp is already correct
|
||||
VERYHIGH_MSG("Packing time %llu = %sframe %llu (variable rate)", ts, isKey ? "key" : "i",
|
||||
packCount);
|
||||
VERYHIGH_MSG("Packing time %llu = %sframe %llu (variable rate)", ts, isKey ? "key" : "i", packCount);
|
||||
}
|
||||
// Fill the new DTSC packet, buffer it.
|
||||
DTSC::Packet nextPack;
|
||||
|
@ -823,8 +805,7 @@ namespace RTP{
|
|||
/// for that data.
|
||||
/// Prints a WARN-level message if packet type is unsupported.
|
||||
/// \todo Support other H264 packets types?
|
||||
void toDTSC::handleH264(uint64_t msTime, char *pl, uint32_t plSize, bool missed,
|
||||
bool hasPadding){
|
||||
void toDTSC::handleH264(uint64_t msTime, char *pl, uint32_t plSize, bool missed, bool hasPadding){
|
||||
if (!plSize){
|
||||
WARN_MSG("Empty packet ignored!");
|
||||
return;
|
||||
|
@ -1000,8 +981,7 @@ namespace RTP{
|
|||
}else{
|
||||
// For non-steady frame rate, assume no offsets are used and the timestamp is already
|
||||
// correct
|
||||
VERYHIGH_MSG("Packing time %llu = %sframe %llu (variable rate)", ts, isKey ? "key" : "i",
|
||||
packCount);
|
||||
VERYHIGH_MSG("Packing time %llu = %sframe %llu (variable rate)", ts, isKey ? "key" : "i", packCount);
|
||||
}
|
||||
// Fill the new DTSC packet, buffer it.
|
||||
DTSC::Packet nextPack;
|
||||
|
@ -1031,8 +1011,7 @@ namespace RTP{
|
|||
isKey ? "key" : "i", frameNo, fps, packCount, (frameNo - packCount), offset);
|
||||
}else{
|
||||
// For non-steady frame rate, assume no offsets are used and the timestamp is already correct
|
||||
VERYHIGH_MSG("Packing time %llu = %sframe %llu (variable rate)", ts, isKey ? "key" : "i",
|
||||
packCount);
|
||||
VERYHIGH_MSG("Packing time %llu = %sframe %llu (variable rate)", ts, isKey ? "key" : "i", packCount);
|
||||
}
|
||||
// Fill the new DTSC packet, buffer it.
|
||||
DTSC::Packet nextPack;
|
||||
|
@ -1062,8 +1041,7 @@ namespace RTP{
|
|||
h264::isKeyframe(buffer + lastStart + 4, len - lastStart - 4));
|
||||
}
|
||||
|
||||
void toDTSC::handleVP8(uint64_t msTime, const char *buffer, const uint32_t len, bool missed,
|
||||
bool hasPadding){
|
||||
void toDTSC::handleVP8(uint64_t msTime, const char *buffer, const uint32_t len, bool missed, bool hasPadding){
|
||||
|
||||
// 1 byte is required but we assume that there some payload
|
||||
// data too :P
|
||||
|
@ -1139,8 +1117,7 @@ namespace RTP{
|
|||
// new frame and nothing missed? Send.
|
||||
if (start_of_frame && !missed){
|
||||
DTSC::Packet nextPack;
|
||||
nextPack.genericFill(msTime, 0, trackId, vp8FrameBuffer, vp8FrameBuffer.size(), 0,
|
||||
vp8BufferHasKeyframe);
|
||||
nextPack.genericFill(msTime, 0, trackId, vp8FrameBuffer, vp8FrameBuffer.size(), 0, vp8BufferHasKeyframe);
|
||||
packCount++;
|
||||
outPacket(nextPack);
|
||||
}
|
||||
|
@ -1170,4 +1147,3 @@ namespace RTP{
|
|||
if (start_of_frame && is_keyframe){vp8BufferHasKeyframe = true;}
|
||||
}
|
||||
}// namespace RTP
|
||||
|
||||
|
|
16
lib/rtp.h
16
lib/rtp.h
|
@ -65,17 +65,14 @@ namespace RTP{
|
|||
void sendMPEG2(void *socket, void callBack(void *, char *, unsigned int, unsigned int),
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel);
|
||||
void sendData(void *socket, void callBack(void *, char *, unsigned int, unsigned int),
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel,
|
||||
std::string codec);
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel, std::string codec);
|
||||
void sendRTCP_SR(long long &connectedAt, void *socket, unsigned int tid, DTSC::Meta &metadata,
|
||||
void callBack(void *, char *, unsigned int, unsigned int));
|
||||
void sendRTCP_RR(long long &connectedAt, SDP::Track &sTrk, unsigned int tid,
|
||||
DTSC::Meta &metadata,
|
||||
void callBack(void *, char *, unsigned int, unsigned int));
|
||||
DTSC::Meta &metadata, void callBack(void *, char *, unsigned int, unsigned int));
|
||||
|
||||
Packet();
|
||||
Packet(unsigned int pt, unsigned int seq, unsigned int ts, unsigned int ssr,
|
||||
unsigned int csrcCount = 0);
|
||||
Packet(unsigned int pt, unsigned int seq, unsigned int ts, unsigned int ssr, unsigned int csrcCount = 0);
|
||||
Packet(const Packet &o);
|
||||
void operator=(const Packet &o);
|
||||
~Packet();
|
||||
|
@ -173,13 +170,10 @@ namespace RTP{
|
|||
void handleH264Multi(uint64_t ts, char *buffer, const uint32_t len);
|
||||
std::string spsData; ///< SPS for H264
|
||||
std::string ppsData; ///< PPS for H264
|
||||
void handleVP8(uint64_t msTime, const char *buffer, const uint32_t len, bool missed,
|
||||
bool hasPadding);
|
||||
Util::ResizeablePointer
|
||||
vp8FrameBuffer; ///< Stores successive VP8 payload data. We always start with the first
|
||||
void handleVP8(uint64_t msTime, const char *buffer, const uint32_t len, bool missed, bool hasPadding);
|
||||
Util::ResizeablePointer vp8FrameBuffer; ///< Stores successive VP8 payload data. We always start with the first
|
||||
///< partition; but we might be missing other partitions when they were
|
||||
///< lost. (a partition is basically what's called a slice in H264).
|
||||
bool vp8BufferHasKeyframe;
|
||||
};
|
||||
}// namespace RTP
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "defines.h"
|
||||
#include "rtp_fec.h"
|
||||
#include "rtp.h"
|
||||
#include "rtp_fec.h"
|
||||
|
||||
namespace RTP{
|
||||
/// Based on the `block PT` value, we can either find the
|
||||
|
@ -49,8 +49,7 @@ namespace RTP{
|
|||
/// | mask cont. (present only when L = 1) |
|
||||
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
///
|
||||
PacketFEC::PacketFEC() {
|
||||
}
|
||||
PacketFEC::PacketFEC(){}
|
||||
|
||||
PacketFEC::~PacketFEC(){
|
||||
receivedSeqNums.clear();
|
||||
|
@ -65,7 +64,8 @@ namespace RTP{
|
|||
}
|
||||
|
||||
if (nbytes < 23){
|
||||
FAIL_MSG("Given fecData is too small. Should be at least: 12 (RTP) + 1 (RED) + 10 (FEC) 23 bytes.");
|
||||
FAIL_MSG("Given fecData is too small. Should be at least: 12 (RTP) + 1 (RED) + 10 (FEC) 23 "
|
||||
"bytes.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,8 @@ namespace RTP{
|
|||
uint8_t *redHeader = (uint8_t *)(data + rtpPkt.getHsize());
|
||||
uint8_t moreBlocks = redHeader[0] & 0x80;
|
||||
if (moreBlocks == 1){
|
||||
FAIL_MSG("RED header indicates there are multiple blocks. Haven't seen this before (@todo implement, exiting now).");
|
||||
FAIL_MSG("RED header indicates there are multiple blocks. Haven't seen this before (@todo "
|
||||
"implement, exiting now).");
|
||||
// \todo do not EXIT!
|
||||
return false;
|
||||
}
|
||||
|
@ -112,7 +113,8 @@ namespace RTP{
|
|||
uint8_t PacketFEC::getExtensionFlag(){
|
||||
|
||||
if (fecPacketData.size() == 0){
|
||||
FAIL_MSG("Cannot get extension-flag from the FEC header; fecPacketData member is not set. Not initialized?");
|
||||
FAIL_MSG("Cannot get extension-flag from the FEC header; fecPacketData member is not set. "
|
||||
"Not initialized?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -122,7 +124,8 @@ namespace RTP{
|
|||
uint8_t PacketFEC::getLongMaskFlag(){
|
||||
|
||||
if (fecPacketData.size() == 0){
|
||||
FAIL_MSG("Cannot get the long-mask-flag from the FEC header. fecPacketData member is not set. Not initialized?");
|
||||
FAIL_MSG("Cannot get the long-mask-flag from the FEC header. fecPacketData member is not "
|
||||
"set. Not initialized?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -133,13 +136,12 @@ namespace RTP{
|
|||
uint8_t PacketFEC::getNumBytesUsedForMask(){
|
||||
|
||||
if (fecPacketData.size() == 0){
|
||||
FAIL_MSG("Cannot get the number of bytes used by the mask. fecPacketData member is not set. Not initialized?");
|
||||
FAIL_MSG("Cannot get the number of bytes used by the mask. fecPacketData member is not set. "
|
||||
"Not initialized?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (getLongMaskFlag() == 0) {
|
||||
return 2;
|
||||
}
|
||||
if (getLongMaskFlag() == 0){return 2;}
|
||||
|
||||
return 6;
|
||||
}
|
||||
|
@ -147,7 +149,8 @@ namespace RTP{
|
|||
uint16_t PacketFEC::getSequenceBaseNumber(){
|
||||
|
||||
if (fecPacketData.size() == 0){
|
||||
FAIL_MSG("Cannot get the sequence base number. fecPacketData member is not set. Not initialized?");
|
||||
FAIL_MSG(
|
||||
"Cannot get the sequence base number. fecPacketData member is not set. Not initialized?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -189,7 +192,8 @@ namespace RTP{
|
|||
uint16_t PacketFEC::getLevel0ProtectionLength(){
|
||||
|
||||
if (fecPacketData.size() == 0){
|
||||
FAIL_MSG("Cannot get the level 0 protection length. fecPacketData member is not set. Not initialized?");
|
||||
FAIL_MSG("Cannot get the level 0 protection length. fecPacketData member is not set. Not "
|
||||
"initialized?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -207,7 +211,8 @@ namespace RTP{
|
|||
|
||||
char *fecHeader = getFECHeader();
|
||||
if (!fecHeader){
|
||||
FAIL_MSG("Cannot get the FEC header which we need to get the `length recovery` field. Not initialized?");
|
||||
FAIL_MSG("Cannot get the FEC header which we need to get the `length recovery` field. Not "
|
||||
"initialized?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -246,9 +251,7 @@ namespace RTP{
|
|||
}
|
||||
|
||||
uint16_t seqNumBase = getSequenceBaseNumber();
|
||||
if (seqNumBase == 0) {
|
||||
WARN_MSG("Base sequence number is 0; it's possible but unlikely.");
|
||||
}
|
||||
if (seqNumBase == 0){WARN_MSG("Base sequence number is 0; it's possible but unlikely.");}
|
||||
|
||||
// Skip the `Protection Length`
|
||||
maskPtr = maskPtr + 2;
|
||||
|
@ -292,24 +295,21 @@ namespace RTP{
|
|||
/// The `receivedMediaPackets` is the history of media packets
|
||||
/// that you received and keep in a memory. These are used
|
||||
/// when XORing when we reconstruct a packet.
|
||||
void PacketFEC::tryToRecoverMissingPacket(std::map<uint16_t, Packet>& receivedMediaPackets, Packet& reconstructedPacket) {
|
||||
void PacketFEC::tryToRecoverMissingPacket(std::map<uint16_t, Packet> &receivedMediaPackets,
|
||||
Packet &reconstructedPacket){
|
||||
|
||||
// Mark all the media packets that we protect and which have
|
||||
// been received as "received" in our internal list.
|
||||
std::set<uint16_t>::iterator protIt = coveredSeqNums.begin();
|
||||
while (protIt != coveredSeqNums.end()){
|
||||
if (receivedMediaPackets.count(*protIt) == 1) {
|
||||
addReceivedSequenceNumber(*protIt);
|
||||
}
|
||||
if (receivedMediaPackets.count(*protIt) == 1){addReceivedSequenceNumber(*protIt);}
|
||||
protIt++;
|
||||
}
|
||||
|
||||
// We have received all media packets that we could recover;
|
||||
// so there is no need for this FEC packet.
|
||||
// @todo Jaron shall we reuse allocs/PacketFECs?
|
||||
if (receivedSeqNums.size() == coveredSeqNums.size()) {
|
||||
return;
|
||||
}
|
||||
if (receivedSeqNums.size() == coveredSeqNums.size()){return;}
|
||||
|
||||
if (coveredSeqNums.size() != (receivedSeqNums.size() + 1)){
|
||||
// missing more then 1 packet. we can only recover when
|
||||
|
@ -402,9 +402,7 @@ namespace RTP{
|
|||
}
|
||||
Packet &mediaPacket = receivedMediaPackets[seqNum];
|
||||
char *mediaData = mediaPacket.ptr() + mediaPacket.getHsize();
|
||||
for (size_t i = 0; i < recoverPayloadSize; ++i) {
|
||||
recoverData[12 + i] ^= mediaData[i];
|
||||
}
|
||||
for (size_t i = 0; i < recoverPayloadSize; ++i){recoverData[12 + i] ^= mediaData[i];}
|
||||
++protIt;
|
||||
}
|
||||
|
||||
|
@ -414,7 +412,6 @@ namespace RTP{
|
|||
// @todo check what other header fields we need to fix.
|
||||
}
|
||||
|
||||
|
||||
void FECSorter::addPacket(const Packet &pack){
|
||||
if (tmpVideoLossPrevention & SDP_LOSS_PREVENTION_ULPFEC){
|
||||
packetHistory[pack.getSequence()] = pack;
|
||||
|
@ -447,12 +444,8 @@ namespace RTP{
|
|||
/// |F| block PT | timestamp offset | block length |
|
||||
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
///
|
||||
void FECSorter::addREDPacket(char* dat,
|
||||
unsigned int len,
|
||||
uint8_t codecPayloadType,
|
||||
uint8_t REDPayloadType,
|
||||
uint8_t ULPFECPayloadType)
|
||||
{
|
||||
void FECSorter::addREDPacket(char *dat, unsigned int len, uint8_t codecPayloadType,
|
||||
uint8_t REDPayloadType, uint8_t ULPFECPayloadType){
|
||||
|
||||
RTP::Packet pkt(dat, len);
|
||||
if (pkt.getPayloadType() != REDPayloadType){
|
||||
|
@ -510,7 +503,8 @@ namespace RTP{
|
|||
fec->tryToRecoverMissingPacket(packetHistory, recreatedPacket);
|
||||
if (recreatedPacket.ptr() != NULL){
|
||||
char *pl = recreatedPacket.getPayload();
|
||||
WARN_MSG(" => reconstructed %u, %02X %02X %02X %02X | %02X %02X %02X %02X", recreatedPacket.getSequence(), pl[0], pl[1], pl[2], pl[3], pl[4], pl[5], pl[6], pl[7]);
|
||||
WARN_MSG(" => reconstructed %u, %02X %02X %02X %02X | %02X %02X %02X %02X",
|
||||
recreatedPacket.getSequence(), pl[0], pl[1], pl[2], pl[3], pl[4], pl[5], pl[6], pl[7]);
|
||||
addPacket(recreatedPacket);
|
||||
}
|
||||
return;
|
||||
|
@ -531,14 +525,13 @@ namespace RTP{
|
|||
size_t nfecs = fecPackets.size();
|
||||
for (size_t i = 0; i < nfecs; ++i){
|
||||
PacketFEC *fec = fecPackets[i];
|
||||
if (fec->coversSequenceNumber(sn)) {
|
||||
return fec;
|
||||
}
|
||||
if (fec->coversSequenceNumber(sn)){return fec;}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FECPacket::sendRTCP_RR(RTP::FECSorter &sorter, uint32_t mySSRC, uint32_t theirSSRC, void* userData, void callBack(void* userData, const char* payload, uint32_t nbytes)) {
|
||||
void FECPacket::sendRTCP_RR(RTP::FECSorter &sorter, uint32_t mySSRC, uint32_t theirSSRC, void *userData,
|
||||
void callBack(void *userData, const char *payload, uint32_t nbytes)){
|
||||
char *rtcpData = (char *)malloc(32);
|
||||
if (!rtcpData){
|
||||
FAIL_MSG("Could not allocate 32 bytes. Something is seriously messed up.");
|
||||
|
@ -550,12 +543,9 @@ namespace RTP{
|
|||
Bit::htobs(rtcpData + 2, 7); // 7 4-byte words follow the header
|
||||
Bit::htobl(rtcpData + 4, mySSRC); // set receiver identifier
|
||||
Bit::htobl(rtcpData + 8, theirSSRC); // set source identifier
|
||||
rtcpData[12] =
|
||||
(sorter.lostCurrent * 255) /
|
||||
(sorter.lostCurrent + sorter.packCurrent); // fraction lost since prev RR
|
||||
rtcpData[12] = (sorter.lostCurrent * 255) / (sorter.lostCurrent + sorter.packCurrent); // fraction lost since prev RR
|
||||
Bit::htob24(rtcpData + 13, sorter.lostTotal); // cumulative packets lost since start
|
||||
Bit::htobl(rtcpData + 16, sorter.rtpSeq | (sorter.packTotal &
|
||||
0xFFFF0000ul)); // highest sequence received
|
||||
Bit::htobl(rtcpData + 16, sorter.rtpSeq | (sorter.packTotal & 0xFFFF0000ul)); // highest sequence received
|
||||
Bit::htobl(rtcpData + 20, 0); /// \TODO jitter (diff in timestamp vs packet arrival)
|
||||
Bit::htobl(rtcpData + 24, 0); /// \TODO last SR (middle 32 bits of last SR or zero)
|
||||
Bit::htobl(rtcpData + 28, 0); /// \TODO delay since last SR in 2b seconds + 2b fraction
|
||||
|
@ -565,5 +555,4 @@ namespace RTP{
|
|||
free(rtcpData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}// namespace RTP
|
||||
|
|
|
@ -21,14 +21,12 @@ namespace RTP{
|
|||
public:
|
||||
PacketFEC();
|
||||
~PacketFEC();
|
||||
bool initWithREDPacket(
|
||||
const char *data,
|
||||
bool initWithREDPacket(const char *data,
|
||||
size_t nbytes); /// Initialize using the given data. `data` must point to the first byte of
|
||||
/// the RTP packet which contains the RED and FEC headers and data.
|
||||
uint8_t getExtensionFlag(); ///< From fec header: should be 0, see
|
||||
///< https://tools.ietf.org/html/rfc5109#section-7.3.
|
||||
uint8_t
|
||||
getLongMaskFlag(); ///< From fec header: returns 0 when the short mask version is used (16
|
||||
uint8_t getLongMaskFlag(); ///< From fec header: returns 0 when the short mask version is used (16
|
||||
///< bits), otherwise 1 (48 bits). The mask is used to calculate what
|
||||
///< sequence numbers are protected, starting at the base sequence number.
|
||||
uint16_t getSequenceBaseNumber(); ///< From fec header: get the base sequence number. The base
|
||||
|
@ -44,13 +42,11 @@ namespace RTP{
|
|||
/// and paylaod.
|
||||
char *getFECHeader(); ///< Get a pointer to the first byte of the FEC header.
|
||||
uint16_t getLevel0ProtectionLength(); ///< Get the length of the `getLevel0Payload()`.
|
||||
uint16_t
|
||||
getLengthRecovery(); ///< Get the `length recovery` value (Little Endian). This value is used
|
||||
uint16_t getLengthRecovery(); ///< Get the `length recovery` value (Little Endian). This value is used
|
||||
///< while XORing to recover the length of the missing media packet.
|
||||
bool coversSequenceNumber(uint16_t sn); ///< Returns true when this `PacketFEC` instance is used
|
||||
///< to protect the given sequence number.
|
||||
void
|
||||
addReceivedSequenceNumber(uint16_t sn); ///< Whenever you receive a media packet (complete) call
|
||||
void addReceivedSequenceNumber(uint16_t sn); ///< Whenever you receive a media packet (complete) call
|
||||
///< this as we need to know if enough media packets
|
||||
///< exist that are needed to recover another one.
|
||||
void tryToRecoverMissingPacket(
|
||||
|
@ -61,17 +57,14 @@ namespace RTP{
|
|||
///< will fill the packet passed by reference.
|
||||
|
||||
private:
|
||||
bool
|
||||
extractCoveringSequenceNumbers(); ///< Used internally to fill the `coveredSeqNums` member which
|
||||
bool extractCoveringSequenceNumbers(); ///< Used internally to fill the `coveredSeqNums` member which
|
||||
///< tell us what media packets this FEC packet rotects.
|
||||
|
||||
public:
|
||||
Util::ResizeablePointer fecPacketData;
|
||||
Util::ResizeablePointer recoverData;
|
||||
std::set<uint16_t>
|
||||
coveredSeqNums; ///< The sequence numbers of the packets that this FEC protects.
|
||||
std::set<uint16_t>
|
||||
receivedSeqNums; ///< We keep track of sequence numbers that were received (at some higher
|
||||
std::set<uint16_t> coveredSeqNums; ///< The sequence numbers of the packets that this FEC protects.
|
||||
std::set<uint16_t> receivedSeqNums; ///< We keep track of sequence numbers that were received (at some higher
|
||||
///< level). We can only recover 1 media packet and this is used to check
|
||||
///< if this `PacketFEC` instance is capable of recovering anything.
|
||||
};
|
||||
|
@ -97,4 +90,3 @@ namespace RTP{
|
|||
};
|
||||
|
||||
}// namespace RTP
|
||||
|
||||
|
|
61
lib/sdp.cpp
61
lib/sdp.cpp
|
@ -1,12 +1,12 @@
|
|||
#include "sdp.h"
|
||||
#include "adts.h"
|
||||
#include "defines.h"
|
||||
#include "encode.h"
|
||||
#include "h264.h"
|
||||
#include "h265.h"
|
||||
#include "http_parser.h"
|
||||
#include "util.h"
|
||||
#include "sdp.h"
|
||||
#include "url.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace SDP{
|
||||
|
||||
|
@ -15,7 +15,6 @@ namespace SDP{
|
|||
snglState->updateInit(track, initData);
|
||||
}
|
||||
|
||||
|
||||
Track::Track(){
|
||||
rtcpSent = 0;
|
||||
channel = -1;
|
||||
|
@ -67,15 +66,13 @@ namespace SDP{
|
|||
size_t count = avccbox.getSPSCount();
|
||||
for (size_t i = 0; i < count; ++i){
|
||||
mediaDesc << (i ? "," : "")
|
||||
<< Encodings::Base64::encode(
|
||||
std::string(avccbox.getSPS(i), avccbox.getSPSLen(i)));
|
||||
<< Encodings::Base64::encode(std::string(avccbox.getSPS(i), avccbox.getSPSLen(i)));
|
||||
}
|
||||
mediaDesc << ",";
|
||||
count = avccbox.getPPSCount();
|
||||
for (size_t i = 0; i < count; ++i){
|
||||
mediaDesc << (i ? "," : "")
|
||||
<< Encodings::Base64::encode(
|
||||
std::string(avccbox.getPPS(i), avccbox.getPPSLen(i)));
|
||||
<< Encodings::Base64::encode(std::string(avccbox.getPPS(i), avccbox.getPPSLen(i)));
|
||||
}
|
||||
mediaDesc << "\r\n"
|
||||
<< "a=framerate:" << ((double)trk.fpks) / 1000.0
|
||||
|
@ -188,8 +185,7 @@ namespace SDP{
|
|||
}else{
|
||||
mediaDesc << "m=audio 0 RTP/AVP 103"
|
||||
<< "\r\n";
|
||||
mediaDesc << "a=rtpmap:103 L" << trk.size << "/" << trk.rate << "/" << trk.channels
|
||||
<< "\r\n";
|
||||
mediaDesc << "a=rtpmap:103 L" << trk.size << "/" << trk.rate << "/" << trk.channels << "\r\n";
|
||||
}
|
||||
mediaDesc << "a=control:track" << trk.trackID << "\r\n";
|
||||
}else if (trk.codec == "opus"){
|
||||
|
@ -212,8 +208,7 @@ namespace SDP{
|
|||
// We simply request interleaved delivery over a trackNo-based identifier.
|
||||
// No need to set any internal state, parseTransport will handle it all.
|
||||
std::stringstream tStr;
|
||||
tStr << "RTP/AVP/TCP;unicast;interleaved=" << ((trackNo - 1) * 2) << "-"
|
||||
<< ((trackNo - 1) * 2 + 1);
|
||||
tStr << "RTP/AVP/TCP;unicast;interleaved=" << ((trackNo - 1) * 2) << "-" << ((trackNo - 1) * 2 + 1);
|
||||
return tStr.str();
|
||||
}else{
|
||||
// A little more tricky: we need to find free ports and remember them.
|
||||
|
@ -277,8 +272,7 @@ namespace SDP{
|
|||
return false;
|
||||
}
|
||||
if (transport.find("TCP") != std::string::npos){
|
||||
std::string chanE =
|
||||
transport.substr(transport.find("interleaved=") + 12,
|
||||
std::string chanE = transport.substr(transport.find("interleaved=") + 12,
|
||||
(transport.size() - transport.rfind('-') - 1)); // extract channel ID
|
||||
channel = atol(chanE.c_str());
|
||||
rtcpSent = 0;
|
||||
|
@ -289,8 +283,7 @@ namespace SDP{
|
|||
cPortA = cPortB = 0;
|
||||
size_t sPort_loc = transport.rfind("server_port=") + 12;
|
||||
if (sPort_loc != std::string::npos){
|
||||
sPortA =
|
||||
atol(transport.substr(sPort_loc, transport.find('-', sPort_loc) - sPort_loc).c_str());
|
||||
sPortA = atol(transport.substr(sPort_loc, transport.find('-', sPort_loc) - sPort_loc).c_str());
|
||||
sPortB = atol(transport.substr(transport.find('-', sPort_loc) + 1).c_str());
|
||||
}
|
||||
size_t port_loc = transport.rfind("client_port=") + 12;
|
||||
|
@ -311,8 +304,7 @@ namespace SDP{
|
|||
std::stringstream tStr;
|
||||
tStr << "RTP/AVP/UDP;unicast;client_port=" << cPortA << '-' << cPortB << ";";
|
||||
if (source.size()){tStr << "source=" << source << ";";}
|
||||
tStr << "server_port=" << portA << "-" << portB << ";ssrc=" << std::hex << mySSRC
|
||||
<< std::dec;
|
||||
tStr << "server_port=" << portA << "-" << portB << ";ssrc=" << std::hex << mySSRC << std::dec;
|
||||
transportString = tStr.str();
|
||||
}else{
|
||||
// Client mode - check ports and/or obey given ports if possible
|
||||
|
@ -342,11 +334,9 @@ namespace SDP{
|
|||
}
|
||||
|
||||
/// Gets the rtpInfo for a given DTSC::Track, source identifier and timestamp (in millis).
|
||||
std::string Track::rtpInfo(const DTSC::Track &trk, const std::string &source,
|
||||
uint64_t currentTime){
|
||||
std::string Track::rtpInfo(const DTSC::Track &trk, const std::string &source, uint64_t currentTime){
|
||||
std::stringstream rInfo;
|
||||
rInfo << "url=" << source << "/track" << trk.trackID
|
||||
<< ";"; // get the current url, not localhost
|
||||
rInfo << "url=" << source << "/track" << trk.trackID << ";"; // get the current url, not localhost
|
||||
rInfo << "sequence=" << pack.getSequence() << ";rtptime=" << currentTime * getMultiplier(trk);
|
||||
return rInfo.str();
|
||||
}
|
||||
|
@ -541,8 +531,7 @@ namespace SDP{
|
|||
// a=fmtp:97
|
||||
// profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;
|
||||
// config=120856E500
|
||||
FAIL_MSG("AAC transport mode not supported: %s",
|
||||
tracks[trackNo].getParamString("mode").c_str());
|
||||
FAIL_MSG("AAC transport mode not supported: %s", tracks[trackNo].getParamString("mode").c_str());
|
||||
nope = true;
|
||||
myMeta->tracks.erase(trackNo);
|
||||
tracks.erase(trackNo);
|
||||
|
@ -562,12 +551,9 @@ namespace SDP{
|
|||
updateH264Init(trackNo);
|
||||
}
|
||||
if (thisTrack->codec == "HEVC"){
|
||||
tracks[trackNo].hevcInfo.addUnit(
|
||||
Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-vps")));
|
||||
tracks[trackNo].hevcInfo.addUnit(
|
||||
Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-sps")));
|
||||
tracks[trackNo].hevcInfo.addUnit(
|
||||
Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-pps")));
|
||||
tracks[trackNo].hevcInfo.addUnit(Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-vps")));
|
||||
tracks[trackNo].hevcInfo.addUnit(Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-sps")));
|
||||
tracks[trackNo].hevcInfo.addUnit(Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-pps")));
|
||||
updateH265Init(trackNo);
|
||||
}
|
||||
continue;
|
||||
|
@ -639,8 +625,7 @@ namespace SDP{
|
|||
if (H.url == "200"){
|
||||
++trackCounter;
|
||||
if (!tracks.count(trackCounter)){return 0;}
|
||||
if (!tracks[trackCounter].parseTransport(H.GetHeader("Transport"), cH, src,
|
||||
myMeta->tracks[trackCounter])){
|
||||
if (!tracks[trackCounter].parseTransport(H.GetHeader("Transport"), cH, src, myMeta->tracks[trackCounter])){
|
||||
return 0;
|
||||
}
|
||||
return trackCounter;
|
||||
|
@ -660,13 +645,11 @@ namespace SDP{
|
|||
}
|
||||
|
||||
if ((urlString.size() >= it->second.control.size() &&
|
||||
urlString.substr(urlString.size() - it->second.control.size()) ==
|
||||
it->second.control) ||
|
||||
urlString.substr(urlString.size() - it->second.control.size()) == it->second.control) ||
|
||||
(pw.size() >= it->second.control.size() &&
|
||||
pw.substr(pw.size() - it->second.control.size()) == it->second.control)){
|
||||
INFO_MSG("Parsing SETUP against track %lu", it->first);
|
||||
if (!it->second.parseTransport(H.GetHeader("Transport"), cH, src,
|
||||
myMeta->tracks[it->first])){
|
||||
if (!it->second.parseTransport(H.GetHeader("Transport"), cH, src, myMeta->tracks[it->first])){
|
||||
return 0;
|
||||
}
|
||||
return it->first;
|
||||
|
@ -677,8 +660,7 @@ namespace SDP{
|
|||
uint32_t trackNo = atoi(H.url.c_str() + H.url.find("/track") + 6);
|
||||
if (trackNo){
|
||||
INFO_MSG("Parsing SETUP against track %lu", trackNo);
|
||||
if (!tracks[trackNo].parseTransport(H.GetHeader("Transport"), cH, src,
|
||||
myMeta->tracks[trackNo])){
|
||||
if (!tracks[trackNo].parseTransport(H.GetHeader("Transport"), cH, src, myMeta->tracks[trackNo])){
|
||||
return 0;
|
||||
}
|
||||
return trackNo;
|
||||
|
@ -701,9 +683,7 @@ namespace SDP{
|
|||
}
|
||||
|
||||
void State::updateInit(const uint64_t trackNo, const std::string &initData){
|
||||
if (myMeta->tracks.count(trackNo)){
|
||||
myMeta->tracks[trackNo].init = initData;
|
||||
}
|
||||
if (myMeta->tracks.count(trackNo)){myMeta->tracks[trackNo].init = initData;}
|
||||
}
|
||||
|
||||
/// Handles RTP packets generically, for both TCP and UDP-based connections.
|
||||
|
@ -714,4 +694,3 @@ namespace SDP{
|
|||
}
|
||||
|
||||
}// namespace SDP
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@ namespace SDP{
|
|||
class Track{
|
||||
public:
|
||||
Track();
|
||||
std::string generateTransport(uint32_t trackNo, const std::string &dest = "",
|
||||
bool TCPmode = true);
|
||||
std::string generateTransport(uint32_t trackNo, const std::string &dest = "", bool TCPmode = true);
|
||||
std::string getParamString(const std::string ¶m) const;
|
||||
uint64_t getParamInt(const std::string ¶m) const;
|
||||
bool parseTransport(const std::string &transport, const std::string &host,
|
||||
|
@ -54,6 +53,7 @@ namespace SDP{
|
|||
uint32_t getTrackNoForChannel(uint8_t chan);
|
||||
uint32_t parseSetup(HTTP::Parser &H, const std::string &host, const std::string &source);
|
||||
void handleIncomingRTP(const uint64_t track, const RTP::Packet &pkt);
|
||||
|
||||
public:
|
||||
DTSC::Meta *myMeta;
|
||||
std::map<uint32_t, RTP::toDTSC> tConv; ///< Converters to DTSC
|
||||
|
@ -62,4 +62,3 @@ namespace SDP{
|
|||
|
||||
std::string mediaDescription(const DTSC::Track &trk);
|
||||
}// namespace SDP
|
||||
|
||||
|
|
|
@ -75,24 +75,20 @@ namespace SDP{
|
|||
return "";
|
||||
}
|
||||
|
||||
static std::vector<std::string> sdp_split(
|
||||
const std::string &str, const std::string &delim,
|
||||
static std::vector<std::string>
|
||||
sdp_split(const std::string &str, const std::string &delim,
|
||||
bool keepEmpty); // Split a string on the given delimeter and return a vector with the parts.
|
||||
static bool
|
||||
sdp_extract_payload_type(const std::string &str,
|
||||
static bool sdp_extract_payload_type(const std::string &str,
|
||||
uint64_t &result); // Extract the payload number from a SDP line that
|
||||
// starts like: `a=something:[payloadtype]`.
|
||||
static bool sdp_get_name_value_from_varval(
|
||||
const std::string &str, std::string &var,
|
||||
static bool sdp_get_name_value_from_varval(const std::string &str, std::string &var,
|
||||
std::string &value); // Extracts the `name` and `value` from a string like `<name>=<value>`.
|
||||
// The `name` will always be converted to lowercase!.
|
||||
static void sdp_get_all_name_values_from_string(
|
||||
const std::string &str, std::map<std::string, std::string>
|
||||
&result); // Extracts all the name/value pairs from a string like:
|
||||
static void
|
||||
sdp_get_all_name_values_from_string(const std::string &str, std::map<std::string, std::string> &result); // Extracts all the name/value pairs from a string like:
|
||||
// `<name>=<value>;<name>=<value>`. The `name` part will
|
||||
// always be converted to lowercase.
|
||||
static bool
|
||||
sdp_get_attribute_value(const std::string &str,
|
||||
static bool sdp_get_attribute_value(const std::string &str,
|
||||
std::string &result); // Extract an "attribute" value, which is formatted
|
||||
// like: `a=something:<attribute-value>`
|
||||
static std::string string_to_upper(const std::string &str);
|
||||
|
@ -352,8 +348,7 @@ namespace SDP{
|
|||
bool Media::parseFrameRateLine(const std::string &line){
|
||||
|
||||
if (line.substr(0, 12) != "a=framerate:"){
|
||||
ERROR_MSG("Cannot parse the `a=framerate:` line because it's incorrectly formatted: `%s`.",
|
||||
line.c_str());
|
||||
ERROR_MSG("Cannot parse the `a=framerate:` line because it's incorrectly formatted: `%s`.", line.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -533,14 +528,10 @@ namespace SDP{
|
|||
MediaFormat *Media::getRetransMissionFormatForPayloadType(uint64_t pt){
|
||||
|
||||
std::vector<SDP::MediaFormat *> rtxFormats = getFormatsForEncodingName("RTX");
|
||||
if (rtxFormats.size() == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (rtxFormats.size() == 0){return NULL;}
|
||||
|
||||
for (size_t i = 0; i < rtxFormats.size(); ++i){
|
||||
if (rtxFormats[i]->associatedPayloadType == pt) {
|
||||
return rtxFormats[i];
|
||||
}
|
||||
if (rtxFormats[i]->associatedPayloadType == pt){return rtxFormats[i];}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -567,8 +558,7 @@ namespace SDP{
|
|||
///
|
||||
/// @param mediaType `video` or `audio`
|
||||
/// @param encodingName Encoding name in fullcaps, e.g. `H264`, `OPUS`, etc.
|
||||
MediaFormat *Session::getMediaFormatByEncodingName(const std::string &mediaType,
|
||||
const std::string &encodingName){
|
||||
MediaFormat *Session::getMediaFormatByEncodingName(const std::string &mediaType, const std::string &encodingName){
|
||||
SDP::Media *media = getMediaForType(mediaType);
|
||||
if (!media){
|
||||
WARN_MSG("No SDP::Media found for media type %s.", mediaType.c_str());
|
||||
|
@ -666,8 +656,7 @@ namespace SDP{
|
|||
return true;
|
||||
}
|
||||
|
||||
static std::vector<std::string> sdp_split(const std::string &str, const std::string &delim,
|
||||
bool keepEmpty){
|
||||
static std::vector<std::string> sdp_split(const std::string &str, const std::string &delim, bool keepEmpty){
|
||||
std::vector<std::string> strings;
|
||||
std::ostringstream word;
|
||||
for (size_t n = 0; n < str.size(); ++n){
|
||||
|
@ -686,8 +675,7 @@ namespace SDP{
|
|||
// extract payload type.
|
||||
size_t start_pos = str.find_first_of(':');
|
||||
size_t end_pos = str.find_first_of(' ', start_pos);
|
||||
if (start_pos == std::string::npos || end_pos == std::string::npos ||
|
||||
(start_pos + 1) >= end_pos){
|
||||
if (start_pos == std::string::npos || end_pos == std::string::npos || (start_pos + 1) >= end_pos){
|
||||
FAIL_MSG("Invalid `a=rtpmap` line. Has not payload type.");
|
||||
return false;
|
||||
}
|
||||
|
@ -704,8 +692,7 @@ namespace SDP{
|
|||
// when parsing the `a=fmtp:<fmt>` line.
|
||||
//
|
||||
// Note that we will always convert the `var` to lowercase.
|
||||
static bool sdp_get_name_value_from_varval(const std::string &str, std::string &var,
|
||||
std::string &value){
|
||||
static bool sdp_get_name_value_from_varval(const std::string &str, std::string &var, std::string &value){
|
||||
|
||||
if (str.empty()){
|
||||
ERROR_MSG("Cannot get `name` and `value` from string because the given string is empty. "
|
||||
|
@ -764,8 +751,7 @@ namespace SDP{
|
|||
|
||||
size_t start = str.find(":");
|
||||
if (start == std::string::npos){
|
||||
ERROR_MSG("Cannot get attribute value because we did not find the : character in %s.",
|
||||
str.c_str());
|
||||
ERROR_MSG("Cannot get attribute value because we did not find the : character in %s.", str.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -773,12 +759,9 @@ namespace SDP{
|
|||
return true;
|
||||
}
|
||||
|
||||
Answer::Answer() :
|
||||
isVideoEnabled(false),
|
||||
isAudioEnabled(false),
|
||||
candidatePort(0),
|
||||
videoLossPrevention(SDP_LOSS_PREVENTION_NONE)
|
||||
{}
|
||||
Answer::Answer()
|
||||
: isVideoEnabled(false), isAudioEnabled(false), candidatePort(0),
|
||||
videoLossPrevention(SDP_LOSS_PREVENTION_NONE){}
|
||||
|
||||
bool Answer::parseOffer(const std::string &sdp){
|
||||
|
||||
|
@ -964,10 +947,7 @@ namespace SDP{
|
|||
// them payload types into a string that is used with the
|
||||
// `m=` line to indicate we have support for these.
|
||||
supportedPayloadTypes.push_back((uint8_t)fmtMedia->payloadType);
|
||||
if ((videoLossPrevention & SDP_LOSS_PREVENTION_ULPFEC)
|
||||
&& fmtRED
|
||||
&& fmtULPFEC)
|
||||
{
|
||||
if ((videoLossPrevention & SDP_LOSS_PREVENTION_ULPFEC) && fmtRED && fmtULPFEC){
|
||||
supportedPayloadTypes.push_back(fmtRED->payloadType);
|
||||
supportedPayloadTypes.push_back(fmtULPFEC->payloadType);
|
||||
}
|
||||
|
@ -976,9 +956,7 @@ namespace SDP{
|
|||
size_t nels = supportedPayloadTypes.size();
|
||||
for (size_t k = 0; k < nels; ++k){
|
||||
ss << (int)supportedPayloadTypes[k];
|
||||
if ((k + 1) < nels) {
|
||||
ss << " ";
|
||||
}
|
||||
if ((k + 1) < nels){ss << " ";}
|
||||
}
|
||||
std::string payloadTypes = ss.str();
|
||||
|
||||
|
@ -1008,10 +986,7 @@ namespace SDP{
|
|||
addLine("a=%s", fmtMedia->rtpmap.c_str());
|
||||
|
||||
// BEGIN FEC/RTX: testing with just FEC or RTX
|
||||
if ((videoLossPrevention & SDP_LOSS_PREVENTION_ULPFEC)
|
||||
&& fmtRED
|
||||
&& fmtULPFEC)
|
||||
{
|
||||
if ((videoLossPrevention & SDP_LOSS_PREVENTION_ULPFEC) && fmtRED && fmtULPFEC){
|
||||
addLine("a=rtpmap:%u ulpfec/90000", fmtULPFEC->payloadType);
|
||||
addLine("a=rtpmap:%u red/90000", fmtRED->payloadType);
|
||||
}
|
||||
|
@ -1026,7 +1001,8 @@ namespace SDP{
|
|||
if (fmtMedia->encodingName == "H264"){
|
||||
std::string usedProfile = fmtMedia->getFormatParameterForName("profile-level-id");
|
||||
if (usedProfile != "42e01f"){
|
||||
WARN_MSG("The selected profile-level-id was not 42e01f. We rewrite it into this because that's what we support atm.");
|
||||
WARN_MSG("The selected profile-level-id was not 42e01f. We rewrite it into this because "
|
||||
"that's what we support atm.");
|
||||
usedProfile = "42e01f";
|
||||
}
|
||||
|
||||
|
@ -1074,8 +1050,7 @@ namespace SDP{
|
|||
SDP::Media &outMedia, SDP::MediaFormat &outFormat){
|
||||
Media *media = sdpOffer.getMediaForType(type);
|
||||
if (!media){
|
||||
INFO_MSG("Cannot enable %s codec; offer doesn't have %s media.", codecList.c_str(),
|
||||
type.c_str());
|
||||
INFO_MSG("Cannot enable %s codec; offer doesn't have %s media.", codecList.c_str(), type.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1103,7 +1078,8 @@ namespace SDP{
|
|||
continue;
|
||||
}
|
||||
if (formats[j]->getProfileLevelIdForH264() != "42e01f"){
|
||||
MEDIUM_MSG("Skipping this H264 format because it uses an unsupported profile-level-id.");
|
||||
MEDIUM_MSG(
|
||||
"Skipping this H264 format because it uses an unsupported profile-level-id.");
|
||||
format = NULL;
|
||||
continue;
|
||||
}
|
||||
|
@ -1179,6 +1155,4 @@ namespace SDP{
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}// namespace SDP
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include "dtsc.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "dtsc.h"
|
||||
|
||||
#define SDP_PAYLOAD_TYPE_NONE 9999 /// Define that is used to indicate a payload type is not set.
|
||||
#define SDP_LOSS_PREVENTION_NONE 0
|
||||
#define SDP_LOSS_PREVENTION_NACK (1 << 1) /// Use simple NACK based loss prevention. (e.g. send a NACK to pusher of video stream when a packet is lost)
|
||||
#define SDP_LOSS_PREVENTION_ULPFEC (1 << 2) /// Use FEC (See rtp.cpp, PacketRED). When used we try to add the correct `a=rtpmap` for RED and ULPFEC to the SDP when supported by the offer.
|
||||
#define SDP_LOSS_PREVENTION_NACK \
|
||||
(1 << 1) /// Use simple NACK based loss prevention. (e.g. send a NACK to pusher of video stream when a packet is lost)
|
||||
#define SDP_LOSS_PREVENTION_ULPFEC \
|
||||
(1 << 2) /// Use FEC (See rtp.cpp, PacketRED). When used we try to add the correct `a=rtpmap` for RED and ULPFEC to the SDP when supported by the offer.
|
||||
|
||||
namespace SDP{
|
||||
|
||||
|
@ -30,28 +32,23 @@ namespace SDP{
|
|||
class MediaFormat{
|
||||
public:
|
||||
MediaFormat();
|
||||
std::string getFormatParameterForName(
|
||||
const std::string &name) const; ///< Get a parameter which was part of the `a=fmtp:` line.
|
||||
uint32_t getAudioSampleRate()
|
||||
const; ///< Returns the audio sample rate. When `audioSampleRate` has been set this will be
|
||||
std::string getFormatParameterForName(const std::string &name) const; ///< Get a parameter which was part of the `a=fmtp:` line.
|
||||
uint32_t getAudioSampleRate() const; ///< Returns the audio sample rate. When `audioSampleRate` has been set this will be
|
||||
///< returned, otherwise we use the `payloadType` to determine the samplerate or
|
||||
///< return 0 when we fail to determine to samplerate.
|
||||
uint32_t getAudioNumChannels()
|
||||
const; ///< Returns the number of audio channels. When `audioNumChannels` has been set this
|
||||
uint32_t
|
||||
getAudioNumChannels() const; ///< Returns the number of audio channels. When `audioNumChannels` has been set this
|
||||
///< will be returned, otherwise we use the `payloadType` when it's set to determine
|
||||
///< the samplerate or we return 0 when we can't determine the number of channels.
|
||||
uint32_t getAudioBitSize()
|
||||
const; ///< Returns the audio bitsize. When `audioBitSize` has been set this will be
|
||||
uint32_t getAudioBitSize() const; ///< Returns the audio bitsize. When `audioBitSize` has been set this will be
|
||||
///< returned, othwerise we use the `encodingName` to determine the right
|
||||
///< `audioBitSize` or 0 when we can't determine the `audioBitSize`
|
||||
uint32_t
|
||||
getVideoRate() const; ///< Returns the video time base. When `videoRate` has been set this will
|
||||
uint32_t getVideoRate() const; ///< Returns the video time base. When `videoRate` has been set this will
|
||||
///< be returned, otherwise we use the `encodingName` to determine the
|
||||
///< right value or 0 when we can't determine the video rate.
|
||||
uint32_t getVideoOrAudioRate() const; ///< Returns whichever rate has been set.
|
||||
uint64_t getPayloadType() const; ///< Returns the `payloadType` member.
|
||||
int32_t
|
||||
getPacketizationModeForH264(); ///< When this represents a h264 format this will return the
|
||||
int32_t getPacketizationModeForH264(); ///< When this represents a h264 format this will return the
|
||||
///< packetization mode when it was provided in the SDP
|
||||
std::string getProfileLevelIdForH264(); ///< When this represents a H264 format, this will return the profile-level-id from the format parameters.
|
||||
|
||||
|
@ -72,12 +69,10 @@ namespace SDP{
|
|||
std::string iceUFrag; ///< From `a=ice-ufrag:<ufrag>, used with WebRTC / STUN.
|
||||
std::string icePwd; ///< From `a=ice-pwd:<pwd>`, used with WebRTC / STUN
|
||||
std::string rtpmap; ///< The `a=<rtpmap:...> value; value between brackets.
|
||||
std::map<std::string, std::string>
|
||||
formatParameters; ///< Stores the var-val pairs from `a=fmtp:<fmt>` entry e.g. =
|
||||
std::map<std::string, std::string> formatParameters; ///< Stores the var-val pairs from `a=fmtp:<fmt>` entry e.g. =
|
||||
///< `packetization-mode=1;profile-level-id=4d0029;sprop-parameter-sets=Z00AKeKQCADDYC3AQEBpB4kRUA==,aO48gA==`
|
||||
///< */
|
||||
std::set<std::string>
|
||||
rtcpFormats; ///< Stores the `fb-val` from the line with `a=rtcp-fb:<fmt> <fb-val>`.
|
||||
std::set<std::string> rtcpFormats; ///< Stores the `fb-val` from the line with `a=rtcp-fb:<fmt> <fb-val>`.
|
||||
};
|
||||
|
||||
class Media{
|
||||
|
@ -85,40 +80,32 @@ namespace SDP{
|
|||
Media();
|
||||
bool parseMediaLine(const std::string &sdpLine); ///< Parses `m=` line. Creates a `MediaFormat`
|
||||
///< entry for each of the found <fmt> values.
|
||||
bool parseRtpMapLine(
|
||||
const std::string &sdpLine); ///< Parses `a=rtpmap:` line which contains the some codec
|
||||
bool parseRtpMapLine(const std::string &sdpLine); ///< Parses `a=rtpmap:` line which contains the some codec
|
||||
///< specific info. When this line contains the samplerate and
|
||||
///< number of audio channels they will be extracted.
|
||||
bool parseRtspControlLine(const std::string &sdpLine); ///< Parses `a=control:`
|
||||
bool parseFrameRateLine(const std::string &sdpLine); ///< Parses `a=framerate:`
|
||||
bool parseFormatParametersLine(const std::string &sdpLine); ///< Parses `a=fmtp:<payload-type>`.
|
||||
bool parseRtcpFeedbackLine(
|
||||
const std::string &sdpLine); ///< Parses `a=rtcp-fb:<payload-type>`. See RFC4584
|
||||
bool parseFingerprintLine(
|
||||
const std::string
|
||||
&sdpLine); ///< Parses `a=fingerprint:<hash-func> <value>`. See
|
||||
bool parseRtcpFeedbackLine(const std::string &sdpLine); ///< Parses `a=rtcp-fb:<payload-type>`. See RFC4584
|
||||
bool parseFingerprintLine(const std::string &sdpLine); ///< Parses `a=fingerprint:<hash-func> <value>`. See
|
||||
///< https://tools.ietf.org/html/rfc8122#section-5, used with WebRTC
|
||||
bool parseSSRCLine(const std::string &sdpLine); ///< Parses `a=ssrc:<ssrc>`.
|
||||
MediaFormat *getFormatForSdpLine(
|
||||
const std::string
|
||||
&sdpLine); ///< Returns the track to which this SDP line applies. This means that the
|
||||
MediaFormat *getFormatForSdpLine(const std::string &sdpLine); ///< Returns the track to which this SDP line applies. This means that the
|
||||
///< SDP line should be formatteed like: `a=something:[payloadtype]`.
|
||||
MediaFormat *getFormatForPayloadType(
|
||||
uint64_t &payloadType); ///< Finds the `MediaFormat` in `formats`. Returns NULL when no
|
||||
MediaFormat *
|
||||
getFormatForPayloadType(uint64_t &payloadType); ///< Finds the `MediaFormat` in `formats`. Returns NULL when no
|
||||
///< format was found for the given payload type. .
|
||||
MediaFormat *getFormatForEncodingName(
|
||||
const std::string
|
||||
&encName); ///< Finds the `MediaFormats in `formats`. Returns NULL when no format was
|
||||
MediaFormat *getFormatForEncodingName(const std::string &encName); ///< Finds the `MediaFormats in `formats`. Returns NULL when no format was
|
||||
///< found for the given encoding name. E.g. `VP8`, `VP9`, `H264`
|
||||
std::vector<SDP::MediaFormat *> getFormatsForEncodingName(const std::string &encName);
|
||||
std::string getIcePwdForFormat(
|
||||
const MediaFormat
|
||||
&fmt); ///< The `a=ice-pwd` can be session global or media specific. This function will
|
||||
std::string getIcePwdForFormat(const MediaFormat &fmt); ///< The `a=ice-pwd` can be session global or media specific. This function will
|
||||
///< check if the `SDP::MediaFormat` has a ice-pwd that we should use.
|
||||
uint32_t
|
||||
getSSRC() const; ///< Returns the first SSRC `a=ssrc:<value>` value found for the media.
|
||||
uint32_t getSSRC() const; ///< Returns the first SSRC `a=ssrc:<value>` value found for the media.
|
||||
operator bool() const;
|
||||
MediaFormat* getRetransMissionFormatForPayloadType(uint64_t pt); ///< When available, it resurns the RTX format that is directly associated with the media (not encapsulated with a RED header). RTX can be combined with FEC in which case it's supposed to be stored in RED packets. The `encName` should be something like H264,VP8; e.g. the format for which you want to get the RTX format.
|
||||
MediaFormat *getRetransMissionFormatForPayloadType(
|
||||
uint64_t pt); ///< When available, it resurns the RTX format that is directly associated with
|
||||
///< the media (not encapsulated with a RED header). RTX can be combined with
|
||||
///< FEC in which case it's supposed to be stored in RED packets. The `encName` should be something like H264,VP8; e.g. the format for which you want to get the RTX format.
|
||||
|
||||
public:
|
||||
std::string type; ///< The `media` field of the media line: `m=<media> <port> <proto> <fmt>`,
|
||||
|
@ -132,8 +119,7 @@ namespace SDP{
|
|||
std::string setupMethod; ///< From `a=setup:<passive, active, actpass>, used with WebRTC / STUN
|
||||
std::string fingerprintHash; ///< From `a=fingerprint:<hash> <value>`, e.g. sha-256, used with
|
||||
///< WebRTC / STUN
|
||||
std::string
|
||||
fingerprintValue; ///< From `a=fingerprint:<hash> <value>`, the actual fingerprint, used
|
||||
std::string fingerprintValue; ///< From `a=fingerprint:<hash> <value>`, the actual fingerprint, used
|
||||
///< with WebRTC / STUN, see https://tools.ietf.org/html/rfc8122#section-5
|
||||
std::string mediaID; ///< From `a=mid:<value>`. When generating an WebRTC answer this value must
|
||||
///< be the same as in the offer.
|
||||
|
@ -144,21 +130,17 @@ namespace SDP{
|
|||
bool supportsRTCPMux; ///< From `a=rtcp-mux`, indicates if it can mux RTP and RTCP on one
|
||||
///< transport channel.
|
||||
bool supportsRTCPReducedSize; ///< From `a=rtcp-rsize`, reduced size RTCP packets.
|
||||
std::string
|
||||
payloadTypes; ///< From `m=` line, all the payload types as string, separated by space.
|
||||
std::map<uint64_t, MediaFormat>
|
||||
formats; ///< Formats indexed by payload type. Payload type is the number in the <fmt>
|
||||
std::string payloadTypes; ///< From `m=` line, all the payload types as string, separated by space.
|
||||
std::map<uint64_t, MediaFormat> formats; ///< Formats indexed by payload type. Payload type is the number in the <fmt>
|
||||
///< field(s) from the `m=` line.
|
||||
};
|
||||
|
||||
class Session{
|
||||
public:
|
||||
bool parseSDP(const std::string &sdp);
|
||||
Media *getMediaForType(
|
||||
const std::string &type); ///< Get a `SDP::Media*` for the given type, e.g. `video` or
|
||||
Media *getMediaForType(const std::string &type); ///< Get a `SDP::Media*` for the given type, e.g. `video` or
|
||||
///< `audio`. Returns NULL when the type was not found.
|
||||
MediaFormat *getMediaFormatByEncodingName(const std::string &mediaType,
|
||||
const std::string &encodingName);
|
||||
MediaFormat *getMediaFormatByEncodingName(const std::string &mediaType, const std::string &encodingName);
|
||||
bool hasReceiveOnlyMedia(); ///< Returns true when one of the media sections has a `a=recvonly`
|
||||
///< attribute. This is used to determine if the other peer only
|
||||
///< wants to receive or also sent data. */
|
||||
|
@ -168,8 +150,7 @@ namespace SDP{
|
|||
///< stream specific infomration is stored in a `MediaFormat`
|
||||
std::string icePwd; ///< From `a=ice-pwd`, this property can be session-wide or media specific.
|
||||
///< Used with WebRTC and STUN when calculating the message-integrity.
|
||||
std::string
|
||||
iceUFrag; ///< From `a=ice-ufag`, this property can be session-wide or media specific. Used
|
||||
std::string iceUFrag; ///< From `a=ice-ufag`, this property can be session-wide or media specific. Used
|
||||
///< with WebRTC and STUN when calculating the message-integrity.
|
||||
};
|
||||
|
||||
|
@ -216,5 +197,4 @@ namespace SDP{
|
|||
uint8_t videoLossPrevention; ///< See the SDP_LOSS_PREVENTION_* values at the top of this header.
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}// namespace SDP
|
||||
|
|
|
@ -1,28 +1,27 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/sem.h>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include "auth.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
#include "procs.h"
|
||||
#include "shared_memory.h"
|
||||
#include "stream.h"
|
||||
#include "procs.h"
|
||||
#include "bitfields.h"
|
||||
#include "timing.h"
|
||||
#include "auth.h"
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <aclapi.h>
|
||||
#include <accctrl.h>
|
||||
#include <aclapi.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
/// Forces a disconnect to all users.
|
||||
static void killStatistics(char *data, size_t len, unsigned int id){
|
||||
(*(data - 1)) = 60 | ((*(data - 1)) & 0x80); // Send disconnect message;
|
||||
|
@ -32,12 +31,8 @@ namespace IPC {
|
|||
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
static std::map<std::string, sharedPage> preservedPages;
|
||||
void preservePage(std::string p) {
|
||||
preservedPages[p].init(p, 0, false, false);
|
||||
}
|
||||
void releasePage(std::string p) {
|
||||
preservedPages.erase(p);
|
||||
}
|
||||
void preservePage(std::string p){preservedPages[p].init(p, 0, false, false);}
|
||||
void releasePage(std::string p){preservedPages.erase(p);}
|
||||
#endif
|
||||
|
||||
///\brief Empty semaphore constructor, clears all values
|
||||
|
@ -66,10 +61,7 @@ namespace IPC {
|
|||
}
|
||||
|
||||
///\brief The deconstructor
|
||||
semaphore::~semaphore() {
|
||||
close();
|
||||
}
|
||||
|
||||
semaphore::~semaphore(){close();}
|
||||
|
||||
///\brief Returns whether we have a valid semaphore
|
||||
semaphore::operator bool() const{
|
||||
|
@ -106,9 +98,7 @@ namespace IPC {
|
|||
}
|
||||
SECURITY_ATTRIBUTES security = getSecurityAttributes();
|
||||
mySem = CreateMutex(&security, true, semaName.c_str());
|
||||
if (value){
|
||||
ReleaseMutex(mySem);
|
||||
}
|
||||
if (value){ReleaseMutex(mySem);}
|
||||
}else{
|
||||
mySem = OpenMutex(SYNCHRONIZE, false, semaName.c_str());
|
||||
}
|
||||
|
@ -142,9 +132,7 @@ namespace IPC {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
if (*this) {
|
||||
myName = (char *)name;
|
||||
}
|
||||
if (*this){myName = (char *)name;}
|
||||
}
|
||||
|
||||
///\brief Returns the current value of the semaphore
|
||||
|
@ -189,9 +177,7 @@ namespace IPC {
|
|||
WaitForSingleObject(mySem, INFINITE);
|
||||
#else
|
||||
int tmp;
|
||||
do {
|
||||
tmp = sem_wait(mySem);
|
||||
} while (tmp == -1 && errno == EINTR);
|
||||
do{tmp = sem_wait(mySem);}while (tmp == -1 && errno == EINTR);
|
||||
#endif
|
||||
lockTime = Util::getMicros();
|
||||
++isLocked;
|
||||
|
@ -209,9 +195,7 @@ namespace IPC {
|
|||
result = 0;
|
||||
}
|
||||
#else
|
||||
do {
|
||||
result = sem_trywait(mySem);
|
||||
} while (result == -1 && errno == EINTR);
|
||||
do{result = sem_trywait(mySem);}while (result == -1 && errno == EINTR);
|
||||
#endif
|
||||
isLocked += (result == 0 ? 1 : 0);
|
||||
if (isLocked == 1){lockTime = Util::getMicros();}
|
||||
|
@ -306,9 +290,7 @@ namespace IPC {
|
|||
static SECURITY_ATTRIBUTES result;
|
||||
static bool resultValid = false;
|
||||
static SECURITY_DESCRIPTOR securityDescriptor;
|
||||
if (resultValid) {
|
||||
return result;
|
||||
}
|
||||
if (resultValid){return result;}
|
||||
|
||||
InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
|
||||
if (!SetSecurityDescriptorDacl(&securityDescriptor, TRUE, NULL, FALSE)){
|
||||
|
@ -349,9 +331,7 @@ namespace IPC {
|
|||
}
|
||||
|
||||
///\brief Default destructor
|
||||
sharedPage::~sharedPage() {
|
||||
close();
|
||||
}
|
||||
sharedPage::~sharedPage(){close();}
|
||||
|
||||
#ifdef SHM_ENABLED
|
||||
|
||||
|
@ -394,18 +374,14 @@ namespace IPC {
|
|||
CloseHandle(handle);
|
||||
#else
|
||||
::close(handle);
|
||||
if (master && name != "") {
|
||||
shm_unlink(name.c_str());
|
||||
}
|
||||
if (master && name != ""){shm_unlink(name.c_str());}
|
||||
#endif
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
///\brief Returns whether the shared page is valid or not
|
||||
sharedPage::operator bool() const {
|
||||
return mapped != 0;
|
||||
}
|
||||
sharedPage::operator bool() const{return mapped != 0;}
|
||||
|
||||
///\brief Assignment operator
|
||||
void sharedPage::operator=(sharedPage &rhs){
|
||||
|
@ -414,7 +390,6 @@ namespace IPC {
|
|||
rhs.master = false; // Make sure the memory does not get unlinked
|
||||
}
|
||||
|
||||
|
||||
///\brief Initialize a page, de-initialize before if needed
|
||||
///\param name_ The name of the page to be created
|
||||
///\param len_ The size to make the page
|
||||
|
@ -427,7 +402,8 @@ namespace IPC {
|
|||
master = master_;
|
||||
mapped = 0;
|
||||
if (name.size()){
|
||||
INSANE_MSG("Opening page %s in %s mode %s auto-backoff", name.c_str(), master ? "master" : "client", autoBackoff ? "with" : "without");
|
||||
INSANE_MSG("Opening page %s in %s mode %s auto-backoff", name.c_str(),
|
||||
master ? "master" : "client", autoBackoff ? "with" : "without");
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
if (master){
|
||||
// Under cygwin, all pages are 4 bytes longer than claimed.
|
||||
|
@ -435,15 +411,14 @@ namespace IPC {
|
|||
}else{
|
||||
int i = 0;
|
||||
do{
|
||||
if (i != 0) {
|
||||
Util::wait(1000);
|
||||
}
|
||||
if (i != 0){Util::wait(1000);}
|
||||
handle = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, name.c_str());
|
||||
i++;
|
||||
}while (i < 10 && !handle && autoBackoff);
|
||||
}
|
||||
if (!handle){
|
||||
MEDIUM_MSG("%s for page %s failed with error code %u", (master ? "CreateFileMapping" : "OpenFileMapping"), name.c_str(), GetLastError());
|
||||
MEDIUM_MSG("%s for page %s failed with error code %u",
|
||||
(master ? "CreateFileMapping" : "OpenFileMapping"), name.c_str(), GetLastError());
|
||||
return;
|
||||
}
|
||||
mapped = (char *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||
|
@ -488,9 +463,7 @@ namespace IPC {
|
|||
}else{
|
||||
struct stat buffStats;
|
||||
int xRes = fstat(handle, &buffStats);
|
||||
if (xRes < 0) {
|
||||
return;
|
||||
}
|
||||
if (xRes < 0){return;}
|
||||
len = buffStats.st_size;
|
||||
if (!len){
|
||||
mapped = 0;
|
||||
|
@ -514,7 +487,8 @@ namespace IPC {
|
|||
///\param len_ The size to make the file
|
||||
///\param master_ Whether to create or merely open the file
|
||||
///\param autoBackoff When only opening the file, wait for it to appear or fail
|
||||
sharedFile::sharedFile(const std::string & name_, uint64_t len_, bool master_, bool autoBackoff) : handle(0), name(name_), len(len_), master(master_), mapped(NULL) {
|
||||
sharedFile::sharedFile(const std::string &name_, uint64_t len_, bool master_, bool autoBackoff)
|
||||
: handle(0), name(name_), len(len_), master(master_), mapped(NULL){
|
||||
handle = 0;
|
||||
name = name_;
|
||||
len = len_;
|
||||
|
@ -523,7 +497,6 @@ namespace IPC {
|
|||
init(name_, len_, master_, autoBackoff);
|
||||
}
|
||||
|
||||
|
||||
///\brief Creates a copy of a shared page
|
||||
///\param rhs The page to copy
|
||||
sharedFile::sharedFile(const sharedFile &rhs){
|
||||
|
@ -536,9 +509,7 @@ namespace IPC {
|
|||
}
|
||||
|
||||
///\brief Returns whether the shared file is valid or not
|
||||
sharedFile::operator bool() const {
|
||||
return mapped != 0;
|
||||
}
|
||||
sharedFile::operator bool() const{return mapped != 0;}
|
||||
|
||||
///\brief Assignment operator
|
||||
void sharedFile::operator=(sharedFile &rhs){
|
||||
|
@ -560,9 +531,7 @@ namespace IPC {
|
|||
unmap();
|
||||
if (handle > 0){
|
||||
::close(handle);
|
||||
if (master && name != "") {
|
||||
unlink(name.c_str());
|
||||
}
|
||||
if (master && name != ""){unlink(name.c_str());}
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
@ -587,11 +556,13 @@ namespace IPC {
|
|||
mapped = 0;
|
||||
if (name.size()){
|
||||
/// \todo Use ACCESSPERMS instead of 0600?
|
||||
handle = open(std::string(Util::getTmpFolder() + name).c_str(), (master ? O_CREAT | O_TRUNC | O_EXCL : 0) | O_RDWR, (mode_t)0600);
|
||||
handle = open(std::string(Util::getTmpFolder() + name).c_str(),
|
||||
(master ? O_CREAT | O_TRUNC | O_EXCL : 0) | O_RDWR, (mode_t)0600);
|
||||
if (handle == -1){
|
||||
if (master){
|
||||
HIGH_MSG("Overwriting old file for %s", name.c_str());
|
||||
handle = open(std::string(Util::getTmpFolder() + name).c_str(), O_CREAT | O_TRUNC | O_RDWR, (mode_t)0600);
|
||||
handle = open(std::string(Util::getTmpFolder() + name).c_str(),
|
||||
O_CREAT | O_TRUNC | O_RDWR, (mode_t)0600);
|
||||
}else{
|
||||
int i = 0;
|
||||
while (i < 10 && handle == -1 && autoBackoff){
|
||||
|
@ -613,9 +584,7 @@ namespace IPC {
|
|||
}else{
|
||||
struct stat buffStats;
|
||||
int xRes = fstat(handle, &buffStats);
|
||||
if (xRes < 0) {
|
||||
return;
|
||||
}
|
||||
if (xRes < 0){return;}
|
||||
len = buffStats.st_size;
|
||||
}
|
||||
mapped = (char *)mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, handle, 0);
|
||||
|
@ -627,18 +596,13 @@ namespace IPC {
|
|||
}
|
||||
|
||||
///\brief Default destructor
|
||||
sharedFile::~sharedFile() {
|
||||
close();
|
||||
}
|
||||
|
||||
sharedFile::~sharedFile(){close();}
|
||||
|
||||
///\brief StatExchange constructor, sets the datapointer to the given value
|
||||
statExchange::statExchange(char *_data) : data(_data){}
|
||||
|
||||
///\brief Sets timestamp of the current stats
|
||||
void statExchange::now(long long int time) {
|
||||
Bit::htobll(data, time);
|
||||
}
|
||||
void statExchange::now(long long int time){Bit::htobll(data, time);}
|
||||
|
||||
///\brief Gets timestamp of the current stats
|
||||
long long int statExchange::now(){
|
||||
|
@ -647,81 +611,53 @@ namespace IPC {
|
|||
}
|
||||
|
||||
///\brief Sets time currently connected
|
||||
void statExchange::time(long time) {
|
||||
Bit::htobl(data + 8, time);
|
||||
}
|
||||
void statExchange::time(long time){Bit::htobl(data + 8, time);}
|
||||
|
||||
/// Calculates session ID from CRC, stream name, connector and host.
|
||||
std::string statExchange::getSessId(){
|
||||
return Secure::md5(data+32, 140);
|
||||
}
|
||||
std::string statExchange::getSessId(){return Secure::md5(data + 32, 140);}
|
||||
|
||||
///\brief Gets time currently connected
|
||||
long statExchange::time() {
|
||||
return Bit::btohl(data + 8);
|
||||
}
|
||||
long statExchange::time(){return Bit::btohl(data + 8);}
|
||||
|
||||
///\brief Sets the last viewing second of this user
|
||||
void statExchange::lastSecond(long time) {
|
||||
Bit::htobl(data + 12, time);
|
||||
}
|
||||
void statExchange::lastSecond(long time){Bit::htobl(data + 12, time);}
|
||||
|
||||
///\brief Gets the last viewing second of this user
|
||||
long statExchange::lastSecond() {
|
||||
return Bit::btohl(data + 12);
|
||||
}
|
||||
long statExchange::lastSecond(){return Bit::btohl(data + 12);}
|
||||
|
||||
///\brief Sets the amount of bytes received
|
||||
void statExchange::down(long long int bytes) {
|
||||
Bit::htobll(data + 16, bytes);
|
||||
}
|
||||
void statExchange::down(long long int bytes){Bit::htobll(data + 16, bytes);}
|
||||
|
||||
///\brief Gets the amount of bytes received
|
||||
long long int statExchange::down() {
|
||||
return Bit::btohll(data + 16);
|
||||
}
|
||||
long long int statExchange::down(){return Bit::btohll(data + 16);}
|
||||
|
||||
///\brief Sets the amount of bytes sent
|
||||
void statExchange::up(long long int bytes) {
|
||||
Bit::htobll(data + 24, bytes);
|
||||
}
|
||||
void statExchange::up(long long int bytes){Bit::htobll(data + 24, bytes);}
|
||||
|
||||
///\brief Gets the amount of bytes sent
|
||||
long long int statExchange::up() {
|
||||
return Bit::btohll(data + 24);
|
||||
}
|
||||
long long int statExchange::up(){return Bit::btohll(data + 24);}
|
||||
|
||||
///\brief Sets the host of this connection
|
||||
void statExchange::host(std::string name){
|
||||
if (name.size() < 16) {
|
||||
memset(data + 32, 0, 16);
|
||||
}
|
||||
if (name.size() < 16){memset(data + 32, 0, 16);}
|
||||
memcpy(data + 32, name.c_str(), std::min((int)name.size(), 16));
|
||||
}
|
||||
|
||||
///\brief Gets the host of this connection
|
||||
std::string statExchange::host() {
|
||||
return std::string(data + 32, 16);
|
||||
}
|
||||
std::string statExchange::host(){return std::string(data + 32, 16);}
|
||||
|
||||
///\brief Sets the name of the stream this user is viewing
|
||||
void statExchange::streamName(std::string name){
|
||||
size_t splitChar = name.find_first_of("+ ");
|
||||
if (splitChar != std::string::npos) {
|
||||
name[splitChar] = '+';
|
||||
}
|
||||
if (splitChar != std::string::npos){name[splitChar] = '+';}
|
||||
snprintf(data + 48, 100, "%s", name.c_str());
|
||||
}
|
||||
|
||||
///\brief Gets the name of the stream this user is viewing
|
||||
std::string statExchange::streamName() {
|
||||
return std::string(data + 48, strnlen(data + 48, 100));
|
||||
}
|
||||
std::string statExchange::streamName(){return std::string(data + 48, strnlen(data + 48, 100));}
|
||||
|
||||
///\brief Sets the name of the connector through which this user is viewing
|
||||
void statExchange::connector(std::string name) {
|
||||
snprintf(data+148, 20, "%s", name.c_str());
|
||||
}
|
||||
void statExchange::connector(std::string name){snprintf(data + 148, 20, "%s", name.c_str());}
|
||||
|
||||
///\brief Gets the name of the connector through which this user is viewing
|
||||
std::string statExchange::connector(){
|
||||
|
@ -729,39 +665,25 @@ namespace IPC {
|
|||
}
|
||||
|
||||
///\brief Sets checksum field
|
||||
void statExchange::crc(unsigned int sum) {
|
||||
Bit::htobl(data + 168, sum);
|
||||
}
|
||||
void statExchange::crc(unsigned int sum){Bit::htobl(data + 168, sum);}
|
||||
|
||||
///\brief Gets checksum field
|
||||
unsigned int statExchange::crc() {
|
||||
return Bit::btohl(data + 168);
|
||||
}
|
||||
unsigned int statExchange::crc(){return Bit::btohl(data + 168);}
|
||||
|
||||
///\brief Sets checksum field
|
||||
void statExchange::setSync(char s) {
|
||||
data[172] = s;
|
||||
}
|
||||
void statExchange::setSync(char s){data[172] = s;}
|
||||
|
||||
///\brief Gets checksum field
|
||||
char statExchange::getSync() {
|
||||
return data[172];
|
||||
}
|
||||
char statExchange::getSync(){return data[172];}
|
||||
|
||||
///\brief Gets PID field
|
||||
uint32_t statExchange::getPID() {
|
||||
return *(uint32_t*)(data+173);
|
||||
}
|
||||
uint32_t statExchange::getPID(){return *(uint32_t *)(data + 173);}
|
||||
|
||||
///\brief Creates a semaphore guard, locks the semaphore on call
|
||||
semGuard::semGuard(semaphore * thisSemaphore) : mySemaphore(thisSemaphore) {
|
||||
mySemaphore->wait();
|
||||
}
|
||||
semGuard::semGuard(semaphore *thisSemaphore) : mySemaphore(thisSemaphore){mySemaphore->wait();}
|
||||
|
||||
///\brief Destructs a semaphore guard, unlocks the semaphore on call
|
||||
semGuard::~semGuard() {
|
||||
mySemaphore->post();
|
||||
}
|
||||
semGuard::~semGuard(){mySemaphore->post();}
|
||||
|
||||
///\brief Default constructor, erases all the values
|
||||
sharedServer::sharedServer(){
|
||||
|
@ -784,12 +706,8 @@ namespace IPC {
|
|||
///\param len The lenght of the payload
|
||||
///\param withCounter Whether the content should have a counter
|
||||
void sharedServer::init(std::string name, int len, bool withCounter){
|
||||
if (mySemaphore) {
|
||||
mySemaphore.close();
|
||||
}
|
||||
if (baseName != "") {
|
||||
mySemaphore.unlink();
|
||||
}
|
||||
if (mySemaphore){mySemaphore.close();}
|
||||
if (baseName != ""){mySemaphore.unlink();}
|
||||
myPages.clear();
|
||||
baseName = "/" + name;
|
||||
payLen = len;
|
||||
|
@ -806,17 +724,13 @@ namespace IPC {
|
|||
}
|
||||
|
||||
///\brief The deconstructor
|
||||
sharedServer::~sharedServer() {
|
||||
mySemaphore.unlink();
|
||||
}
|
||||
sharedServer::~sharedServer(){mySemaphore.unlink();}
|
||||
|
||||
///\brief Determines whether a sharedServer is valid
|
||||
sharedServer::operator bool() const {
|
||||
return myPages.size();
|
||||
}
|
||||
sharedServer::operator bool() const{return myPages.size();}
|
||||
|
||||
///Sets all currently loaded memory pages to non-master, so they are not cleaned up on destruction, but left behind.
|
||||
///Useful for doing rolling updates and such.
|
||||
/// Sets all currently loaded memory pages to non-master, so they are not cleaned up on
|
||||
/// destruction, but left behind. Useful for doing rolling updates and such.
|
||||
void sharedServer::abandon(){
|
||||
if (!myPages.size()){return;}
|
||||
VERYHIGH_MSG("Abandoning %llu memory pages, leaving them behind on purpose", myPages.size());
|
||||
|
@ -827,9 +741,11 @@ namespace IPC {
|
|||
|
||||
///\brief Creates the next page with the correct size
|
||||
void sharedServer::newPage(){
|
||||
sharedPage tmp(std::string(baseName.substr(1) + (char)(myPages.size() + (int)'A')), std::min(((8192 * 2) << myPages.size()), (32 * 1024 * 1024)), false, false);
|
||||
sharedPage tmp(std::string(baseName.substr(1) + (char)(myPages.size() + (int)'A')),
|
||||
std::min(((8192 * 2) << myPages.size()), (32 * 1024 * 1024)), false, false);
|
||||
if (!tmp.mapped){
|
||||
tmp.init(std::string(baseName.substr(1) + (char)(myPages.size() + (int)'A')), std::min(((8192 * 2) << myPages.size()), (32 * 1024 * 1024)), true);
|
||||
tmp.init(std::string(baseName.substr(1) + (char)(myPages.size() + (int)'A')),
|
||||
std::min(((8192 * 2) << myPages.size()), (32 * 1024 * 1024)), true);
|
||||
tmp.master = false;
|
||||
}
|
||||
myPages.push_back(tmp);
|
||||
|
@ -852,9 +768,7 @@ namespace IPC {
|
|||
unsigned int i = 0;
|
||||
for (std::deque<sharedPage>::iterator it = myPages.begin(); it != myPages.end(); it++){
|
||||
// return if we reached the end
|
||||
if (!it->mapped || !it->len) {
|
||||
return false;
|
||||
}
|
||||
if (!it->mapped || !it->len){return false;}
|
||||
// not on this page? skip to next.
|
||||
if (it->len < (id - i) * payLen){
|
||||
i += it->len / payLen;
|
||||
|
@ -866,9 +780,7 @@ namespace IPC {
|
|||
}else{
|
||||
// no counter - check the entire size for being all zeroes.
|
||||
for (unsigned int j = 0; j < payLen; ++j){
|
||||
if (it->mapped[(id - i)*payLen + j]) {
|
||||
return true;
|
||||
}
|
||||
if (it->mapped[(id - i) * payLen + j]){return true;}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -879,9 +791,7 @@ namespace IPC {
|
|||
|
||||
/// Disconnect all connected users, waits at most 2.5 seconds until completed
|
||||
void sharedServer::finishEach(){
|
||||
if (!hasCounter){
|
||||
return;
|
||||
}
|
||||
if (!hasCounter){return;}
|
||||
unsigned int c = 0; // to prevent eternal loops
|
||||
do{
|
||||
parseEach(killStatistics);
|
||||
|
@ -928,7 +838,8 @@ namespace IPC {
|
|||
}
|
||||
|
||||
///\brief Parse each of the possible payload pieces, and runs a callback on it if in use.
|
||||
void sharedServer::parseEach(void (*activeCallback)(char * data, size_t len, unsigned int id), void (*disconCallback)(char * data, size_t len, unsigned int id)) {
|
||||
void sharedServer::parseEach(void (*activeCallback)(char *data, size_t len, unsigned int id),
|
||||
void (*disconCallback)(char *data, size_t len, unsigned int id)){
|
||||
char *empty = 0;
|
||||
if (!hasCounter){
|
||||
empty = (char *)malloc(payLen * sizeof(char));
|
||||
|
@ -952,9 +863,7 @@ namespace IPC {
|
|||
char *counter = it->mapped + offset;
|
||||
// increase the count if needed
|
||||
++userCount;
|
||||
if (*counter & 0x80){
|
||||
connectedUsers++;
|
||||
}
|
||||
if (*counter & 0x80){connectedUsers++;}
|
||||
char countNum = (*counter) & 0x7F;
|
||||
lastFilled = id;
|
||||
if (id >= amount){
|
||||
|
@ -962,26 +871,21 @@ namespace IPC {
|
|||
VERYHIGH_MSG("Shared memory %s is now at count %u", baseName.c_str(), amount);
|
||||
}
|
||||
uint32_t tmpPID = *((uint32_t *)(it->mapped + 1 + offset + payLen - 4));
|
||||
if (tmpPID > 1 && it->master && !Util::Procs::isRunning(tmpPID) && !(countNum == 126 || countNum == 127)){
|
||||
if (tmpPID > 1 && it->master && !Util::Procs::isRunning(tmpPID) &&
|
||||
!(countNum == 126 || countNum == 127)){
|
||||
WARN_MSG("process disappeared, timing out. (pid %lu)", tmpPID);
|
||||
*counter = 125 | (0x80 & (*counter)); // if process is already dead, instant timeout.
|
||||
}
|
||||
activeCallback(it->mapped + offset + 1, payLen, id);
|
||||
switch (countNum){
|
||||
case 127:
|
||||
HIGH_MSG("Client %u requested disconnect", id);
|
||||
break;
|
||||
case 126:
|
||||
HIGH_MSG("Client %u timed out", id);
|
||||
break;
|
||||
case 127: HIGH_MSG("Client %u requested disconnect", id); break;
|
||||
case 126: HIGH_MSG("Client %u timed out", id); break;
|
||||
default:
|
||||
#ifndef NOCRASHCHECK
|
||||
if (tmpPID > 1 && it->master){
|
||||
if (countNum > 10 && countNum < 60){
|
||||
if (countNum < 30){
|
||||
if (countNum > 15) {
|
||||
WARN_MSG("Process %d is unresponsive", tmpPID);
|
||||
}
|
||||
if (countNum > 15){WARN_MSG("Process %d is unresponsive", tmpPID);}
|
||||
Util::Procs::Stop(tmpPID); // soft kill
|
||||
}else{
|
||||
ERROR_MSG("Killing unresponsive process %d", tmpPID);
|
||||
|
@ -990,9 +894,7 @@ namespace IPC {
|
|||
}
|
||||
if (countNum > 70){
|
||||
if (countNum < 90){
|
||||
if (countNum > 75) {
|
||||
WARN_MSG("Stopping process %d is unresponsive", tmpPID);
|
||||
}
|
||||
if (countNum > 75){WARN_MSG("Stopping process %d is unresponsive", tmpPID);}
|
||||
Util::Procs::Stop(tmpPID); // soft kill
|
||||
}else{
|
||||
ERROR_MSG("Killing unresponsive stopping process %d", tmpPID);
|
||||
|
@ -1005,9 +907,7 @@ namespace IPC {
|
|||
}
|
||||
if (countNum == 127 || countNum == 126){
|
||||
semGuard tmpGuard(&mySemaphore);
|
||||
if (disconCallback){
|
||||
disconCallback(counter + 1, payLen, id);
|
||||
}
|
||||
if (disconCallback){disconCallback(counter + 1, payLen, id);}
|
||||
memset(counter + 1, 0, payLen);
|
||||
*counter = 0;
|
||||
}else{
|
||||
|
@ -1047,9 +947,7 @@ namespace IPC {
|
|||
}
|
||||
if (id >= amount + 100){
|
||||
// stop, we're guaranteed no more pages are full at this point
|
||||
if (empty) {
|
||||
free(empty);
|
||||
}
|
||||
if (empty){free(empty);}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1067,9 +965,7 @@ namespace IPC {
|
|||
bool unsetMaster = !(it->master);
|
||||
semGuard tmpGuard(&mySemaphore);
|
||||
newPage();
|
||||
if (unsetMaster){
|
||||
(myPages.end()-1)->master = false;
|
||||
}
|
||||
if (unsetMaster){(myPages.end() - 1)->master = false;}
|
||||
it = myPages.end() - 2;
|
||||
}
|
||||
}
|
||||
|
@ -1080,9 +976,7 @@ namespace IPC {
|
|||
deletePage();
|
||||
}
|
||||
|
||||
if (empty) {
|
||||
free(empty);
|
||||
}
|
||||
if (empty){free(empty);}
|
||||
}
|
||||
|
||||
///\brief Creates an empty shared client
|
||||
|
@ -1093,7 +987,6 @@ namespace IPC {
|
|||
countAsViewer = true;
|
||||
}
|
||||
|
||||
|
||||
///\brief Copy constructor for sharedClients
|
||||
///\param rhs The client ro copy
|
||||
sharedClient::sharedClient(const sharedClient &rhs){
|
||||
|
@ -1139,7 +1032,8 @@ namespace IPC {
|
|||
///\param name The basename of the server to connect to
|
||||
///\param len The size of the payload to allocate
|
||||
///\param withCounter Whether or not this payload has a counter
|
||||
sharedClient::sharedClient(std::string name, int len, bool withCounter) : baseName("/" + name), payLen(len), offsetOnPage(-1), hasCounter(withCounter) {
|
||||
sharedClient::sharedClient(std::string name, int len, bool withCounter)
|
||||
: baseName("/" + name), payLen(len), offsetOnPage(-1), hasCounter(withCounter){
|
||||
countAsViewer = true;
|
||||
#ifdef __APPLE__
|
||||
// note: O_CREAT is only needed for mac, probably
|
||||
|
@ -1165,14 +1059,14 @@ namespace IPC {
|
|||
while (offsetOnPage == -1 && (++attempts) < 20){
|
||||
for (char i = 'A'; i <= 'Z'; i++){
|
||||
myPage.init(baseName.substr(1) + i, (4096 << (i - 'A')), false, false);
|
||||
if (!myPage.mapped) {
|
||||
break;
|
||||
}
|
||||
if (!myPage.mapped){break;}
|
||||
int offset = 0;
|
||||
while (offset + payLen + (hasCounter ? 1 : 0) <= myPage.len){
|
||||
if ((hasCounter && myPage.mapped[offset] == 0) || (!hasCounter && !memcmp(myPage.mapped + offset, empty, payLen))) {
|
||||
if ((hasCounter && myPage.mapped[offset] == 0) ||
|
||||
(!hasCounter && !memcmp(myPage.mapped + offset, empty, payLen))){
|
||||
semGuard tmpGuard(&mySemaphore);
|
||||
if ((hasCounter && myPage.mapped[offset] == 0) || (!hasCounter && !memcmp(myPage.mapped + offset, empty, payLen))) {
|
||||
if ((hasCounter && myPage.mapped[offset] == 0) ||
|
||||
(!hasCounter && !memcmp(myPage.mapped + offset, empty, payLen))){
|
||||
offsetOnPage = offset;
|
||||
if (hasCounter){
|
||||
myPage.mapped[offset] = 1;
|
||||
|
@ -1184,41 +1078,29 @@ namespace IPC {
|
|||
}
|
||||
offset += payLen + (hasCounter ? 1 : 0);
|
||||
}
|
||||
if (offsetOnPage != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (offsetOnPage == -1) {
|
||||
Util::wait(500);
|
||||
if (offsetOnPage != -1){break;}
|
||||
}
|
||||
if (offsetOnPage == -1){Util::wait(500);}
|
||||
}
|
||||
if (offsetOnPage == -1){
|
||||
FAIL_MSG("Could not register on page for %s", baseName.c_str());
|
||||
myPage.close();
|
||||
}
|
||||
if (empty) {
|
||||
free(empty);
|
||||
}
|
||||
if (empty){free(empty);}
|
||||
}
|
||||
|
||||
///\brief The deconstructor
|
||||
sharedClient::~sharedClient() {
|
||||
mySemaphore.close();
|
||||
}
|
||||
sharedClient::~sharedClient(){mySemaphore.close();}
|
||||
|
||||
///\brief Writes data to the shared data
|
||||
void sharedClient::write(char *data, int len){
|
||||
if (hasCounter) {
|
||||
keepAlive();
|
||||
}
|
||||
if (hasCounter){keepAlive();}
|
||||
memcpy(myPage.mapped + offsetOnPage + (hasCounter ? 1 : 0), data, std::min(len, payLen));
|
||||
}
|
||||
|
||||
///\brief Indicate that the process is done using this piece of memory, set the counter to finished
|
||||
void sharedClient::finish(){
|
||||
if (!myPage.mapped) {
|
||||
return;
|
||||
}
|
||||
if (!myPage.mapped){return;}
|
||||
if (!hasCounter){
|
||||
DEBUG_MSG(DLVL_WARN, "Trying to time-out an element without counters");
|
||||
myPage.close();
|
||||
|
@ -1236,44 +1118,30 @@ namespace IPC {
|
|||
DEBUG_MSG(DLVL_WARN, "Trying to keep-alive an element without counters");
|
||||
return;
|
||||
}
|
||||
if (isAlive()){
|
||||
myPage.mapped[offsetOnPage] = (countAsViewer ? 0x81 : 0x01);
|
||||
}
|
||||
if (isAlive()){myPage.mapped[offsetOnPage] = (countAsViewer ? 0x81 : 0x01);}
|
||||
}
|
||||
|
||||
bool sharedClient::isAlive(){
|
||||
if (!hasCounter) {
|
||||
return (myPage.mapped != 0);
|
||||
}
|
||||
if (myPage.mapped && offsetOnPage >= 0){
|
||||
return (myPage.mapped[offsetOnPage] & 0x7F) < 60;
|
||||
}
|
||||
if (!hasCounter){return (myPage.mapped != 0);}
|
||||
if (myPage.mapped && offsetOnPage >= 0){return (myPage.mapped[offsetOnPage] & 0x7F) < 60;}
|
||||
return false;
|
||||
}
|
||||
|
||||
///\brief Get a pointer to the data of this client
|
||||
char *sharedClient::getData(){
|
||||
if (!myPage.mapped) {
|
||||
return 0;
|
||||
}
|
||||
if (!myPage.mapped){return 0;}
|
||||
return (myPage.mapped + offsetOnPage + (hasCounter ? 1 : 0));
|
||||
}
|
||||
|
||||
int sharedClient::getCounter(){
|
||||
if (!hasCounter){
|
||||
return -1;
|
||||
}
|
||||
if (!myPage.mapped) {
|
||||
return 0;
|
||||
}
|
||||
if (!hasCounter){return -1;}
|
||||
if (!myPage.mapped){return 0;}
|
||||
return *(myPage.mapped + offsetOnPage);
|
||||
}
|
||||
|
||||
userConnection::userConnection(char *_data){
|
||||
data = _data;
|
||||
if (!data){
|
||||
WARN_MSG("userConnection created with null pointer!");
|
||||
}
|
||||
if (!data){WARN_MSG("userConnection created with null pointer!");}
|
||||
}
|
||||
|
||||
unsigned long userConnection::getTrackId(size_t offset) const{
|
||||
|
@ -1290,7 +1158,6 @@ namespace IPC {
|
|||
return;
|
||||
}
|
||||
Bit::htobl(data + (offset * 6), trackId);
|
||||
|
||||
}
|
||||
|
||||
unsigned long userConnection::getKeynum(size_t offset) const{
|
||||
|
@ -1307,7 +1174,5 @@ namespace IPC {
|
|||
return;
|
||||
}
|
||||
Bit::htobs(data + (offset * 6) + 4, keynum);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}// namespace IPC
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "timing.h"
|
||||
#include "defines.h"
|
||||
#include "timing.h"
|
||||
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
#include <windows.h>
|
||||
|
@ -46,6 +46,7 @@ namespace IPC {
|
|||
unsigned int crc();
|
||||
uint32_t getPID();
|
||||
std::string getSessId();
|
||||
|
||||
private:
|
||||
///\brief The payload for the stat exchange
|
||||
/// - 8 byte - now (timestamp of last statistics)
|
||||
|
@ -78,6 +79,7 @@ namespace IPC {
|
|||
void close();
|
||||
void abandon();
|
||||
void unlink();
|
||||
|
||||
private:
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
///\todo Maybe sometime implement anything else than 777
|
||||
|
@ -96,6 +98,7 @@ namespace IPC {
|
|||
public:
|
||||
semGuard(semaphore *thisSemaphore);
|
||||
~semGuard();
|
||||
|
||||
private:
|
||||
///\brief The semaphore to guard.
|
||||
semaphore *mySemaphore;
|
||||
|
@ -110,9 +113,7 @@ namespace IPC {
|
|||
operator bool() const;
|
||||
void init(const std::string &name_, uint64_t len_, bool master_ = false, bool autoBackoff = true);
|
||||
void operator=(sharedFile &rhs);
|
||||
bool operator < (const sharedFile & rhs) const {
|
||||
return name < rhs.name;
|
||||
}
|
||||
bool operator<(const sharedFile &rhs) const{return name < rhs.name;}
|
||||
void close();
|
||||
void unmap();
|
||||
bool exists();
|
||||
|
@ -143,9 +144,7 @@ namespace IPC {
|
|||
operator bool() const;
|
||||
void init(const std::string &name_, uint64_t len_, bool master_ = false, bool autoBackoff = true);
|
||||
void operator=(sharedPage &rhs);
|
||||
bool operator < (const sharedPage & rhs) const {
|
||||
return name < rhs.name;
|
||||
}
|
||||
bool operator<(const sharedPage &rhs) const{return name < rhs.name;}
|
||||
void unmap();
|
||||
void close();
|
||||
bool exists();
|
||||
|
@ -191,7 +190,8 @@ namespace IPC {
|
|||
sharedServer(std::string name, int len, bool withCounter = false);
|
||||
void init(std::string name, int len, bool withCounter = false);
|
||||
~sharedServer();
|
||||
void parseEach(void (*activeCallback)(char * data, size_t len, unsigned int id), void (*disconCallback)(char * data, size_t len, unsigned int id) = 0);
|
||||
void parseEach(void (*activeCallback)(char *data, size_t len, unsigned int id),
|
||||
void (*disconCallback)(char *data, size_t len, unsigned int id) = 0);
|
||||
char *getIndex(unsigned int id);
|
||||
operator bool() const;
|
||||
///\brief The amount of connected clients
|
||||
|
@ -199,6 +199,7 @@ namespace IPC {
|
|||
unsigned int connectedUsers;
|
||||
void finishEach();
|
||||
void abandon();
|
||||
|
||||
private:
|
||||
bool isInUse(unsigned int id);
|
||||
void newPage();
|
||||
|
@ -238,6 +239,7 @@ namespace IPC {
|
|||
char *getData();
|
||||
int getCounter();
|
||||
bool countAsViewer;
|
||||
|
||||
private:
|
||||
///\brief The basename of the shared pages.
|
||||
std::string baseName;
|
||||
|
@ -260,7 +262,8 @@ namespace IPC {
|
|||
void setTrackId(size_t offset, unsigned long trackId) const;
|
||||
unsigned long getKeynum(size_t offset) const;
|
||||
void setKeynum(size_t offset, unsigned long keynum);
|
||||
|
||||
private:
|
||||
char *data;
|
||||
};
|
||||
}
|
||||
}// namespace IPC
|
||||
|
|
|
@ -275,9 +275,7 @@ std::string Socket::resolveHostToBestExternalAddrGuess(const std::string &host,
|
|||
bool Socket::getSocketName(int fd, std::string &host, uint32_t &port){
|
||||
struct sockaddr_in6 tmpaddr;
|
||||
socklen_t len = sizeof(tmpaddr);
|
||||
if (getsockname(fd, (sockaddr *)&tmpaddr, &len)){
|
||||
return false;
|
||||
}
|
||||
if (getsockname(fd, (sockaddr *)&tmpaddr, &len)){return false;}
|
||||
static char addrconv[INET6_ADDRSTRLEN];
|
||||
if (tmpaddr.sin6_family == AF_INET6){
|
||||
host = inet_ntop(AF_INET6, &(tmpaddr.sin6_addr), addrconv, INET6_ADDRSTRLEN);
|
||||
|
@ -1184,9 +1182,7 @@ void Socket::Connection::setHost(std::string host){
|
|||
hints.ai_next = NULL;
|
||||
int s = getaddrinfo(host.c_str(), 0, &hints, &result);
|
||||
if (s != 0){return;}
|
||||
if (result){
|
||||
memcpy(&remoteaddr, result->ai_addr, result->ai_addrlen);
|
||||
}
|
||||
if (result){memcpy(&remoteaddr, result->ai_addr, result->ai_addrlen);}
|
||||
freeaddrinfo(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ namespace Socket{
|
|||
bool iread(Buffer &buffer, int flags = 0); ///< Incremental write call that is compatible with Socket::Buffer.
|
||||
bool iwrite(std::string &buffer); ///< Write call that is compatible with std::string.
|
||||
void setBoundAddr();
|
||||
|
||||
protected:
|
||||
std::string lastErr; ///< Stores last error, if any.
|
||||
#ifdef SSL
|
||||
|
|
145
lib/srtp.cpp
145
lib/srtp.cpp
|
@ -1,6 +1,6 @@
|
|||
#include <algorithm>
|
||||
#include "defines.h"
|
||||
#include "srtp.h"
|
||||
#include <algorithm>
|
||||
|
||||
/* --------------------------------------- */
|
||||
|
||||
|
@ -59,11 +59,9 @@ int SRTPReader::init(const std::string& cipher, const std::string& key, const st
|
|||
/* select the right profile from exchanged cipher */
|
||||
if ("SRTP_AES128_CM_SHA1_80" == cipher){
|
||||
profile = srtp_profile_aes128_cm_sha1_80;
|
||||
}
|
||||
else if ("SRTP_AES128_CM_SHA1_32" == cipher) {
|
||||
}else if ("SRTP_AES128_CM_SHA1_32" == cipher){
|
||||
profile = srtp_profile_aes128_cm_sha1_32;
|
||||
}
|
||||
else {
|
||||
}else{
|
||||
ERROR_MSG("Unsupported SRTP cipher used: %s.", cipher.c_str());
|
||||
r = -2;
|
||||
goto error;
|
||||
|
@ -103,9 +101,7 @@ int SRTPReader::init(const std::string& cipher, const std::string& key, const st
|
|||
}
|
||||
|
||||
error:
|
||||
if (r < 0) {
|
||||
shutdown();
|
||||
}
|
||||
if (r < 0){shutdown();}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -116,7 +112,8 @@ int SRTPReader::shutdown() {
|
|||
|
||||
srtp_err_status_t status = srtp_dealloc(session);
|
||||
if (srtp_err_status_ok != status){
|
||||
ERROR_MSG("Failed to cleanly shutdown the SRTP session. Status: %s", srtp_status_to_string(status).c_str());
|
||||
ERROR_MSG("Failed to cleanly shutdown the SRTP session. Status: %s",
|
||||
srtp_status_to_string(status).c_str());
|
||||
r -= 5;
|
||||
}
|
||||
|
||||
|
@ -245,11 +242,9 @@ int SRTPWriter::init(const std::string& cipher, const std::string& key, const st
|
|||
/* select the exchanged cipher */
|
||||
if ("SRTP_AES128_CM_SHA1_80" == cipher){
|
||||
profile = srtp_profile_aes128_cm_sha1_80;
|
||||
}
|
||||
else if ("SRTP_AES128_CM_SHA1_32" == cipher) {
|
||||
}else if ("SRTP_AES128_CM_SHA1_32" == cipher){
|
||||
profile = srtp_profile_aes128_cm_sha1_32;
|
||||
}
|
||||
else {
|
||||
}else{
|
||||
ERROR_MSG("Unsupported SRTP cipher used: %s.", cipher.c_str());
|
||||
r = -2;
|
||||
goto error;
|
||||
|
@ -289,9 +284,7 @@ int SRTPWriter::init(const std::string& cipher, const std::string& key, const st
|
|||
}
|
||||
|
||||
error:
|
||||
if (r < 0) {
|
||||
shutdown();
|
||||
}
|
||||
if (r < 0){shutdown();}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -302,7 +295,8 @@ int SRTPWriter::shutdown() {
|
|||
|
||||
srtp_err_status_t status = srtp_dealloc(session);
|
||||
if (srtp_err_status_ok != status){
|
||||
ERROR_MSG("Failed to cleanly shutdown the SRTP session. Status: %s", srtp_status_to_string(status).c_str());
|
||||
ERROR_MSG("Failed to cleanly shutdown the SRTP session. Status: %s",
|
||||
srtp_status_to_string(status).c_str());
|
||||
r -= 5;
|
||||
}
|
||||
|
||||
|
@ -381,41 +375,98 @@ int SRTPWriter::protectRtcp(uint8_t* data, int* nbytes) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------- */
|
||||
|
||||
static std::string srtp_status_to_string(uint32_t status){
|
||||
|
||||
switch (status){
|
||||
case srtp_err_status_ok: { return "srtp_err_status_ok"; }
|
||||
case srtp_err_status_fail: { return "srtp_err_status_fail"; }
|
||||
case srtp_err_status_bad_param: { return "srtp_err_status_bad_param"; }
|
||||
case srtp_err_status_alloc_fail: { return "srtp_err_status_alloc_fail"; }
|
||||
case srtp_err_status_dealloc_fail: { return "srtp_err_status_dealloc_fail"; }
|
||||
case srtp_err_status_init_fail: { return "srtp_err_status_init_fail"; }
|
||||
case srtp_err_status_terminus: { return "srtp_err_status_terminus"; }
|
||||
case srtp_err_status_auth_fail: { return "srtp_err_status_auth_fail"; }
|
||||
case srtp_err_status_cipher_fail: { return "srtp_err_status_cipher_fail"; }
|
||||
case srtp_err_status_replay_fail: { return "srtp_err_status_replay_fail"; }
|
||||
case srtp_err_status_replay_old: { return "srtp_err_status_replay_old"; }
|
||||
case srtp_err_status_algo_fail: { return "srtp_err_status_algo_fail"; }
|
||||
case srtp_err_status_no_such_op: { return "srtp_err_status_no_such_op"; }
|
||||
case srtp_err_status_no_ctx: { return "srtp_err_status_no_ctx"; }
|
||||
case srtp_err_status_cant_check: { return "srtp_err_status_cant_check"; }
|
||||
case srtp_err_status_key_expired: { return "srtp_err_status_key_expired"; }
|
||||
case srtp_err_status_socket_err: { return "srtp_err_status_socket_err"; }
|
||||
case srtp_err_status_signal_err: { return "srtp_err_status_signal_err"; }
|
||||
case srtp_err_status_nonce_bad: { return "srtp_err_status_nonce_bad"; }
|
||||
case srtp_err_status_read_fail: { return "srtp_err_status_read_fail"; }
|
||||
case srtp_err_status_write_fail: { return "srtp_err_status_write_fail"; }
|
||||
case srtp_err_status_parse_err: { return "srtp_err_status_parse_err"; }
|
||||
case srtp_err_status_encode_err: { return "srtp_err_status_encode_err"; }
|
||||
case srtp_err_status_semaphore_err: { return "srtp_err_status_semaphore_err"; }
|
||||
case srtp_err_status_pfkey_err: { return "srtp_err_status_pfkey_err"; }
|
||||
case srtp_err_status_bad_mki: { return "srtp_err_status_bad_mki"; }
|
||||
case srtp_err_status_pkt_idx_old: { return "srtp_err_status_pkt_idx_old"; }
|
||||
case srtp_err_status_pkt_idx_adv: { return "srtp_err_status_pkt_idx_adv"; }
|
||||
default: { return "UNKNOWN"; }
|
||||
case srtp_err_status_ok:{
|
||||
return "srtp_err_status_ok";
|
||||
}
|
||||
case srtp_err_status_fail:{
|
||||
return "srtp_err_status_fail";
|
||||
}
|
||||
case srtp_err_status_bad_param:{
|
||||
return "srtp_err_status_bad_param";
|
||||
}
|
||||
case srtp_err_status_alloc_fail:{
|
||||
return "srtp_err_status_alloc_fail";
|
||||
}
|
||||
case srtp_err_status_dealloc_fail:{
|
||||
return "srtp_err_status_dealloc_fail";
|
||||
}
|
||||
case srtp_err_status_init_fail:{
|
||||
return "srtp_err_status_init_fail";
|
||||
}
|
||||
case srtp_err_status_terminus:{
|
||||
return "srtp_err_status_terminus";
|
||||
}
|
||||
case srtp_err_status_auth_fail:{
|
||||
return "srtp_err_status_auth_fail";
|
||||
}
|
||||
case srtp_err_status_cipher_fail:{
|
||||
return "srtp_err_status_cipher_fail";
|
||||
}
|
||||
case srtp_err_status_replay_fail:{
|
||||
return "srtp_err_status_replay_fail";
|
||||
}
|
||||
case srtp_err_status_replay_old:{
|
||||
return "srtp_err_status_replay_old";
|
||||
}
|
||||
case srtp_err_status_algo_fail:{
|
||||
return "srtp_err_status_algo_fail";
|
||||
}
|
||||
case srtp_err_status_no_such_op:{
|
||||
return "srtp_err_status_no_such_op";
|
||||
}
|
||||
case srtp_err_status_no_ctx:{
|
||||
return "srtp_err_status_no_ctx";
|
||||
}
|
||||
case srtp_err_status_cant_check:{
|
||||
return "srtp_err_status_cant_check";
|
||||
}
|
||||
case srtp_err_status_key_expired:{
|
||||
return "srtp_err_status_key_expired";
|
||||
}
|
||||
case srtp_err_status_socket_err:{
|
||||
return "srtp_err_status_socket_err";
|
||||
}
|
||||
case srtp_err_status_signal_err:{
|
||||
return "srtp_err_status_signal_err";
|
||||
}
|
||||
case srtp_err_status_nonce_bad:{
|
||||
return "srtp_err_status_nonce_bad";
|
||||
}
|
||||
case srtp_err_status_read_fail:{
|
||||
return "srtp_err_status_read_fail";
|
||||
}
|
||||
case srtp_err_status_write_fail:{
|
||||
return "srtp_err_status_write_fail";
|
||||
}
|
||||
case srtp_err_status_parse_err:{
|
||||
return "srtp_err_status_parse_err";
|
||||
}
|
||||
case srtp_err_status_encode_err:{
|
||||
return "srtp_err_status_encode_err";
|
||||
}
|
||||
case srtp_err_status_semaphore_err:{
|
||||
return "srtp_err_status_semaphore_err";
|
||||
}
|
||||
case srtp_err_status_pfkey_err:{
|
||||
return "srtp_err_status_pfkey_err";
|
||||
}
|
||||
case srtp_err_status_bad_mki:{
|
||||
return "srtp_err_status_bad_mki";
|
||||
}
|
||||
case srtp_err_status_pkt_idx_old:{
|
||||
return "srtp_err_status_pkt_idx_old";
|
||||
}
|
||||
case srtp_err_status_pkt_idx_adv:{
|
||||
return "srtp_err_status_pkt_idx_adv";
|
||||
}
|
||||
default:{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <srtp2/srtp.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <srtp2/srtp.h>
|
||||
|
||||
#define SRTP_PARSER_MASTER_KEY_LEN 16
|
||||
#define SRTP_PARSER_MASTER_SALT_LEN 14
|
||||
|
|
134
lib/stream.cpp
134
lib/stream.cpp
|
@ -1,19 +1,19 @@
|
|||
/// \file stream.cpp
|
||||
/// Utilities for handling streams.
|
||||
|
||||
#include "stream.h"
|
||||
#include "config.h"
|
||||
#include "defines.h"
|
||||
#include "dtsc.h"
|
||||
#include "h265.h"
|
||||
#include "http_parser.h"
|
||||
#include "json.h"
|
||||
#include "langcodes.h"
|
||||
#include "mp4_generic.h"
|
||||
#include "procs.h"
|
||||
#include "shared_memory.h"
|
||||
#include "socket.h"
|
||||
#include "stream.h"
|
||||
#include "triggers.h" //LTS
|
||||
#include "h265.h"
|
||||
#include "mp4_generic.h"
|
||||
#include "langcodes.h"
|
||||
#include "http_parser.h"
|
||||
#include <semaphore.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -98,7 +98,11 @@ std::string Util::codecString(const std::string & codec, const std::string & ini
|
|||
if (mInfo.general_profile_compatflags & 0x40000000ul){mappedFlags += 0x00000002ul;}
|
||||
if (mInfo.general_profile_compatflags & 0x80000000ul){mappedFlags += 0x00000001ul;}
|
||||
r << std::hex << (unsigned long)mappedFlags << std::dec << '.';
|
||||
if (mInfo.general_tier_flag){r << 'H';}else{r << 'L';}
|
||||
if (mInfo.general_tier_flag){
|
||||
r << 'H';
|
||||
}else{
|
||||
r << 'L';
|
||||
}
|
||||
r << (unsigned long)mInfo.general_level_idc;
|
||||
if (mInfo.constraint_flags[0]){
|
||||
r << '.' << std::hex << (unsigned long)mInfo.constraint_flags[0] << std::dec;
|
||||
|
@ -112,8 +116,7 @@ std::string Util::codecString(const std::string & codec, const std::string & ini
|
|||
}
|
||||
|
||||
/// Replaces all stream-related variables in the given 'str' with their values.
|
||||
void Util::streamVariables(std::string &str, const std::string &streamname,
|
||||
const std::string &source){
|
||||
void Util::streamVariables(std::string &str, const std::string &streamname, const std::string &source){
|
||||
replace(str, "$source", source);
|
||||
replace(str, "$datetime", "$year.$month.$day.$hour.$minute.$second");
|
||||
replace(str, "$day", strftime_now("%d"));
|
||||
|
@ -213,7 +216,9 @@ JSON::Value Util::getStreamConfig(const std::string &streamname){
|
|||
if (!Util::getGlobalConfig("defaultStream")){
|
||||
WARN_MSG("Could not get stream '%s' config!", smp.c_str());
|
||||
}else{
|
||||
INFO_MSG("Could not get stream '%s' config, not emitting WARN message because fallback is configured", smp.c_str());
|
||||
INFO_MSG("Could not get stream '%s' config, not emitting WARN message because fallback is "
|
||||
"configured",
|
||||
smp.c_str());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -447,7 +452,8 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
|
|||
}
|
||||
|
||||
if (pid == 0){
|
||||
for (std::set<int>::iterator it = Util::Procs::socketList.begin(); it != Util::Procs::socketList.end(); ++it){
|
||||
for (std::set<int>::iterator it = Util::Procs::socketList.begin();
|
||||
it != Util::Procs::socketList.end(); ++it){
|
||||
close(*it);
|
||||
}
|
||||
Socket::Connection io(0, 1);
|
||||
|
@ -511,8 +517,7 @@ JSON::Value Util::getInputBySource(const std::string &filename, bool isProvider)
|
|||
MEDIUM_MSG("Checking input %s: %s (%s)", inputs.getIndiceName(i).c_str(),
|
||||
tmp_input.getMember("name").asString().c_str(), source.c_str());
|
||||
|
||||
if (tmpFn.substr(0, front.size()) == front &&
|
||||
tmpFn.substr(tmpFn.size() - back.size()) == back){
|
||||
if (tmpFn.substr(0, front.size()) == front && tmpFn.substr(tmpFn.size() - back.size()) == back){
|
||||
if (tmp_input.getMember("non-provider") && !isProvider){
|
||||
noProviderNoPick = true;
|
||||
continue;
|
||||
|
@ -643,12 +648,24 @@ bool Util::checkException(const JSON::Value & ex, const std::string & useragent)
|
|||
if (!e->isArray() || !e->size()){continue;}
|
||||
bool setTo = false;
|
||||
bool except = false;
|
||||
//whitelist makes the return value true if any value is contained in the UA, blacklist makes it false.
|
||||
//the '_except' variants do so only if none of the values are contained in the UA.
|
||||
if ((*e)[0u].asStringRef() == "whitelist"){setTo = true; except = false;}
|
||||
if ((*e)[0u].asStringRef() == "whitelist_except"){setTo = true; except = true;}
|
||||
if ((*e)[0u].asStringRef() == "blacklist"){setTo = false; except = false;}
|
||||
if ((*e)[0u].asStringRef() == "blacklist_except"){setTo = false; except = true;}
|
||||
// whitelist makes the return value true if any value is contained in the UA, blacklist makes it
|
||||
// false. the '_except' variants do so only if none of the values are contained in the UA.
|
||||
if ((*e)[0u].asStringRef() == "whitelist"){
|
||||
setTo = true;
|
||||
except = false;
|
||||
}
|
||||
if ((*e)[0u].asStringRef() == "whitelist_except"){
|
||||
setTo = true;
|
||||
except = true;
|
||||
}
|
||||
if ((*e)[0u].asStringRef() == "blacklist"){
|
||||
setTo = false;
|
||||
except = false;
|
||||
}
|
||||
if ((*e)[0u].asStringRef() == "blacklist_except"){
|
||||
setTo = false;
|
||||
except = true;
|
||||
}
|
||||
if (e->size() == 1){
|
||||
ret = setTo;
|
||||
continue;
|
||||
|
@ -679,9 +696,12 @@ DTSC::Scan Util::DTSCShmReader::getScan(){
|
|||
return DTSC::Scan(rAcc.getPointer("dtsc_data"), rAcc.getSize("dtsc_data"));
|
||||
}
|
||||
|
||||
std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa, const std::string &trackType, const std::string &trackVal, const std::string &UA){
|
||||
std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa, const std::string &trackType,
|
||||
const std::string &trackVal, const std::string &UA){
|
||||
std::set<size_t> result;
|
||||
if (!trackVal.size() || trackVal == "0" || trackVal == "-1" || trackVal == "none"){return result;}//don't select anything in particular
|
||||
if (!trackVal.size() || trackVal == "0" || trackVal == "-1" || trackVal == "none"){
|
||||
return result;
|
||||
}// don't select anything in particular
|
||||
if (trackVal.find(',') != std::string::npos){
|
||||
// Comma-separated list, recurse.
|
||||
std::stringstream ss(trackVal);
|
||||
|
@ -702,10 +722,12 @@ std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa,
|
|||
}
|
||||
const DTSC::Track &Trk = M.tracks.at(trackNo);
|
||||
if (Trk.type != trackType && Trk.codec != trackType){
|
||||
INFO_MSG("Track %zd is not %s (%s/%s), cannot select", trackNo, trackType.c_str(), Trk.type.c_str(), Trk.codec.c_str());
|
||||
INFO_MSG("Track %zd is not %s (%s/%s), cannot select", trackNo, trackType.c_str(),
|
||||
Trk.type.c_str(), Trk.codec.c_str());
|
||||
return result;
|
||||
}
|
||||
INFO_MSG("Selecting %s track %zd (%s/%s)", trackType.c_str(), trackNo, Trk.type.c_str(), Trk.codec.c_str());
|
||||
INFO_MSG("Selecting %s track %zd (%s/%s)", trackType.c_str(), trackNo, Trk.type.c_str(),
|
||||
Trk.codec.c_str());
|
||||
result.insert(trackNo);
|
||||
return result;
|
||||
}
|
||||
|
@ -717,7 +739,9 @@ std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa,
|
|||
std::set<size_t> validTracks = getSupportedTracks(M, capa);
|
||||
for (std::set<size_t>::iterator it = validTracks.begin(); it != validTracks.end(); it++){
|
||||
const DTSC::Track &Trk = M.tracks.at(*it);
|
||||
if (!trackType.size() || Trk.type == trackType || Trk.codec == trackType){result.insert(*it);}
|
||||
if (!trackType.size() || Trk.type == trackType || Trk.codec == trackType){
|
||||
result.insert(*it);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -759,12 +783,24 @@ std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa,
|
|||
if (trackLow[0] == '<' || trackLow[0] == '>'){
|
||||
unsigned int bpsVal;
|
||||
uint64_t targetBps = 0;
|
||||
if (trackLow.find("bps") != std::string::npos && sscanf(trackLow.c_str(), "<%ubps", &bpsVal) == 1){targetBps = bpsVal;}
|
||||
if (trackLow.find("kbps") != std::string::npos && sscanf(trackLow.c_str(), "<%ukbps", &bpsVal) == 1){targetBps = bpsVal*1024;}
|
||||
if (trackLow.find("mbps") != std::string::npos && sscanf(trackLow.c_str(), "<%umbps", &bpsVal) == 1){targetBps = bpsVal*1024*1024;}
|
||||
if (trackLow.find("bps") != std::string::npos && sscanf(trackLow.c_str(), ">%ubps", &bpsVal) == 1){targetBps = bpsVal;}
|
||||
if (trackLow.find("kbps") != std::string::npos && sscanf(trackLow.c_str(), ">%ukbps", &bpsVal) == 1){targetBps = bpsVal*1024;}
|
||||
if (trackLow.find("mbps") != std::string::npos && sscanf(trackLow.c_str(), ">%umbps", &bpsVal) == 1){targetBps = bpsVal*1024*1024;}
|
||||
if (trackLow.find("bps") != std::string::npos && sscanf(trackLow.c_str(), "<%ubps", &bpsVal) == 1){
|
||||
targetBps = bpsVal;
|
||||
}
|
||||
if (trackLow.find("kbps") != std::string::npos && sscanf(trackLow.c_str(), "<%ukbps", &bpsVal) == 1){
|
||||
targetBps = bpsVal * 1024;
|
||||
}
|
||||
if (trackLow.find("mbps") != std::string::npos && sscanf(trackLow.c_str(), "<%umbps", &bpsVal) == 1){
|
||||
targetBps = bpsVal * 1024 * 1024;
|
||||
}
|
||||
if (trackLow.find("bps") != std::string::npos && sscanf(trackLow.c_str(), ">%ubps", &bpsVal) == 1){
|
||||
targetBps = bpsVal;
|
||||
}
|
||||
if (trackLow.find("kbps") != std::string::npos && sscanf(trackLow.c_str(), ">%ukbps", &bpsVal) == 1){
|
||||
targetBps = bpsVal * 1024;
|
||||
}
|
||||
if (trackLow.find("mbps") != std::string::npos && sscanf(trackLow.c_str(), ">%umbps", &bpsVal) == 1){
|
||||
targetBps = bpsVal * 1024 * 1024;
|
||||
}
|
||||
if (targetBps){
|
||||
targetBps >>= 3;
|
||||
// select all tracks of this type that match the requirements
|
||||
|
@ -799,9 +835,15 @@ std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa,
|
|||
{
|
||||
unsigned int bpsVal;
|
||||
uint64_t targetBps = 0;
|
||||
if (trackLow.find("bps") != std::string::npos && sscanf(trackLow.c_str(), "%ubps", &bpsVal) == 1){targetBps = bpsVal;}
|
||||
if (trackLow.find("kbps") != std::string::npos && sscanf(trackLow.c_str(), "%ukbps", &bpsVal) == 1){targetBps = bpsVal*1024;}
|
||||
if (trackLow.find("mbps") != std::string::npos && sscanf(trackLow.c_str(), "%umbps", &bpsVal) == 1){targetBps = bpsVal*1024*1024;}
|
||||
if (trackLow.find("bps") != std::string::npos && sscanf(trackLow.c_str(), "%ubps", &bpsVal) == 1){
|
||||
targetBps = bpsVal;
|
||||
}
|
||||
if (trackLow.find("kbps") != std::string::npos && sscanf(trackLow.c_str(), "%ukbps", &bpsVal) == 1){
|
||||
targetBps = bpsVal * 1024;
|
||||
}
|
||||
if (trackLow.find("mbps") != std::string::npos && sscanf(trackLow.c_str(), "%umbps", &bpsVal) == 1){
|
||||
targetBps = bpsVal * 1024 * 1024;
|
||||
}
|
||||
if (targetBps){
|
||||
targetBps >>= 3;
|
||||
// select nearest bit rate track of this type
|
||||
|
@ -811,7 +853,8 @@ std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa,
|
|||
for (std::set<size_t>::iterator it = validTracks.begin(); it != validTracks.end(); it++){
|
||||
const DTSC::Track &Trk = M.tracks.at(*it);
|
||||
if (!trackType.size() || Trk.type == trackType || Trk.codec == trackType){
|
||||
if (currVal == INVALID_TRACK_ID || (Trk.bps >= targetBps && currDist > (Trk.bps-targetBps)) || (Trk.bps < targetBps && currDist > (targetBps-Trk.bps))){
|
||||
if (currVal == INVALID_TRACK_ID || (Trk.bps >= targetBps && currDist > (Trk.bps - targetBps)) ||
|
||||
(Trk.bps < targetBps && currDist > (targetBps - Trk.bps))){
|
||||
currVal = *it;
|
||||
currDist = (Trk.bps >= targetBps) ? (Trk.bps - targetBps) : (targetBps - Trk.bps);
|
||||
}
|
||||
|
@ -838,7 +881,9 @@ std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa,
|
|||
if (trackLow == "mono"){targetChannel = 1;}
|
||||
if (trackLow == "stereo"){targetChannel = 2;}
|
||||
if (trackLow == "stereo"){targetChannel = 2;}
|
||||
if (trackLow.find("ch") != std::string::npos && sscanf(trackLow.c_str(), "%uch", &channelVal) == 1){targetChannel = channelVal;}
|
||||
if (trackLow.find("ch") != std::string::npos && sscanf(trackLow.c_str(), "%uch", &channelVal) == 1){
|
||||
targetChannel = channelVal;
|
||||
}
|
||||
if (targetChannel){
|
||||
std::set<size_t> validTracks = getSupportedTracks(M, capa);
|
||||
for (std::set<size_t>::iterator it = validTracks.begin(); it != validTracks.end(); it++){
|
||||
|
@ -900,7 +945,8 @@ std::set<size_t> Util::findTracks(const DTSC::Meta &M, const JSON::Value &capa,
|
|||
const DTSC::Track &Trk = M.tracks.at(*it);
|
||||
if (!trackType.size() || Trk.type == trackType || Trk.codec == trackType){
|
||||
uint64_t trackArea = Trk.width * Trk.height;
|
||||
if (currVal == INVALID_TRACK_ID || (trackArea >= targetArea && currDist > (trackArea-targetArea)) || (trackArea < targetArea && currDist > (targetArea-trackArea))){
|
||||
if (currVal == INVALID_TRACK_ID || (trackArea >= targetArea && currDist > (trackArea - targetArea)) ||
|
||||
(trackArea < targetArea && currDist > (targetArea - trackArea))){
|
||||
currVal = *it;
|
||||
currDist = (trackArea >= targetArea) ? (trackArea - targetArea) : (targetArea - trackArea);
|
||||
}
|
||||
|
@ -953,9 +999,7 @@ std::set<size_t> Util::getSupportedTracks(const DTSC::Meta &M, const JSON::Value
|
|||
std::set<size_t> validTracks;
|
||||
for (std::map<unsigned int, DTSC::Track>::const_iterator it = M.tracks.begin(); it != M.tracks.end(); it++){
|
||||
const DTSC::Track &Trk = it->second;
|
||||
if (type != "" && type != Trk.type){
|
||||
continue;
|
||||
}
|
||||
if (type != "" && type != Trk.type){continue;}
|
||||
// Remove tracks for which we don't have codec support
|
||||
if (capa.isMember("codecs")){
|
||||
std::string codec = Trk.codec;
|
||||
|
@ -1071,8 +1115,7 @@ std::set<size_t> Util::wouldSelect(const DTSC::Meta &M, const std::map<std::stri
|
|||
for (std::set<size_t>::iterator trit = validTracks.begin(); trit != validTracks.end(); trit++){
|
||||
const DTSC::Track &Trk = M.tracks.at(*trit);
|
||||
bool problems = false;
|
||||
if (capa.isMember("exceptions") && capa["exceptions"].isObject() &&
|
||||
capa["exceptions"].size()){
|
||||
if (capa.isMember("exceptions") && capa["exceptions"].isObject() && capa["exceptions"].size()){
|
||||
jsonForEachConst(capa["exceptions"], ex){
|
||||
if (ex.key() == "codec:" + Trk.codec){
|
||||
problems = !Util::checkException(*ex, UA);
|
||||
|
@ -1091,7 +1134,6 @@ std::set<size_t> Util::wouldSelect(const DTSC::Meta &M, const std::map<std::stri
|
|||
}
|
||||
/*LTS-END*/
|
||||
|
||||
|
||||
jsonForEachConst(capa["codecs"], it){
|
||||
unsigned int selCounter = 0;
|
||||
if ((*it).size() > 0){
|
||||
|
@ -1222,10 +1264,7 @@ std::set<size_t> Util::wouldSelect(const DTSC::Meta &M, const std::map<std::stri
|
|||
/*LTS-START*/
|
||||
if (noSelAudio && Trk.type == "audio"){continue;}
|
||||
if (noSelVideo && Trk.type == "video"){continue;}
|
||||
if (noSelSub &&
|
||||
(Trk.type == "subtitle" || Trk.codec == "subtitle")){
|
||||
continue;
|
||||
}
|
||||
if (noSelSub && (Trk.type == "subtitle" || Trk.codec == "subtitle")){continue;}
|
||||
/*LTS-END*/
|
||||
result.insert(*trit);
|
||||
found = true;
|
||||
|
@ -1253,10 +1292,7 @@ std::set<size_t> Util::wouldSelect(const DTSC::Meta &M, const std::map<std::stri
|
|||
/*LTS-START*/
|
||||
if (noSelAudio && Trk.type == "audio"){continue;}
|
||||
if (noSelVideo && Trk.type == "video"){continue;}
|
||||
if (noSelSub &&
|
||||
(Trk.type == "subtitle" || Trk.type == "subtitle")){
|
||||
continue;
|
||||
}
|
||||
if (noSelSub && (Trk.type == "subtitle" || Trk.type == "subtitle")){continue;}
|
||||
/*LTS-END*/
|
||||
result.insert(*trit);
|
||||
found = true;
|
||||
|
|
28
lib/stream.h
28
lib/stream.h
|
@ -2,12 +2,12 @@
|
|||
/// Utilities for handling streams.
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "socket.h"
|
||||
#include "json.h"
|
||||
#include "dtsc.h"
|
||||
#include "json.h"
|
||||
#include "shared_memory.h"
|
||||
#include "socket.h"
|
||||
#include "util.h"
|
||||
#include <string>
|
||||
|
||||
const JSON::Value empty;
|
||||
|
||||
|
@ -16,7 +16,10 @@ namespace Util {
|
|||
std::string getTmpFolder();
|
||||
void sanitizeName(std::string &streamname);
|
||||
bool streamAlive(std::string &streamname);
|
||||
bool startInput(std::string streamname, std::string filename = "", bool forkFirst = true, bool isProvider = false, const std::map<std::string, std::string> & overrides = std::map<std::string, std::string>(), pid_t * spawn_pid = NULL);
|
||||
bool startInput(std::string streamname, std::string filename = "", bool forkFirst = true,
|
||||
bool isProvider = false,
|
||||
const std::map<std::string, std::string> &overrides = std::map<std::string, std::string>(),
|
||||
pid_t *spawn_pid = NULL);
|
||||
int startPush(const std::string &streamname, std::string &target);
|
||||
JSON::Value getStreamConfig(const std::string &streamname);
|
||||
JSON::Value getGlobalConfig(const std::string &optionName);
|
||||
|
@ -26,20 +29,25 @@ namespace Util {
|
|||
bool checkException(const JSON::Value &ex, const std::string &useragent);
|
||||
std::string codecString(const std::string &codec, const std::string &initData = "");
|
||||
|
||||
std::set<size_t> getSupportedTracks(const DTSC::Meta &M, const JSON::Value &capa = empty, const std::string &type = "", const std::string &UA = "");
|
||||
std::set<size_t> findTracks(const DTSC::Meta &M, const JSON::Value &capa, const std::string &trackType, const std::string &trackVal, const std::string &UA = "");
|
||||
std::set<size_t> wouldSelect(const DTSC::Meta &M, const std::string &trackSelector = "", const JSON::Value &capa = empty, const std::string &UA = "");
|
||||
std::set<size_t> wouldSelect(const DTSC::Meta &M, const std::map<std::string, std::string> &targetParams, const JSON::Value &capa = empty, const std::string &UA = "", uint64_t seekTarget = 0);
|
||||
std::set<size_t> getSupportedTracks(const DTSC::Meta &M, const JSON::Value &capa = empty,
|
||||
const std::string &type = "", const std::string &UA = "");
|
||||
std::set<size_t> findTracks(const DTSC::Meta &M, const JSON::Value &capa, const std::string &trackType,
|
||||
const std::string &trackVal, const std::string &UA = "");
|
||||
std::set<size_t> wouldSelect(const DTSC::Meta &M, const std::string &trackSelector = "",
|
||||
const JSON::Value &capa = empty, const std::string &UA = "");
|
||||
std::set<size_t> wouldSelect(const DTSC::Meta &M, const std::map<std::string, std::string> &targetParams,
|
||||
const JSON::Value &capa = empty, const std::string &UA = "",
|
||||
uint64_t seekTarget = 0);
|
||||
|
||||
class DTSCShmReader{
|
||||
public:
|
||||
DTSCShmReader(const std::string &pageName);
|
||||
DTSC::Scan getMember(const std::string &indice);
|
||||
DTSC::Scan getScan();
|
||||
|
||||
private:
|
||||
IPC::sharedPage rPage;
|
||||
Util::RelAccX rAcc;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}// namespace Util
|
||||
|
|
270
lib/stun.cpp
270
lib/stun.cpp
|
@ -1,62 +1,144 @@
|
|||
#include "checksum.h" // for crc32
|
||||
#include "defines.h"
|
||||
#include "stun.h"
|
||||
#include "checksum.h" // for crc32
|
||||
|
||||
/* --------------------------------------- */
|
||||
|
||||
std::string stun_family_type_to_string(uint8_t type){
|
||||
switch (type){
|
||||
case STUN_IP4: { return "STUN_IP4"; }
|
||||
case STUN_IP6: { return "STUN_IP6"; }
|
||||
default: { return "UNKNOWN"; }
|
||||
case STUN_IP4:{
|
||||
return "STUN_IP4";
|
||||
}
|
||||
case STUN_IP6:{
|
||||
return "STUN_IP6";
|
||||
}
|
||||
default:{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string stun_message_type_to_string(uint16_t type){
|
||||
switch (type){
|
||||
case STUN_MSG_TYPE_NONE: { return "STUN_MSG_TYPE_NONE"; }
|
||||
case STUN_MSG_TYPE_BINDING_REQUEST: { return "STUN_MSG_TYPE_BINDING_REQUEST"; }
|
||||
case STUN_MSG_TYPE_BINDING_RESPONSE_SUCCESS: { return "STUN_MSG_TYPE_BINDING_RESPONSE_SUCCESS"; }
|
||||
case STUN_MSG_TYPE_BINDING_RESPONSE_ERROR: { return "STUN_MSG_TYPE_BINDING_RESPONSE_ERROR"; }
|
||||
case STUN_MSG_TYPE_BINDING_INDICATION: { return "STUN_MSG_TYPE_BINDING_INDICATION"; }
|
||||
default: { return "UNKNOWN"; }
|
||||
case STUN_MSG_TYPE_NONE:{
|
||||
return "STUN_MSG_TYPE_NONE";
|
||||
}
|
||||
case STUN_MSG_TYPE_BINDING_REQUEST:{
|
||||
return "STUN_MSG_TYPE_BINDING_REQUEST";
|
||||
}
|
||||
case STUN_MSG_TYPE_BINDING_RESPONSE_SUCCESS:{
|
||||
return "STUN_MSG_TYPE_BINDING_RESPONSE_SUCCESS";
|
||||
}
|
||||
case STUN_MSG_TYPE_BINDING_RESPONSE_ERROR:{
|
||||
return "STUN_MSG_TYPE_BINDING_RESPONSE_ERROR";
|
||||
}
|
||||
case STUN_MSG_TYPE_BINDING_INDICATION:{
|
||||
return "STUN_MSG_TYPE_BINDING_INDICATION";
|
||||
}
|
||||
default:{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string stun_attribute_type_to_string(uint16_t type){
|
||||
switch (type){
|
||||
case STUN_ATTR_TYPE_NONE: { return "STUN_ATTR_TYPE_NONE"; }
|
||||
case STUN_ATTR_TYPE_MAPPED_ADDR: { return "STUN_ATTR_TYPE_MAPPED_ADDR"; }
|
||||
case STUN_ATTR_TYPE_CHANGE_REQ: { return "STUN_ATTR_TYPE_CHANGE_REQ"; }
|
||||
case STUN_ATTR_TYPE_USERNAME: { return "STUN_ATTR_TYPE_USERNAME"; }
|
||||
case STUN_ATTR_TYPE_MESSAGE_INTEGRITY: { return "STUN_ATTR_TYPE_MESSAGE_INTEGRITY"; }
|
||||
case STUN_ATTR_TYPE_ERR_CODE: { return "STUN_ATTR_TYPE_ERR_CODE"; }
|
||||
case STUN_ATTR_TYPE_UNKNOWN_ATTRIBUTES: { return "STUN_ATTR_TYPE_UNKNOWN_ATTRIBUTES"; }
|
||||
case STUN_ATTR_TYPE_CHANNEL_NUMBER: { return "STUN_ATTR_TYPE_CHANNEL_NUMBER"; }
|
||||
case STUN_ATTR_TYPE_LIFETIME: { return "STUN_ATTR_TYPE_LIFETIME"; }
|
||||
case STUN_ATTR_TYPE_XOR_PEER_ADDR: { return "STUN_ATTR_TYPE_XOR_PEER_ADDR"; }
|
||||
case STUN_ATTR_TYPE_DATA: { return "STUN_ATTR_TYPE_DATA"; }
|
||||
case STUN_ATTR_TYPE_REALM: { return "STUN_ATTR_TYPE_REALM"; }
|
||||
case STUN_ATTR_TYPE_NONCE: { return "STUN_ATTR_TYPE_NONCE"; }
|
||||
case STUN_ATTR_TYPE_XOR_RELAY_ADDRESS: { return "STUN_ATTR_TYPE_XOR_RELAY_ADDRESS"; }
|
||||
case STUN_ATTR_TYPE_REQ_ADDRESS_FAMILY: { return "STUN_ATTR_TYPE_REQ_ADDRESS_FAMILY"; }
|
||||
case STUN_ATTR_TYPE_EVEN_PORT: { return "STUN_ATTR_TYPE_EVEN_PORT"; }
|
||||
case STUN_ATTR_TYPE_REQUESTED_TRANSPORT: { return "STUN_ATTR_TYPE_REQUESTED_TRANSPORT"; }
|
||||
case STUN_ATTR_TYPE_DONT_FRAGMENT: { return "STUN_ATTR_TYPE_DONT_FRAGMENT"; }
|
||||
case STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS: { return "STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS"; }
|
||||
case STUN_ATTR_TYPE_RESERVATION_TOKEN: { return "STUN_ATTR_TYPE_RESERVATION_TOKEN"; }
|
||||
case STUN_ATTR_TYPE_PRIORITY: { return "STUN_ATTR_TYPE_PRIORITY"; }
|
||||
case STUN_ATTR_TYPE_USE_CANDIDATE: { return "STUN_ATTR_TYPE_USE_CANDIDATE"; }
|
||||
case STUN_ATTR_TYPE_PADDING: { return "STUN_ATTR_TYPE_PADDING"; }
|
||||
case STUN_ATTR_TYPE_RESPONSE_PORT: { return "STUN_ATTR_TYPE_RESPONSE_PORT"; }
|
||||
case STUN_ATTR_TYPE_SOFTWARE: { return "STUN_ATTR_TYPE_SOFTWARE"; }
|
||||
case STUN_ATTR_TYPE_ALTERNATE_SERVER: { return "STUN_ATTR_TYPE_ALTERNATE_SERVER"; }
|
||||
case STUN_ATTR_TYPE_FINGERPRINT: { return "STUN_ATTR_TYPE_FINGERPRINT"; }
|
||||
case STUN_ATTR_TYPE_ICE_CONTROLLED: { return "STUN_ATTR_TYPE_ICE_CONTROLLED"; }
|
||||
case STUN_ATTR_TYPE_ICE_CONTROLLING: { return "STUN_ATTR_TYPE_ICE_CONTROLLING"; }
|
||||
case STUN_ATTR_TYPE_RESPONSE_ORIGIN: { return "STUN_ATTR_TYPE_RESPONSE_ORIGIN"; }
|
||||
case STUN_ATTR_TYPE_OTHER_ADDRESS: { return "STUN_ATTR_TYPE_OTHER_ADDRESS"; }
|
||||
default: { return "UNKNOWN"; }
|
||||
case STUN_ATTR_TYPE_NONE:{
|
||||
return "STUN_ATTR_TYPE_NONE";
|
||||
}
|
||||
case STUN_ATTR_TYPE_MAPPED_ADDR:{
|
||||
return "STUN_ATTR_TYPE_MAPPED_ADDR";
|
||||
}
|
||||
case STUN_ATTR_TYPE_CHANGE_REQ:{
|
||||
return "STUN_ATTR_TYPE_CHANGE_REQ";
|
||||
}
|
||||
case STUN_ATTR_TYPE_USERNAME:{
|
||||
return "STUN_ATTR_TYPE_USERNAME";
|
||||
}
|
||||
case STUN_ATTR_TYPE_MESSAGE_INTEGRITY:{
|
||||
return "STUN_ATTR_TYPE_MESSAGE_INTEGRITY";
|
||||
}
|
||||
case STUN_ATTR_TYPE_ERR_CODE:{
|
||||
return "STUN_ATTR_TYPE_ERR_CODE";
|
||||
}
|
||||
case STUN_ATTR_TYPE_UNKNOWN_ATTRIBUTES:{
|
||||
return "STUN_ATTR_TYPE_UNKNOWN_ATTRIBUTES";
|
||||
}
|
||||
case STUN_ATTR_TYPE_CHANNEL_NUMBER:{
|
||||
return "STUN_ATTR_TYPE_CHANNEL_NUMBER";
|
||||
}
|
||||
case STUN_ATTR_TYPE_LIFETIME:{
|
||||
return "STUN_ATTR_TYPE_LIFETIME";
|
||||
}
|
||||
case STUN_ATTR_TYPE_XOR_PEER_ADDR:{
|
||||
return "STUN_ATTR_TYPE_XOR_PEER_ADDR";
|
||||
}
|
||||
case STUN_ATTR_TYPE_DATA:{
|
||||
return "STUN_ATTR_TYPE_DATA";
|
||||
}
|
||||
case STUN_ATTR_TYPE_REALM:{
|
||||
return "STUN_ATTR_TYPE_REALM";
|
||||
}
|
||||
case STUN_ATTR_TYPE_NONCE:{
|
||||
return "STUN_ATTR_TYPE_NONCE";
|
||||
}
|
||||
case STUN_ATTR_TYPE_XOR_RELAY_ADDRESS:{
|
||||
return "STUN_ATTR_TYPE_XOR_RELAY_ADDRESS";
|
||||
}
|
||||
case STUN_ATTR_TYPE_REQ_ADDRESS_FAMILY:{
|
||||
return "STUN_ATTR_TYPE_REQ_ADDRESS_FAMILY";
|
||||
}
|
||||
case STUN_ATTR_TYPE_EVEN_PORT:{
|
||||
return "STUN_ATTR_TYPE_EVEN_PORT";
|
||||
}
|
||||
case STUN_ATTR_TYPE_REQUESTED_TRANSPORT:{
|
||||
return "STUN_ATTR_TYPE_REQUESTED_TRANSPORT";
|
||||
}
|
||||
case STUN_ATTR_TYPE_DONT_FRAGMENT:{
|
||||
return "STUN_ATTR_TYPE_DONT_FRAGMENT";
|
||||
}
|
||||
case STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS:{
|
||||
return "STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS";
|
||||
}
|
||||
case STUN_ATTR_TYPE_RESERVATION_TOKEN:{
|
||||
return "STUN_ATTR_TYPE_RESERVATION_TOKEN";
|
||||
}
|
||||
case STUN_ATTR_TYPE_PRIORITY:{
|
||||
return "STUN_ATTR_TYPE_PRIORITY";
|
||||
}
|
||||
case STUN_ATTR_TYPE_USE_CANDIDATE:{
|
||||
return "STUN_ATTR_TYPE_USE_CANDIDATE";
|
||||
}
|
||||
case STUN_ATTR_TYPE_PADDING:{
|
||||
return "STUN_ATTR_TYPE_PADDING";
|
||||
}
|
||||
case STUN_ATTR_TYPE_RESPONSE_PORT:{
|
||||
return "STUN_ATTR_TYPE_RESPONSE_PORT";
|
||||
}
|
||||
case STUN_ATTR_TYPE_SOFTWARE:{
|
||||
return "STUN_ATTR_TYPE_SOFTWARE";
|
||||
}
|
||||
case STUN_ATTR_TYPE_ALTERNATE_SERVER:{
|
||||
return "STUN_ATTR_TYPE_ALTERNATE_SERVER";
|
||||
}
|
||||
case STUN_ATTR_TYPE_FINGERPRINT:{
|
||||
return "STUN_ATTR_TYPE_FINGERPRINT";
|
||||
}
|
||||
case STUN_ATTR_TYPE_ICE_CONTROLLED:{
|
||||
return "STUN_ATTR_TYPE_ICE_CONTROLLED";
|
||||
}
|
||||
case STUN_ATTR_TYPE_ICE_CONTROLLING:{
|
||||
return "STUN_ATTR_TYPE_ICE_CONTROLLING";
|
||||
}
|
||||
case STUN_ATTR_TYPE_RESPONSE_ORIGIN:{
|
||||
return "STUN_ATTR_TYPE_RESPONSE_ORIGIN";
|
||||
}
|
||||
case STUN_ATTR_TYPE_OTHER_ADDRESS:{
|
||||
return "STUN_ATTR_TYPE_OTHER_ADDRESS";
|
||||
}
|
||||
default:{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,15 +181,12 @@ static uint32_t poly_crc32(uint32_t inCrc, const uint8_t* data, size_t nbytes)
|
|||
0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
|
||||
0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
|
||||
0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D
|
||||
};
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
|
||||
|
||||
uint32_t crc32 = inCrc ^ 0xFFFFFFFF;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
crc32 = (crc32 >> 8) ^ crc_table[ (crc32 ^ data[i]) & 0xFF ];
|
||||
}
|
||||
for (i = 0; i < nbytes; i++){crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ data[i]) & 0xFF];}
|
||||
|
||||
return (crc32 ^ 0xFFFFFFFF);
|
||||
}
|
||||
|
@ -154,7 +233,8 @@ int stun_compute_hmac_sha1(uint8_t* message, uint32_t nbytes, std::string key, u
|
|||
goto error;
|
||||
}
|
||||
|
||||
DONTEVEN_MSG("Calculating hmac-sha1 with key `%s` with size %zu over %zu bytes of data.", key.c_str(), key.size(), nbytes);
|
||||
DONTEVEN_MSG("Calculating hmac-sha1 with key `%s` with size %zu over %zu bytes of data.",
|
||||
key.c_str(), key.size(), nbytes);
|
||||
|
||||
r = mbedtls_md_hmac_starts(&md_ctx, (const unsigned char *)key.c_str(), key.size());
|
||||
if (r != 0){
|
||||
|
@ -243,13 +323,9 @@ int stun_compute_message_integrity(std::vector<uint8_t>& buffer, std::string key
|
|||
dx += len;
|
||||
|
||||
/* skip padding. */
|
||||
while ( (dx & 0x03) != 0 && dx < buffer.size()) {
|
||||
dx++;
|
||||
}
|
||||
while ((dx & 0x03) != 0 && dx < buffer.size()){dx++;}
|
||||
|
||||
if (type == STUN_ATTR_TYPE_MESSAGE_INTEGRITY) {
|
||||
break;
|
||||
}
|
||||
if (type == STUN_ATTR_TYPE_MESSAGE_INTEGRITY){break;}
|
||||
|
||||
type = 0;
|
||||
len = 0;
|
||||
|
@ -310,13 +386,9 @@ int stun_compute_fingerprint(std::vector<uint8_t>& buffer, uint32_t& result) {
|
|||
dx += len;
|
||||
|
||||
/* skip padding. */
|
||||
while ( (dx & 0x03) != 0 && dx < buffer.size()) {
|
||||
dx++;
|
||||
}
|
||||
while ((dx & 0x03) != 0 && dx < buffer.size()){dx++;}
|
||||
|
||||
if (type == STUN_ATTR_TYPE_FINGERPRINT) {
|
||||
break;
|
||||
}
|
||||
if (type == STUN_ATTR_TYPE_FINGERPRINT){break;}
|
||||
|
||||
type = 0;
|
||||
len = 0;
|
||||
|
@ -327,7 +399,6 @@ int stun_compute_fingerprint(std::vector<uint8_t>& buffer, uint32_t& result) {
|
|||
buffer[2] = (offset >> 8) & 0xFF;
|
||||
buffer[3] = offset & 0xFF;
|
||||
|
||||
|
||||
// result = (checksum::crc32LE(0 ^ 0xFFFFFFFF, (const char*)&buffer[0], offset + 12) ^ 0xFFFFFFFF) ^ 0x5354554e;
|
||||
result = poly_crc32(0L, &buffer[0], offset + 12) ^ 0x5354554e;
|
||||
|
||||
|
@ -340,11 +411,7 @@ int stun_compute_fingerprint(std::vector<uint8_t>& buffer, uint32_t& result) {
|
|||
|
||||
/* --------------------------------------- */
|
||||
|
||||
StunAttribute::StunAttribute()
|
||||
:type(STUN_ATTR_TYPE_NONE)
|
||||
,length(0)
|
||||
{
|
||||
}
|
||||
StunAttribute::StunAttribute() : type(STUN_ATTR_TYPE_NONE), length(0){}
|
||||
|
||||
void StunAttribute::print(){
|
||||
|
||||
|
@ -354,7 +421,8 @@ void StunAttribute::print() {
|
|||
switch (type){
|
||||
|
||||
case STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS:{
|
||||
DONTEVEN_MSG("StunAttribute.xor_address.family: %s", stun_family_type_to_string(xor_address.family).c_str());
|
||||
DONTEVEN_MSG("StunAttribute.xor_address.family: %s",
|
||||
stun_family_type_to_string(xor_address.family).c_str());
|
||||
DONTEVEN_MSG("StunAttribute.xor_address.port: %u", xor_address.port);
|
||||
DONTEVEN_MSG("StunAttribute.xor_address.ip: %s", (char *)xor_address.ip);
|
||||
break;
|
||||
|
@ -372,7 +440,8 @@ void StunAttribute::print() {
|
|||
|
||||
case STUN_ATTR_TYPE_ICE_CONTROLLING:{
|
||||
uint8_t *p = (uint8_t *)&ice_controlling.tie_breaker;
|
||||
DONTEVEN_MSG("StunAttribute.ice_controlling.tie_breaker: 0x%04x%04x", *(uint32_t*)(p + 4), *(uint32_t*)(p));
|
||||
DONTEVEN_MSG("StunAttribute.ice_controlling.tie_breaker: 0x%04x%04x", *(uint32_t *)(p + 4),
|
||||
*(uint32_t *)(p));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -383,9 +452,7 @@ void StunAttribute::print() {
|
|||
|
||||
case STUN_ATTR_TYPE_MESSAGE_INTEGRITY:{
|
||||
std::stringstream ss;
|
||||
for(int i = 0; i < 20; ++i) {
|
||||
ss << std::hex << (int) message_integrity.sha1[i];
|
||||
}
|
||||
for (int i = 0; i < 20; ++i){ss << std::hex << (int)message_integrity.sha1[i];}
|
||||
std::string str = ss.str();
|
||||
DONTEVEN_MSG("StunAttribute.message_integrity.sha1: %s", str.c_str());
|
||||
break;
|
||||
|
@ -400,11 +467,7 @@ void StunAttribute::print() {
|
|||
|
||||
/* --------------------------------------- */
|
||||
|
||||
StunMessage::StunMessage()
|
||||
:type(STUN_MSG_TYPE_NONE)
|
||||
,length(0)
|
||||
,cookie(0x2112a442)
|
||||
{
|
||||
StunMessage::StunMessage() : type(STUN_MSG_TYPE_NONE), length(0), cookie(0x2112a442){
|
||||
transaction_id[0] = 0;
|
||||
transaction_id[1] = 0;
|
||||
transaction_id[2] = 0;
|
||||
|
@ -432,25 +495,19 @@ void StunMessage::print() {
|
|||
DONTEVEN_MSG("StunMessage.type: %s", stun_message_type_to_string(type).c_str());
|
||||
DONTEVEN_MSG("StunMessage.length: %u", length);
|
||||
DONTEVEN_MSG("StunMessage.cookie: 0x%08X", cookie);
|
||||
DONTEVEN_MSG("StunMessage.transaction_id: 0x%08X, 0x%08X, 0x%08X", transaction_id[0], transaction_id[1], transaction_id[2]);
|
||||
DONTEVEN_MSG("StunMessage.transaction_id: 0x%08X, 0x%08X, 0x%08X", transaction_id[0],
|
||||
transaction_id[1], transaction_id[2]);
|
||||
}
|
||||
|
||||
StunAttribute *StunMessage::getAttributeByType(uint16_t type){
|
||||
size_t nattribs = attributes.size();
|
||||
for (size_t i = 0; i < nattribs; ++i){
|
||||
if (attributes[i].type == type) {
|
||||
return &attributes[i];
|
||||
}
|
||||
if (attributes[i].type == type){return &attributes[i];}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* --------------------------------------- */
|
||||
StunReader::StunReader()
|
||||
:buffer_data(NULL)
|
||||
,buffer_size(0)
|
||||
,read_dx(0)
|
||||
{
|
||||
}
|
||||
StunReader::StunReader() : buffer_data(NULL), buffer_size(0), read_dx(0){}
|
||||
|
||||
int StunReader::parse(uint8_t *data, size_t nbytes, size_t &nparsed, StunMessage &msg){
|
||||
|
||||
|
@ -551,16 +608,15 @@ int StunReader::parse(uint8_t* data, size_t nbytes, size_t& nparsed, StunMessage
|
|||
}
|
||||
|
||||
default:{
|
||||
DONTEVEN_MSG("Unhandled stun attribute: 0x%04X, %s", attr.type, stun_attribute_type_to_string(attr.type).c_str());
|
||||
DONTEVEN_MSG("Unhandled stun attribute: 0x%04X, %s", attr.type,
|
||||
stun_attribute_type_to_string(attr.type).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move the read_dx so it's positioned after the currently parsed attribute */
|
||||
read_dx = attr_offset + attr.length;
|
||||
while ( (read_dx & 0x03) != 0 && (read_dx < buffer_size)) {
|
||||
read_dx++;
|
||||
}
|
||||
while ((read_dx & 0x03) != 0 && (read_dx < buffer_size)){read_dx++;}
|
||||
|
||||
msg.attributes.push_back(attr);
|
||||
|
||||
|
@ -681,12 +737,7 @@ int StunReader::parseXorMappedAddress(StunAttribute& attr) {
|
|||
ip_ptr[2] = ip_ptr[2] ^ cookie[2];
|
||||
ip_ptr[3] = ip_ptr[3] ^ cookie[3];
|
||||
|
||||
sprintf((char*)attr.xor_address.ip,
|
||||
"%u.%u.%u.%u",
|
||||
ip_ptr[3],
|
||||
ip_ptr[2],
|
||||
ip_ptr[1],
|
||||
ip_ptr[0]);
|
||||
sprintf((char *)attr.xor_address.ip, "%u.%u.%u.%u", ip_ptr[3], ip_ptr[2], ip_ptr[1], ip_ptr[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -767,10 +818,7 @@ uint64_t StunReader::readU64() {
|
|||
|
||||
/* --------------------------------------- */
|
||||
|
||||
StunWriter::StunWriter()
|
||||
:padding_byte(0)
|
||||
{
|
||||
}
|
||||
StunWriter::StunWriter() : padding_byte(0){}
|
||||
|
||||
int StunWriter::begin(StunMessage &msg, uint8_t paddingByte){
|
||||
|
||||
|
@ -819,7 +867,8 @@ int StunWriter::writeXorMappedAddress(uint8_t family, uint16_t port, const std::
|
|||
|
||||
uint32_t ip_int = 0;
|
||||
if (0 != convertIp4StringToInt(ip, ip_int)){
|
||||
FAIL_MSG("Cannot write xor-mapped-address, because we failed to convert the given IP4 string into a uint32_t.");
|
||||
FAIL_MSG("Cannot write xor-mapped-address, because we failed to convert the given IP4 string "
|
||||
"into a uint32_t.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -870,7 +919,8 @@ int StunWriter::writeXorMappedAddress(uint8_t family, uint16_t port, uint32_t ip
|
|||
int StunWriter::writeUsername(const std::string &username){
|
||||
|
||||
if (buffer.size() < 20){
|
||||
FAIL_MSG("Cannot write username because you didn't call `begin()` and the STUN header hasn't been written yet..");
|
||||
FAIL_MSG("Cannot write username because you didn't call `begin()` and the STUN header hasn't "
|
||||
"been written yet..");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -885,7 +935,8 @@ int StunWriter::writeUsername(const std::string& username) {
|
|||
int StunWriter::writeSoftware(const std::string &software){
|
||||
|
||||
if (buffer.size() < 20){
|
||||
FAIL_MSG("Cannot write software because it seems that you didn't call `begin()` which writes the stun header.");
|
||||
FAIL_MSG("Cannot write software because it seems that you didn't call `begin()` which writes "
|
||||
"the stun header.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -905,7 +956,8 @@ int StunWriter::writeSoftware(const std::string& software) {
|
|||
int StunWriter::writeMessageIntegrity(const std::string &password){
|
||||
|
||||
if (buffer.size() < 20){
|
||||
FAIL_MSG("Cannot write the message integrity because it seems that you didn't call `begin()` which writes the stun header.");
|
||||
FAIL_MSG("Cannot write the message integrity because it seems that you didn't call `begin()` "
|
||||
"which writes the stun header.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -936,7 +988,8 @@ int StunWriter::writeMessageIntegrity(const std::string& password) {
|
|||
int StunWriter::writeFingerprint(){
|
||||
|
||||
if (buffer.size() < 20){
|
||||
FAIL_MSG("Cannot write the fingerprint because it seems that you didn't write the header, call `begin()` first.");
|
||||
FAIL_MSG("Cannot write the fingerprint because it seems that you didn't write the header, call "
|
||||
"`begin()` first.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1026,7 +1079,8 @@ void StunWriter::rewriteU16(size_t dx, uint16_t v) {
|
|||
void StunWriter::rewriteU32(size_t dx, uint32_t v){
|
||||
|
||||
if ((dx + 4) > buffer.size()){
|
||||
FAIL_MSG("Trying to rewrite U32 in Stun::StunWriter::rewriteU32() but index is out of bounds.\n");
|
||||
FAIL_MSG(
|
||||
"Trying to rewrite U32 in Stun::StunWriter::rewriteU32() but index is out of bounds.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1043,9 +1097,7 @@ void StunWriter::writeString(const std::string& str) {
|
|||
|
||||
void StunWriter::writePadding(){
|
||||
|
||||
while ((buffer.size() & 0x03) != 0) {
|
||||
buffer.push_back(padding_byte);
|
||||
}
|
||||
while ((buffer.size() & 0x03) != 0){buffer.push_back(padding_byte);}
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
|
|
13
lib/stun.h
13
lib/stun.h
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/* --------------------------------------- */
|
||||
|
||||
|
@ -200,7 +200,10 @@ public:
|
|||
StunWriter();
|
||||
|
||||
/* write header and finalize. call for each stun message */
|
||||
int begin(StunMessage& msg, uint8_t paddingByte = 0x00); /* I've added the padding byte here so that we can use the examples that can be found here https://tools.ietf.org/html/rfc5769#section-2.2 as they use 0x20 or 0x00 as the padding byte which is correct as you are free to use w/e padding byte you want. */
|
||||
int begin(StunMessage &msg,
|
||||
uint8_t paddingByte = 0x00); /* I've added the padding byte here so that we can use the
|
||||
examples that can be found here https://tools.ietf.org/html/rfc5769#section-2.2
|
||||
as they use 0x20 or 0x00 as the padding byte which is correct as you are free to use w/e padding byte you want. */
|
||||
int end();
|
||||
|
||||
/* write attributes */
|
||||
|
@ -236,9 +239,7 @@ private:
|
|||
|
||||
inline uint8_t *StunWriter::getBufferPtr(){
|
||||
|
||||
if (0 == buffer.size()) {
|
||||
return NULL;
|
||||
}
|
||||
if (0 == buffer.size()){return NULL;}
|
||||
|
||||
return &buffer[0];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "subtitles.h"
|
||||
#include "bitfields.h"
|
||||
#include "subtitles.h"
|
||||
|
||||
#include "defines.h"
|
||||
namespace Subtitle{
|
||||
|
@ -21,7 +21,6 @@ namespace Subtitle {
|
|||
}else{
|
||||
// get parts from meta
|
||||
// calculate duration
|
||||
|
||||
}
|
||||
|
||||
packet.getString("data", output.subtitle);
|
||||
|
@ -33,6 +32,4 @@ namespace Subtitle {
|
|||
return output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}// namespace Subtitle
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include "dtsc.h"
|
||||
#include <string>
|
||||
|
||||
namespace Subtitle{
|
||||
|
||||
|
@ -11,5 +11,4 @@ namespace Subtitle {
|
|||
|
||||
Packet getSubtitle(DTSC::Packet packet, DTSC::Meta meta);
|
||||
|
||||
}
|
||||
|
||||
}// namespace Subtitle
|
||||
|
|
139
lib/theora.cpp
139
lib/theora.cpp
|
@ -1,9 +1,9 @@
|
|||
#include "defines.h"
|
||||
#include "theora.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sstream>
|
||||
#include "defines.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace theora{
|
||||
bool header::checkDataSize(unsigned int size){
|
||||
|
@ -36,9 +36,7 @@ namespace theora {
|
|||
}
|
||||
|
||||
uint16_t header::getInt16(size_t index){
|
||||
if (datasize >= (index + 1)){
|
||||
return 0 + (data[index] << 8) + data[index + 1];
|
||||
}
|
||||
if (datasize >= (index + 1)){return 0 + (data[index] << 8) + data[index + 1];}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -54,197 +52,138 @@ namespace theora {
|
|||
datasize = length;
|
||||
}
|
||||
|
||||
header::~header(){
|
||||
}
|
||||
header::~header(){}
|
||||
|
||||
bool isHeader(const char *newData, unsigned int length){
|
||||
if (length < 7){
|
||||
return false;
|
||||
}
|
||||
if (length < 7){return false;}
|
||||
if (!(newData[0] & 0x80)){
|
||||
FAIL_MSG("newdata != 0x80: %.2X", newData[0]);
|
||||
return false;
|
||||
}
|
||||
if (memcmp(newData + 1, "theora", 6) != 0){
|
||||
return false;
|
||||
}
|
||||
if (memcmp(newData + 1, "theora", 6) != 0){return false;}
|
||||
return true;
|
||||
}
|
||||
|
||||
int header::getHeaderType(){
|
||||
return (data[0] & 0x7F);
|
||||
}
|
||||
int header::getHeaderType(){return (data[0] & 0x7F);}
|
||||
|
||||
char header::getVMAJ(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[7];
|
||||
}
|
||||
if (getHeaderType() == 0){return data[7];}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getVMIN(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[8];
|
||||
}
|
||||
if (getHeaderType() == 0){return data[8];}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getVREV(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[9];
|
||||
}
|
||||
if (getHeaderType() == 0){return data[9];}
|
||||
return 0;
|
||||
}
|
||||
|
||||
short header::getFMBW(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt16(10);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt16(10);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
short header::getFMBH(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt16(12);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt16(12);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getPICX(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[20];
|
||||
}
|
||||
if (getHeaderType() == 0){return data[20];}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getPICY(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[21];
|
||||
}
|
||||
if (getHeaderType() == 0){return data[21];}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getKFGShift(){
|
||||
if (getHeaderType() == 0){
|
||||
return (getInt16(40) >> 5) & 0x1F;
|
||||
}
|
||||
if (getHeaderType() == 0){return (getInt16(40) >> 5) & 0x1F;}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getFRN(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt32(22);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt32(22);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getPICH(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(17);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt24(17);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getPICW(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(14);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt24(14);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getFRD(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt32(26);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt32(26);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getPARN(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(30);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt24(30);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getPARD(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(33);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt24(33);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getCS(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[36];
|
||||
}
|
||||
if (getHeaderType() == 0){return data[36];}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getNOMBR(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(37);
|
||||
}
|
||||
if (getHeaderType() == 0){return getInt24(37);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getQUAL(){
|
||||
if (getHeaderType() == 0){
|
||||
return (data[40] >> 3) & 0x1F;
|
||||
}
|
||||
if (getHeaderType() == 0){return (data[40] >> 3) & 0x1F;}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getPF(){
|
||||
if (getHeaderType() == 0){
|
||||
return (data[41] >> 3) & 0x03;
|
||||
}
|
||||
if (getHeaderType() == 0){return (data[41] >> 3) & 0x03;}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string header::getVendor(){
|
||||
if (getHeaderType() != 1){
|
||||
return "";
|
||||
}
|
||||
if (getHeaderType() != 1){return "";}
|
||||
return std::string(data + 11, commentLen(7));
|
||||
}
|
||||
|
||||
long unsigned int header::getNComments(){
|
||||
if (getHeaderType() != 1){
|
||||
return 0;
|
||||
}
|
||||
if (getHeaderType() != 1){return 0;}
|
||||
int offset = 11 + commentLen(7);
|
||||
return commentLen(offset);
|
||||
}
|
||||
|
||||
char header::getLFLIMS(size_t index){
|
||||
if (getHeaderType() != 2){
|
||||
return 0;
|
||||
}
|
||||
if (index >= 64){
|
||||
return 0;
|
||||
}
|
||||
if (getHeaderType() != 2){return 0;}
|
||||
if (index >= 64){return 0;}
|
||||
char NBITS = (data[0] >> 5) & 0x07;
|
||||
return NBITS;
|
||||
}
|
||||
|
||||
std::string header::getUserComment(size_t index){
|
||||
if (index >= getNComments()){
|
||||
return "";
|
||||
}
|
||||
if (index >= getNComments()){return "";}
|
||||
int offset = 11 + commentLen(7) + 4;
|
||||
for (size_t i = 0; i < index; i++){
|
||||
offset += 4 + commentLen(offset);
|
||||
}
|
||||
for (size_t i = 0; i < index; i++){offset += 4 + commentLen(offset);}
|
||||
return std::string(data + offset + 4, commentLen(offset));
|
||||
}
|
||||
|
||||
char header::getFTYPE(){
|
||||
return (data[0] >> 6) & 0x01;
|
||||
}
|
||||
char header::getFTYPE(){return (data[0] >> 6) & 0x01;}
|
||||
|
||||
bool header::isHeader(){
|
||||
return ::theora::isHeader(data, datasize);
|
||||
}
|
||||
bool header::isHeader(){return ::theora::isHeader(data, datasize);}
|
||||
|
||||
std::string header::toPrettyString(size_t indent){
|
||||
std::stringstream result;
|
||||
|
@ -282,8 +221,7 @@ namespace theora {
|
|||
result << std::string(indent + 4, ' ') << "[" << i << "] " << getUserComment(i) << std::endl;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
result << std::string(indent + 2, ' ') << "NBITS: " << (int)getLFLIMS(0) << std::endl;
|
||||
case 2: result << std::string(indent + 2, ' ') << "NBITS: " << (int)getLFLIMS(0) << std::endl;
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
@ -357,9 +295,4 @@ namespace theora {
|
|||
result << std::string(indent + 2, ' ') << "FType: " << (int)getFTYPE() << std::endl;
|
||||
return result.str();
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}// namespace theora
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include<sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace theora{
|
||||
|
||||
|
@ -45,6 +45,7 @@ namespace theora {
|
|||
uint32_t getInt24(size_t index);
|
||||
uint16_t getInt16(size_t index);
|
||||
uint32_t commentLen(size_t index);
|
||||
|
||||
private:
|
||||
char *data;
|
||||
bool checkDataSize(unsigned int size);
|
||||
|
@ -64,5 +65,4 @@ namespace theora {
|
|||
unsigned int datasize;
|
||||
bool checkDataSize(unsigned int size);
|
||||
};*/
|
||||
}
|
||||
|
||||
}// namespace theora
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
/// Utilities for handling time and timestamps.
|
||||
|
||||
#include "timing.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <sys/time.h> //for gettimeofday
|
||||
#include <time.h> //for time and nanosleep
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
// emulate clock_gettime() for OSX compatibility
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
|
@ -30,12 +30,8 @@ void clock_gettime(int ign, struct timespec * ts) {
|
|||
/// If interrupted by signal, resumes sleep until at least ms milliseconds have passed.
|
||||
/// Can be slightly off (in positive direction only) depending on OS accuracy.
|
||||
void Util::wait(int64_t ms){
|
||||
if (ms < 0) {
|
||||
return;
|
||||
}
|
||||
if (ms > 600000) {
|
||||
ms = 600000;
|
||||
}
|
||||
if (ms < 0){return;}
|
||||
if (ms > 600000){ms = 600000;}
|
||||
uint64_t start = getMS();
|
||||
uint64_t now = start;
|
||||
while (now < start + ms){
|
||||
|
@ -50,12 +46,8 @@ void Util::wait(int64_t ms){
|
|||
/// Can be interrupted early by a signal, no guarantee of minimum sleep time.
|
||||
/// Can be slightly off depending on OS accuracy.
|
||||
void Util::sleep(int64_t ms){
|
||||
if (ms < 0) {
|
||||
return;
|
||||
}
|
||||
if (ms > 100000) {
|
||||
ms = 100000;
|
||||
}
|
||||
if (ms < 0){return;}
|
||||
if (ms > 100000){ms = 100000;}
|
||||
struct timespec T;
|
||||
T.tv_sec = ms / 1000;
|
||||
T.tv_nsec = 1000000 * (ms % 1000);
|
||||
|
@ -118,6 +110,7 @@ std::string Util::getUTCString(uint64_t epoch){
|
|||
struct tm *ptm;
|
||||
ptm = gmtime(&rawtime);
|
||||
char result[20];
|
||||
snprintf(result, 20, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
|
||||
snprintf(result, 20, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d", ptm->tm_year + 1900, ptm->tm_mon + 1,
|
||||
ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
|
||||
return std::string(result);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Util{
|
||||
void wait(int64_t ms); ///< Sleeps for the indicated amount of milliseconds or longer.
|
||||
|
@ -18,4 +17,4 @@ namespace Util {
|
|||
uint64_t getNTP();
|
||||
uint64_t epoch(); ///< Gets the amount of seconds since 01/01/1970.
|
||||
std::string getUTCString(uint64_t epoch = 0);
|
||||
}
|
||||
}// namespace Util
|
||||
|
|
|
@ -21,17 +21,16 @@ freely, subject to the following restrictions:
|
|||
distribution.
|
||||
*/
|
||||
|
||||
#include <exception>
|
||||
#include "tinythread.h"
|
||||
#include <exception>
|
||||
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <unistd.h>
|
||||
#elif defined(_TTHREAD_WIN32_)
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace tthread{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -78,13 +77,11 @@ namespace tthread {
|
|||
// Check if we are the last waiter
|
||||
EnterCriticalSection(&mWaitersCountLock);
|
||||
--mWaitersCount;
|
||||
bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
|
||||
(mWaitersCount == 0);
|
||||
bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && (mWaitersCount == 0);
|
||||
LeaveCriticalSection(&mWaitersCountLock);
|
||||
|
||||
// If we are the last waiter to be notified to stop waiting, reset the event
|
||||
if (lastWaiter)
|
||||
ResetEvent(mEvents[_CONDITION_EVENT_ALL]);
|
||||
if (lastWaiter) ResetEvent(mEvents[_CONDITION_EVENT_ALL]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -96,8 +93,7 @@ namespace tthread {
|
|||
LeaveCriticalSection(&mWaitersCountLock);
|
||||
|
||||
// If we have any waiting threads, send them a signal
|
||||
if (haveWaiters)
|
||||
SetEvent(mEvents[_CONDITION_EVENT_ONE]);
|
||||
if (haveWaiters) SetEvent(mEvents[_CONDITION_EVENT_ONE]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -109,12 +105,10 @@ namespace tthread {
|
|||
LeaveCriticalSection(&mWaitersCountLock);
|
||||
|
||||
// If we have any waiting threads, send them a signal
|
||||
if (haveWaiters)
|
||||
SetEvent(mEvents[_CONDITION_EVENT_ALL]);
|
||||
if (haveWaiters) SetEvent(mEvents[_CONDITION_EVENT_ALL]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// POSIX pthread_t to unique thread::id mapping logic.
|
||||
// Note: Here we use a global thread safe std::map to convert instances of
|
||||
|
@ -129,13 +123,11 @@ namespace tthread {
|
|||
static unsigned long int idCount(1);
|
||||
|
||||
lock_guard<mutex> guard(idMapLock);
|
||||
if (idMap.find(aHandle) == idMap.end())
|
||||
idMap[aHandle] = idCount ++;
|
||||
if (idMap.find(aHandle) == idMap.end()) idMap[aHandle] = idCount++;
|
||||
return thread::id(idMap[aHandle]);
|
||||
}
|
||||
#endif // _TTHREAD_POSIX_
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// thread
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -200,8 +192,7 @@ namespace tthread {
|
|||
#if defined(_TTHREAD_WIN32_)
|
||||
mHandle = (HANDLE)_beginthreadex(0, 0, wrapper_function, (void *)ti, 0, &mWin32ThreadID);
|
||||
#elif defined(_TTHREAD_POSIX_)
|
||||
if (pthread_create(&mHandle, NULL, wrapper_function, (void *) ti) != 0)
|
||||
mHandle = 0;
|
||||
if (pthread_create(&mHandle, NULL, wrapper_function, (void *)ti) != 0) mHandle = 0;
|
||||
#endif
|
||||
|
||||
// Did we fail to create the thread?
|
||||
|
@ -213,11 +204,8 @@ namespace tthread {
|
|||
}
|
||||
|
||||
thread::~thread(){
|
||||
if (ti_copy) {
|
||||
((_thread_start_info *)ti_copy)->mThread = 0;
|
||||
}
|
||||
if (joinable())
|
||||
std::terminate();
|
||||
if (ti_copy){((_thread_start_info *)ti_copy)->mThread = 0;}
|
||||
if (joinable()) std::terminate();
|
||||
}
|
||||
|
||||
void thread::join(){
|
||||
|
@ -252,8 +240,7 @@ namespace tthread {
|
|||
}
|
||||
|
||||
thread::id thread::get_id() const{
|
||||
if (!joinable())
|
||||
return id();
|
||||
if (!joinable()) return id();
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return id((unsigned long int)mWin32ThreadID);
|
||||
#elif defined(_TTHREAD_POSIX_)
|
||||
|
@ -277,7 +264,6 @@ namespace tthread {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// this_thread
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -290,4 +276,4 @@ namespace tthread {
|
|||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}// namespace tthread
|
||||
|
|
|
@ -78,8 +78,8 @@ freely, subject to the following restrictions:
|
|||
#endif
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
@ -143,7 +143,6 @@ freely, subject to the following restrictions:
|
|||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/// Main name space for TinyThread++.
|
||||
/// This namespace is more or less equivalent to the @c std namespace for the
|
||||
/// C++11 thread classes. For instance, the tthread::mutex class corresponds to
|
||||
|
@ -329,8 +328,7 @@ namespace tthread {
|
|||
///}
|
||||
/// @endcode
|
||||
|
||||
template <class T>
|
||||
class lock_guard {
|
||||
template <class T> class lock_guard{
|
||||
public:
|
||||
typedef T mutex_type;
|
||||
|
||||
|
@ -344,8 +342,7 @@ namespace tthread {
|
|||
|
||||
/// The destructor unlocks the mutex.
|
||||
~lock_guard(){
|
||||
if (mMutex)
|
||||
mMutex->unlock();
|
||||
if (mMutex) mMutex->unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -383,18 +380,14 @@ namespace tthread {
|
|||
#if defined(_TTHREAD_WIN32_)
|
||||
condition_variable();
|
||||
#else
|
||||
condition_variable() {
|
||||
pthread_cond_init(&mHandle, NULL);
|
||||
}
|
||||
condition_variable(){pthread_cond_init(&mHandle, NULL);}
|
||||
#endif
|
||||
|
||||
/// Destructor.
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
~condition_variable();
|
||||
#else
|
||||
~condition_variable() {
|
||||
pthread_cond_destroy(&mHandle);
|
||||
}
|
||||
~condition_variable(){pthread_cond_destroy(&mHandle);}
|
||||
#endif
|
||||
|
||||
/// Wait for the condition.
|
||||
|
@ -402,8 +395,7 @@ namespace tthread {
|
|||
/// is woken by @c notify_one(), @c notify_all() or a spurious wake up.
|
||||
/// @param[in] aMutex A mutex that will be unlocked when the wait operation
|
||||
/// starts, an locked again as soon as the wait operation is finished.
|
||||
template <class _mutexT>
|
||||
inline void wait(_mutexT & aMutex) {
|
||||
template <class _mutexT> inline void wait(_mutexT &aMutex){
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
// Increment number of waiters
|
||||
EnterCriticalSection(&mWaitersCountLock);
|
||||
|
@ -428,9 +420,7 @@ namespace tthread {
|
|||
#if defined(_TTHREAD_WIN32_)
|
||||
void notify_one();
|
||||
#else
|
||||
inline void notify_one() {
|
||||
pthread_cond_signal(&mHandle);
|
||||
}
|
||||
inline void notify_one(){pthread_cond_signal(&mHandle);}
|
||||
#endif
|
||||
|
||||
/// Notify all threads that are waiting for the condition.
|
||||
|
@ -441,9 +431,7 @@ namespace tthread {
|
|||
#if defined(_TTHREAD_WIN32_)
|
||||
void notify_all();
|
||||
#else
|
||||
inline void notify_all() {
|
||||
pthread_cond_broadcast(&mHandle);
|
||||
}
|
||||
inline void notify_all(){pthread_cond_broadcast(&mHandle);}
|
||||
#endif
|
||||
|
||||
_TTHREAD_DISABLE_ASSIGNMENT(condition_variable)
|
||||
|
@ -459,7 +447,6 @@ namespace tthread {
|
|||
#endif
|
||||
};
|
||||
|
||||
|
||||
/// Thread class.
|
||||
class thread{
|
||||
public:
|
||||
|
@ -474,11 +461,14 @@ namespace tthread {
|
|||
/// Default constructor.
|
||||
/// Construct a @c thread object without an associated thread of execution
|
||||
/// (i.e. non-joinable).
|
||||
thread() : mHandle(0), mNotAThread(true)
|
||||
thread()
|
||||
: mHandle(0), mNotAThread(true)
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
, mWin32ThreadID(0)
|
||||
,
|
||||
mWin32ThreadID(0)
|
||||
#endif
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/// Thread starting constructor.
|
||||
/// Construct a @c thread object with a new thread of execution.
|
||||
|
@ -519,9 +509,7 @@ namespace tthread {
|
|||
/// Get the native handle for this thread.
|
||||
/// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this
|
||||
/// is a @c pthread_t.
|
||||
inline native_handle_type native_handle() {
|
||||
return mHandle;
|
||||
}
|
||||
inline native_handle_type native_handle(){return mHandle;}
|
||||
|
||||
/// Determine the number of threads which can possibly execute concurrently.
|
||||
/// This function is useful for determining the optimal number of threads to
|
||||
|
@ -568,29 +556,17 @@ namespace tthread {
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline friend bool operator==(const id & aId1, const id & aId2) {
|
||||
return (aId1.mId == aId2.mId);
|
||||
}
|
||||
inline friend bool operator==(const id &aId1, const id &aId2){return (aId1.mId == aId2.mId);}
|
||||
|
||||
inline friend bool operator!=(const id & aId1, const id & aId2) {
|
||||
return (aId1.mId != aId2.mId);
|
||||
}
|
||||
inline friend bool operator!=(const id &aId1, const id &aId2){return (aId1.mId != aId2.mId);}
|
||||
|
||||
inline friend bool operator<=(const id & aId1, const id & aId2) {
|
||||
return (aId1.mId <= aId2.mId);
|
||||
}
|
||||
inline friend bool operator<=(const id &aId1, const id &aId2){return (aId1.mId <= aId2.mId);}
|
||||
|
||||
inline friend bool operator<(const id & aId1, const id & aId2) {
|
||||
return (aId1.mId < aId2.mId);
|
||||
}
|
||||
inline friend bool operator<(const id &aId1, const id &aId2){return (aId1.mId < aId2.mId);}
|
||||
|
||||
inline friend bool operator>=(const id & aId1, const id & aId2) {
|
||||
return (aId1.mId >= aId2.mId);
|
||||
}
|
||||
inline friend bool operator>=(const id &aId1, const id &aId2){return (aId1.mId >= aId2.mId);}
|
||||
|
||||
inline friend bool operator>(const id & aId1, const id & aId2) {
|
||||
return (aId1.mId > aId2.mId);
|
||||
}
|
||||
inline friend bool operator>(const id &aId1, const id &aId2){return (aId1.mId > aId2.mId);}
|
||||
|
||||
inline friend std::ostream &operator<<(std::ostream &os, const id &obj){
|
||||
os << obj.mId;
|
||||
|
@ -601,7 +577,6 @@ namespace tthread {
|
|||
unsigned long int mId;
|
||||
};
|
||||
|
||||
|
||||
// Related to <ratio> - minimal to be able to support chrono.
|
||||
typedef long long __intmax_t;
|
||||
|
||||
|
@ -609,9 +584,7 @@ namespace tthread {
|
|||
/// functionality to implement some basic @c chrono classes.
|
||||
template <__intmax_t N, __intmax_t D = 1> class ratio{
|
||||
public:
|
||||
static double _as_double() {
|
||||
return double(N) / double(D);
|
||||
}
|
||||
static double _as_double(){return double(N) / double(D);}
|
||||
};
|
||||
|
||||
/// Minimal implementation of the @c chrono namespace.
|
||||
|
@ -622,18 +595,16 @@ namespace tthread {
|
|||
template <class _Rep, class _Period = ratio<1> > class duration{
|
||||
private:
|
||||
_Rep rep_;
|
||||
|
||||
public:
|
||||
typedef _Rep rep;
|
||||
typedef _Period period;
|
||||
|
||||
/// Construct a duration object with the given duration.
|
||||
template <class _Rep2>
|
||||
explicit duration(const _Rep2 & r) : rep_(r) {};
|
||||
template <class _Rep2> explicit duration(const _Rep2 &r) : rep_(r){};
|
||||
|
||||
/// Return the value of the duration object.
|
||||
rep count() const {
|
||||
return rep_;
|
||||
}
|
||||
rep count() const{return rep_;}
|
||||
};
|
||||
|
||||
// Standard duration types.
|
||||
|
@ -643,7 +614,7 @@ namespace tthread {
|
|||
typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds.
|
||||
typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes.
|
||||
typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours.
|
||||
}
|
||||
}// namespace chrono
|
||||
|
||||
/// The namespace @c this_thread provides methods for dealing with the
|
||||
/// calling thread.
|
||||
|
@ -671,16 +642,17 @@ namespace tthread {
|
|||
/// @endcode
|
||||
/// @note Supported duration types are: nanoseconds, microseconds,
|
||||
/// milliseconds, seconds, minutes and hours.
|
||||
template <class _Rep, class _Period> void sleep_for(const chrono::duration<_Rep, _Period> & aTime) {
|
||||
template <class _Rep, class _Period>
|
||||
void sleep_for(const chrono::duration<_Rep, _Period> &aTime){
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5));
|
||||
#else
|
||||
usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}// namespace this_thread
|
||||
|
||||
}
|
||||
}// namespace tthread
|
||||
|
||||
// Define/macro cleanup
|
||||
#undef _TTHREAD_DISABLE_ASSIGNMENT
|
||||
|
|
|
@ -1,31 +1,33 @@
|
|||
/// \page triggers Triggers
|
||||
/// \brief Listing of all available triggers and their payloads.
|
||||
/// MistServer reports certain occurances as configurable triggers to a URL or executable. This page describes the triggers system in full.
|
||||
/// MistServer reports certain occurances as configurable triggers to a URL or executable. This page
|
||||
/// describes the triggers system in full.
|
||||
///
|
||||
/// Triggers are the preferred way of responding to server events. Each trigger has a name and a payload, and may be stream-specific or global.
|
||||
/// Triggers are the preferred way of responding to server events. Each trigger has a name and a
|
||||
/// payload, and may be stream-specific or global.
|
||||
///
|
||||
/// Triggers may be handled by a URL or an executable. If the handler contains ://, a HTTP URL is assumed. Otherwise, an executable is assumed.
|
||||
/// If handled by an URL, a POST request is sent to the URL with an extra X-Trigger header containing the trigger name and the payload as the
|
||||
/// POST body.
|
||||
/// If handled by an executable, it's started with the trigger name as its only argument, and the payload is piped into the executable over
|
||||
/// standard input.
|
||||
/// Triggers may be handled by a URL or an executable. If the handler contains ://, a HTTP URL is
|
||||
/// assumed. Otherwise, an executable is assumed. If handled by an URL, a POST request is sent to
|
||||
/// the URL with an extra X-Trigger header containing the trigger name and the payload as the POST
|
||||
/// body. If handled by an executable, it's started with the trigger name as its only argument, and
|
||||
/// the payload is piped into the executable over standard input.
|
||||
///
|
||||
/// Currently, all triggers are handled asynchronously and responses (if any) are completely ignored. In the future this may change.
|
||||
/// Currently, all triggers are handled asynchronously and responses (if any) are completely
|
||||
/// ignored. In the future this may change.
|
||||
///
|
||||
|
||||
#include "triggers.h"
|
||||
#include "bitfields.h" //for strToBool
|
||||
#include "defines.h" //for FAIL_MSG and INFO_MSG
|
||||
#include "downloader.h" //for sending http request
|
||||
#include "procs.h" //for StartPiped
|
||||
#include "shared_memory.h"
|
||||
#include "util.h"
|
||||
#include "timing.h"
|
||||
#include "triggers.h"
|
||||
#include "util.h"
|
||||
#include <string.h> //for strncmp
|
||||
|
||||
namespace Triggers{
|
||||
|
||||
|
||||
static void submitTriggerStat(const std::string trigger, uint64_t millis, bool ok){
|
||||
JSON::Value j;
|
||||
j["trigger_stat"]["name"] = trigger;
|
||||
|
@ -42,7 +44,8 @@ namespace Triggers{
|
|||
///\param payload This data will be sent to the destionation URL/program
|
||||
///\param sync If true, handler is executed blocking and uses the response data.
|
||||
///\returns String, false if further processing should be aborted.
|
||||
std::string handleTrigger(const std::string &trigger, const std::string &value, const std::string &payload, int sync, const std::string &defaultResponse){
|
||||
std::string handleTrigger(const std::string &trigger, const std::string &value,
|
||||
const std::string &payload, int sync, const std::string &defaultResponse){
|
||||
uint64_t tStartMs = Util::bootMS();
|
||||
if (!value.size()){
|
||||
WARN_MSG("Trigger requested with empty destination");
|
||||
|
@ -58,7 +61,8 @@ namespace Triggers{
|
|||
submitTriggerStat(trigger, tStartMs, true);
|
||||
return DL.data();
|
||||
}
|
||||
FAIL_MSG("Trigger failed to execute (%s), using default response: %s", DL.getStatusText().c_str(), defaultResponse.c_str());
|
||||
FAIL_MSG("Trigger failed to execute (%s), using default response: %s",
|
||||
DL.getStatusText().c_str(), defaultResponse.c_str());
|
||||
submitTriggerStat(trigger, tStartMs, false);
|
||||
return defaultResponse;
|
||||
}else{// send payload to stdin of newly forked process
|
||||
|
@ -90,9 +94,7 @@ namespace Triggers{
|
|||
Util::sleep(100);
|
||||
++counter;
|
||||
if (counter >= 150){
|
||||
if (counter == 150){
|
||||
FAIL_MSG("Trigger taking too long - killing process");
|
||||
}
|
||||
if (counter == 150){FAIL_MSG("Trigger taking too long - killing process");}
|
||||
if (counter >= 250){
|
||||
Util::Procs::Stop(myProc);
|
||||
}else{
|
||||
|
@ -104,7 +106,9 @@ namespace Triggers{
|
|||
FILE *outFile = fdopen(fdOut, "r");
|
||||
char *fileBuf = 0;
|
||||
size_t fileBufLen = 0;
|
||||
while (!(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){ret += fileBuf;}
|
||||
while (!(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){
|
||||
ret += fileBuf;
|
||||
}
|
||||
fclose(outFile);
|
||||
free(fileBuf);
|
||||
close(fdOut);
|
||||
|
@ -124,14 +128,14 @@ namespace Triggers{
|
|||
|
||||
static std::string usually_empty;
|
||||
|
||||
///\brief returns true if a trigger of the specified type should be handled for a specified stream (, or entire server)
|
||||
///\param type Trigger event type.
|
||||
///\param streamName the stream to be handled
|
||||
///\brief returns true if a trigger of the specified type should be handled for a specified stream
|
||||
///(, or entire server) \param type Trigger event type. \param streamName the stream to be handled
|
||||
///\return returns true if so
|
||||
/// calls doTrigger with dryRun set to true
|
||||
/// returns true if a trigger of the specified type should be
|
||||
/// handled for a specified stream (, or entire server)
|
||||
bool shouldTrigger(const std::string & type, const std::string & streamName, bool paramsCB(const char *, const void *), const void * extraParam){
|
||||
bool shouldTrigger(const std::string &type, const std::string &streamName,
|
||||
bool paramsCB(const char *, const void *), const void *extraParam){
|
||||
usually_empty.clear();
|
||||
return doTrigger(type, empty, streamName, true, usually_empty, paramsCB, extraParam);
|
||||
}
|
||||
|
@ -162,7 +166,9 @@ namespace Triggers{
|
|||
/// this can be used to make sure a payload is only generated if at least one trigger should be handled.
|
||||
///-if this function is called with dryRun==false (for example, from one of the overloaded doTrigger functions), handleTrigger is called for
|
||||
/// all configured triggers. In that case, the return value does not matter, it will probably be false in all cases.
|
||||
bool doTrigger(const std::string & type, const std::string &payload, const std::string &streamName, bool dryRun, std::string &response, bool paramsCB(const char *, const void *), const void * extraParam){
|
||||
bool doTrigger(const std::string &type, const std::string &payload, const std::string &streamName,
|
||||
bool dryRun, std::string &response, bool paramsCB(const char *, const void *),
|
||||
const void *extraParam){
|
||||
// open SHM page for this type:
|
||||
char thisPageName[NAME_BUFFER_SIZE];
|
||||
snprintf(thisPageName, NAME_BUFFER_SIZE, SHM_TRIGGER, type.c_str());
|
||||
|
@ -192,15 +198,14 @@ namespace Triggers{
|
|||
while (bPos + 4 < pLen){
|
||||
uint32_t stringLen = ((unsigned int *)(strPtr + bPos))[0];
|
||||
if (bPos + 4 + stringLen > pLen || !stringLen){break;}
|
||||
if ((streamName.size() == stringLen || splitter == stringLen) && strncmp(strPtr+bPos+4, streamName.data(), stringLen) == 0){
|
||||
if ((streamName.size() == stringLen || splitter == stringLen) &&
|
||||
strncmp(strPtr + bPos + 4, streamName.data(), stringLen) == 0){
|
||||
isHandled = true;
|
||||
}
|
||||
bPos += stringLen + 4;
|
||||
}
|
||||
// no streams explicitly defined for this trigger, return true for all streams.
|
||||
if (bPos <= 4){
|
||||
isHandled = true;
|
||||
}
|
||||
if (bPos <= 4){isHandled = true;}
|
||||
|
||||
if (isHandled && paramsCB){
|
||||
isHandled = paramsCB(trigs.getPointer("params", i), extraParam);
|
||||
|
@ -227,5 +232,4 @@ namespace Triggers{
|
|||
return retVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}// namespace Triggers
|
||||
|
|
|
@ -5,11 +5,15 @@ namespace Triggers{
|
|||
|
||||
static const std::string empty;
|
||||
|
||||
bool doTrigger(const std::string & triggerType, const std::string &payload, const std::string &streamName, bool dryRun, std::string &response, bool paramsCB(const char *, const void *) = 0, const void * extraParam = 0);
|
||||
std::string handleTrigger(const std::string &triggerType, const std::string &value, const std::string &payload, int sync, const std::string &defaultResponse);
|
||||
bool doTrigger(const std::string &triggerType, const std::string &payload,
|
||||
const std::string &streamName, bool dryRun, std::string &response,
|
||||
bool paramsCB(const char *, const void *) = 0, const void *extraParam = 0);
|
||||
std::string handleTrigger(const std::string &triggerType, const std::string &value,
|
||||
const std::string &payload, int sync, const std::string &defaultResponse);
|
||||
|
||||
// All of the below are just shorthands for specific usage of the doTrigger function above:
|
||||
bool shouldTrigger(const std::string & triggerType, const std::string &streamName = empty, bool paramsCB(const char *, const void *) = 0, const void * extraParam = 0);
|
||||
bool doTrigger(const std::string & triggerType, const std::string & payload = empty, const std::string & streamName = empty);
|
||||
}
|
||||
|
||||
bool shouldTrigger(const std::string &triggerType, const std::string &streamName = empty,
|
||||
bool paramsCB(const char *, const void *) = 0, const void *extraParam = 0);
|
||||
bool doTrigger(const std::string &triggerType, const std::string &payload = empty,
|
||||
const std::string &streamName = empty);
|
||||
}// namespace Triggers
|
||||
|
|
|
@ -1,24 +1,35 @@
|
|||
/// \file ts_packet.cpp
|
||||
/// Holds all code for the TS namespace.
|
||||
|
||||
#include "util.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <string.h>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include "ts_packet.h"
|
||||
#include "defines.h"
|
||||
#include "bitfields.h"
|
||||
#include "defines.h"
|
||||
#include "ts_packet.h"
|
||||
#include "util.h"
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef FILLER_DATA
|
||||
#define FILLER_DATA "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo vulputate urna eu commodo. Cras tempor velit nec nulla placerat volutpat. Proin eleifend blandit quam sit amet suscipit. Pellentesque vitae tristique lorem. Maecenas facilisis consequat neque, vitae iaculis eros vulputate ut. Suspendisse ut arcu non eros vestibulum pulvinar id sed erat. Nam dictum tellus vel tellus rhoncus ut mollis tellus fermentum. Fusce volutpat consectetur ante, in mollis nisi euismod vulputate. Curabitur vitae facilisis ligula. Sed sed gravida dolor. Integer eu eros a dolor lobortis ullamcorper. Mauris interdum elit non neque interdum dictum. Suspendisse imperdiet eros sed sapien cursus pulvinar. Vestibulum ut dolor lectus, id commodo elit. Cras convallis varius leo eu porta. Duis luctus sapien nec dui adipiscing quis interdum nunc congue. Morbi pharetra aliquet mauris vitae tristique. Etiam feugiat sapien quis augue elementum id ultricies magna vulputate. Phasellus luctus, leo id egestas consequat, eros tortor commodo neque, vitae hendrerit nunc sem ut odio."
|
||||
#define FILLER_DATA \
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo vulputate urna eu " \
|
||||
"commodo. Cras tempor velit nec nulla placerat volutpat. Proin eleifend blandit quam sit amet " \
|
||||
"suscipit. Pellentesque vitae tristique lorem. Maecenas facilisis consequat neque, vitae " \
|
||||
"iaculis eros vulputate ut. Suspendisse ut arcu non eros vestibulum pulvinar id sed erat. Nam " \
|
||||
"dictum tellus vel tellus rhoncus ut mollis tellus fermentum. Fusce volutpat consectetur ante, " \
|
||||
"in mollis nisi euismod vulputate. Curabitur vitae facilisis ligula. Sed sed gravida dolor. " \
|
||||
"Integer eu eros a dolor lobortis ullamcorper. Mauris interdum elit non neque interdum dictum. " \
|
||||
"Suspendisse imperdiet eros sed sapien cursus pulvinar. Vestibulum ut dolor lectus, id commodo " \
|
||||
"elit. Cras convallis varius leo eu porta. Duis luctus sapien nec dui adipiscing quis interdum " \
|
||||
"nunc congue. Morbi pharetra aliquet mauris vitae tristique. Etiam feugiat sapien quis augue " \
|
||||
"elementum id ultricies magna vulputate. Phasellus luctus, leo id egestas consequat, eros " \
|
||||
"tortor commodo neque, vitae hendrerit nunc sem ut odio."
|
||||
#endif
|
||||
|
||||
std::set<unsigned int> pmt_pids;
|
||||
std::map<unsigned int, std::string> stream_pids;
|
||||
|
||||
|
||||
namespace TS{
|
||||
/// This constructor creates an empty Packet, ready for use for either reading or writing.
|
||||
/// All this constructor does is call Packet::clear().
|
||||
|
@ -41,9 +52,7 @@ namespace TS {
|
|||
uint16_t retries = 0;
|
||||
while (retries < 256){
|
||||
if (!fread((void *)strBuf, 188, 1, data)){
|
||||
if (!feof(data)){
|
||||
FAIL_MSG("Could not read 188 bytes from file! %s", strerror(errno));
|
||||
}
|
||||
if (!feof(data)){FAIL_MSG("Could not read 188 bytes from file! %s", strerror(errno));}
|
||||
return false;
|
||||
}
|
||||
if (strBuf[0] == 0x47){
|
||||
|
@ -54,9 +63,7 @@ namespace TS {
|
|||
if (strBuf[i] == 0x47){
|
||||
INFO_MSG("Shifting %u bytes", i);
|
||||
memmove((void *)strBuf, (void *)(strBuf + i), 188 - i);
|
||||
if (!fread((void *)strBuf, i, 1, data)) {
|
||||
return false;
|
||||
}
|
||||
if (!fread((void *)strBuf, i, 1, data)){return false;}
|
||||
pos = 188;
|
||||
return true;
|
||||
}
|
||||
|
@ -67,19 +74,14 @@ namespace TS {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Packet::FromStream(std::istream & data)
|
||||
{
|
||||
bool Packet::FromStream(std::istream &data){
|
||||
long long int bPos = data.tellg();
|
||||
if(!data.read (strBuf,188))
|
||||
{
|
||||
if (!data.eof()){
|
||||
HIGH_MSG("failed to read 188 bytes: %s", strerror(errno));
|
||||
}
|
||||
if (!data.read(strBuf, 188)){
|
||||
if (!data.eof()){HIGH_MSG("failed to read 188 bytes: %s", strerror(errno));}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(strBuf[0] != 0x47)
|
||||
{
|
||||
if (strBuf[0] != 0x47){
|
||||
HIGH_MSG("Failed to read a good packet on pos %lld", bPos);
|
||||
return false;
|
||||
}
|
||||
|
@ -88,7 +90,6 @@ namespace TS {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// This funtion fills a Packet from
|
||||
/// a char array. It fills the content with
|
||||
/// the first 188 characters of a char array
|
||||
|
@ -101,14 +102,11 @@ namespace TS {
|
|||
}
|
||||
|
||||
/// The deconstructor deletes all space that may be occupied by a Packet.
|
||||
Packet::~Packet() {
|
||||
}
|
||||
Packet::~Packet(){}
|
||||
|
||||
/// update position in character array (pos),
|
||||
void Packet::updPos(unsigned int newPos){
|
||||
if(pos < newPos){
|
||||
pos=newPos;
|
||||
}
|
||||
if (pos < newPos){pos = newPos;}
|
||||
}
|
||||
|
||||
/// Sets the PID of a single Packet.
|
||||
|
@ -134,9 +132,7 @@ namespace TS {
|
|||
|
||||
/// Gets the Continuity Counter of a single Packet.
|
||||
/// \return The value of the Continuity Counter.
|
||||
int Packet::getContinuityCounter() const{
|
||||
return (strBuf[3] & 0x0F);
|
||||
}
|
||||
int Packet::getContinuityCounter() const{return (strBuf[3] & 0x0F);}
|
||||
|
||||
/// Gets the amount of bytes that are not written yet in a Packet.
|
||||
/// \return The amount of bytes that can still be written to this packet.
|
||||
|
@ -176,9 +172,7 @@ namespace TS {
|
|||
/// \return The existence of an adaptationfield.
|
||||
/// - 0: No adaptationfield present.
|
||||
/// - 1: Adaptationfield is present.
|
||||
int Packet::getAdaptationField() const{
|
||||
return ((strBuf[3] & 0x30) >> 4);
|
||||
}
|
||||
int Packet::getAdaptationField() const{return ((strBuf[3] & 0x30) >> 4);}
|
||||
|
||||
/// Sets the PCR (Program Clock Reference) of a Packet.
|
||||
/// \param NewVal The new PCR Value.
|
||||
|
@ -200,13 +194,10 @@ namespace TS {
|
|||
/// Gets the PCR (Program Clock Reference) of a Packet.
|
||||
/// \return The value of the PCR.
|
||||
int64_t Packet::getPCR() const{
|
||||
if (!getAdaptationField()) {
|
||||
return -1;
|
||||
}
|
||||
if (!(strBuf[5] & 0x10)) {
|
||||
return -1;
|
||||
}
|
||||
int64_t Result = (((strBuf[6] << 24) | (strBuf[7] << 16) | (strBuf[8] << 8) | strBuf[9]) << 1) | (strBuf[10] >> 7);
|
||||
if (!getAdaptationField()){return -1;}
|
||||
if (!(strBuf[5] & 0x10)){return -1;}
|
||||
int64_t Result = (((strBuf[6] << 24) | (strBuf[7] << 16) | (strBuf[8] << 8) | strBuf[9]) << 1) |
|
||||
(strBuf[10] >> 7);
|
||||
Result *= 300;
|
||||
Result |= (((strBuf[10] & 0x01) << 8) + strBuf[11]);
|
||||
return Result;
|
||||
|
@ -215,14 +206,11 @@ namespace TS {
|
|||
/// Gets the OPCR (Original Program Clock Reference) of a Packet.
|
||||
/// \return The value of the OPCR.
|
||||
int64_t Packet::getOPCR() const{
|
||||
if (!getAdaptationField()) {
|
||||
return -1;
|
||||
}
|
||||
if (!(strBuf[5 + 6] & 0x10)) {
|
||||
return -1;
|
||||
}
|
||||
if (!getAdaptationField()){return -1;}
|
||||
if (!(strBuf[5 + 6] & 0x10)){return -1;}
|
||||
int64_t Result = 0;
|
||||
Result = (((strBuf[6 + 6] << 24) + (strBuf[7 + 6] << 16) + (strBuf[8 + 6] << 8) + strBuf[9 + 6]) << 1) + (strBuf[10 + 6] & 0x80 >> 7);
|
||||
Result = (((strBuf[6 + 6] << 24) + (strBuf[7 + 6] << 16) + (strBuf[8 + 6] << 8) + strBuf[9 + 6]) << 1) +
|
||||
(strBuf[10 + 6] & 0x80 >> 7);
|
||||
Result = Result * 300;
|
||||
Result += (((strBuf[10 + 6] & 0x01) << 8) + strBuf[11 + 6]);
|
||||
return Result;
|
||||
|
@ -230,21 +218,15 @@ namespace TS {
|
|||
|
||||
/// Gets the transport error inficator of a Packet
|
||||
/// \return The transport error inficator of a Packet
|
||||
bool Packet::hasTransportError() const{
|
||||
return strBuf[1] & 0x80;
|
||||
}
|
||||
bool Packet::hasTransportError() const{return strBuf[1] & 0x80;}
|
||||
|
||||
/// Gets the payload unit start inficator of a Packet
|
||||
/// \return The payload unit start inficator of a Packet
|
||||
bool Packet::getUnitStart() const{
|
||||
return strBuf[1] & 0x40;
|
||||
}
|
||||
bool Packet::getUnitStart() const{return strBuf[1] & 0x40;}
|
||||
|
||||
/// Gets the transport priority of a Packet
|
||||
/// \return The transport priority of a Packet
|
||||
bool Packet::hasPriority() const{
|
||||
return strBuf[1] & 0x20;
|
||||
}
|
||||
bool Packet::hasPriority() const{return strBuf[1] & 0x20;}
|
||||
|
||||
/// Gets the transport scrambling control of a Packet
|
||||
/// \return The transport scrambling control of a Packet
|
||||
|
@ -255,24 +237,19 @@ namespace TS {
|
|||
/// Gets the current length of the adaptationfield.
|
||||
/// \return The length of the adaptationfield.
|
||||
int Packet::getAdaptationFieldLen() const{
|
||||
if (!getAdaptationField()) {
|
||||
return -1;
|
||||
}
|
||||
if (!getAdaptationField()){return -1;}
|
||||
return (int)strBuf[4];
|
||||
}
|
||||
|
||||
Packet::operator bool() const{
|
||||
return pos && strBuf[0] == 0x47;
|
||||
}
|
||||
Packet::operator bool() const{return pos && strBuf[0] == 0x47;}
|
||||
|
||||
/// Prints a packet to stdout, for analyser purposes.
|
||||
/// If detail level contains bitmask 64, prints raw bytes after packet.
|
||||
std::string Packet::toPrettyString(size_t indent, int detailLevel) const{
|
||||
if (!(*this)){
|
||||
return "[Invalid packet - no sync byte]";
|
||||
}
|
||||
if (!(*this)){return "[Invalid packet - no sync byte]";}
|
||||
std::stringstream output;
|
||||
output << std::string(indent, ' ') << "[PID " << getPID() << "|" << std::hex << getContinuityCounter() << std::dec << ": " << getDataSize() << "b ";
|
||||
output << std::string(indent, ' ') << "[PID " << getPID() << "|" << std::hex
|
||||
<< getContinuityCounter() << std::dec << ": " << getDataSize() << "b ";
|
||||
switch (getPID()){
|
||||
case 0: output << "PAT"; break;
|
||||
case 1: output << "CAT"; break;
|
||||
|
@ -292,25 +269,13 @@ namespace TS {
|
|||
break;
|
||||
}
|
||||
output << "]";
|
||||
if (getUnitStart()){
|
||||
output << " [Start]";
|
||||
}
|
||||
if (getUnitStart()){output << " [Start]";}
|
||||
if (getAdaptationField() > 1 && getAdaptationFieldLen()){
|
||||
if (hasDiscontinuity()){
|
||||
output << " [Discontinuity]";
|
||||
}
|
||||
if (getRandomAccess()){
|
||||
output << " [RandomXS]";
|
||||
}
|
||||
if (getESPriority()){
|
||||
output << " [ESPriority]";
|
||||
}
|
||||
if (hasPCR()) {
|
||||
output << " [PCR " << (double)getPCR() / 27000000 << "s]";
|
||||
}
|
||||
if (hasOPCR()) {
|
||||
output<< " [OPCR: " << (double)getOPCR() / 27000000 << "s]";
|
||||
}
|
||||
if (hasDiscontinuity()){output << " [Discontinuity]";}
|
||||
if (getRandomAccess()){output << " [RandomXS]";}
|
||||
if (getESPriority()){output << " [ESPriority]";}
|
||||
if (hasPCR()){output << " [PCR " << (double)getPCR() / 27000000 << "s]";}
|
||||
if (hasOPCR()){output << " [OPCR: " << (double)getOPCR() / 27000000 << "s]";}
|
||||
}
|
||||
output << std::endl;
|
||||
if (!getPID()){
|
||||
|
@ -336,13 +301,10 @@ namespace TS {
|
|||
unsigned int size = getDataSize();
|
||||
|
||||
for (unsigned int i = 0; i < size; ++i){
|
||||
if (!(i % 32)){
|
||||
output << std::endl << std::string(indent + 4, ' ');
|
||||
}
|
||||
output << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)(strBuf+188-size)[i] << " ";
|
||||
if ((i % 4) == 3){
|
||||
output << " ";
|
||||
}
|
||||
if (!(i % 32)){output << std::endl << std::string(indent + 4, ' ');}
|
||||
output << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< (unsigned int)(strBuf + 188 - size)[i] << " ";
|
||||
if ((i % 4) == 3){output << " ";}
|
||||
}
|
||||
output << std::endl;
|
||||
}
|
||||
|
@ -356,15 +318,11 @@ namespace TS {
|
|||
|
||||
/// Returns true if this PID contains a PMT.
|
||||
/// Important caveat: only works if the corresponding PAT has been pretty-printed or had parsePIDs() called on it!
|
||||
bool Packet::isPMT() const{
|
||||
return pmt_pids.count(getPID());
|
||||
}
|
||||
bool Packet::isPMT() const{return pmt_pids.count(getPID());}
|
||||
|
||||
/// Returns true if this PID contains a stream known from a PMT.
|
||||
/// Important caveat: only works if the corresponding PMT was pretty-printed or had parseStreams() called on it!
|
||||
bool Packet::isStream() const{
|
||||
return stream_pids.count(getPID());
|
||||
}
|
||||
bool Packet::isStream() const{return stream_pids.count(getPID());}
|
||||
|
||||
/// Sets the start of a new unit in this Packet.
|
||||
/// \param NewVal The new value for the start of a unit.
|
||||
|
@ -376,16 +334,12 @@ namespace TS {
|
|||
}
|
||||
}
|
||||
|
||||
bool Packet::hasDiscontinuity() const{
|
||||
return strBuf[5] & 0x80;
|
||||
}
|
||||
bool Packet::hasDiscontinuity() const{return strBuf[5] & 0x80;}
|
||||
|
||||
void Packet::setDiscontinuity(bool newVal){
|
||||
updPos(6);
|
||||
if (getAdaptationField() == 3){
|
||||
if (!strBuf[4]) {
|
||||
strBuf[4] = 1;
|
||||
}
|
||||
if (!strBuf[4]){strBuf[4] = 1;}
|
||||
if (newVal){
|
||||
strBuf[5] |= 0x80;
|
||||
}else{
|
||||
|
@ -405,47 +359,35 @@ namespace TS {
|
|||
/// Gets whether this Packet can be accessed at random (indicates keyframe).
|
||||
/// \return Whether or not this Packet contains a keyframe.
|
||||
bool Packet::getRandomAccess() const{
|
||||
if (getAdaptationField() < 2) {
|
||||
return false;
|
||||
}
|
||||
if (getAdaptationField() < 2){return false;}
|
||||
return strBuf[5] & 0x40;
|
||||
}
|
||||
|
||||
/// Gets whether this Packet has the priority bit set
|
||||
/// \return Whether or not this Packet has the priority bit set
|
||||
bool Packet::getESPriority() const{
|
||||
if (getAdaptationField() < 2) {
|
||||
return false;
|
||||
}
|
||||
if (getAdaptationField() < 2){return false;}
|
||||
return strBuf[5] & 0x20;
|
||||
}
|
||||
|
||||
/// Gets the value of the PCR flag
|
||||
///\return true if there is a PCR, false otherwise
|
||||
bool Packet::hasPCR() const{
|
||||
return strBuf[5] & 0x10;
|
||||
}
|
||||
bool Packet::hasPCR() const{return strBuf[5] & 0x10;}
|
||||
|
||||
/// Gets the value of the OPCR flag
|
||||
///\return true if there is an OPCR, false otherwise
|
||||
bool Packet::hasOPCR() const{
|
||||
return strBuf[5] & 0x08;
|
||||
}
|
||||
bool Packet::hasOPCR() const{return strBuf[5] & 0x08;}
|
||||
|
||||
/// Gets the value of the splicing point flag
|
||||
///\return the value of the splicing point flag
|
||||
bool Packet::hasSplicingPoint() const{
|
||||
return strBuf[5] & 0x04;
|
||||
}
|
||||
bool Packet::hasSplicingPoint() const{return strBuf[5] & 0x04;}
|
||||
|
||||
/// Gets the value of the transport private data point flag
|
||||
///\return the value of the transport private data point flag
|
||||
void Packet::setRandomAccess(bool NewVal){
|
||||
updPos(6);
|
||||
if (getAdaptationField() == 3){
|
||||
if (!strBuf[4]) {
|
||||
strBuf[4] = 1;
|
||||
}
|
||||
if (!strBuf[4]){strBuf[4] = 1;}
|
||||
if (NewVal){
|
||||
strBuf[5] |= 0x40;
|
||||
}else{
|
||||
|
@ -467,9 +409,7 @@ namespace TS {
|
|||
void Packet::setESPriority(bool NewVal){
|
||||
updPos(6);
|
||||
if (getAdaptationField() == 3){
|
||||
if (!strBuf[4]) {
|
||||
strBuf[4] = 1;
|
||||
}
|
||||
if (!strBuf[4]){strBuf[4] = 1;}
|
||||
if (NewVal){
|
||||
strBuf[5] |= 0x20;
|
||||
}else{
|
||||
|
@ -495,16 +435,13 @@ namespace TS {
|
|||
MyCntr %= 0x10;
|
||||
}
|
||||
|
||||
/// Checks the size of the internal packet buffer (prints error if size !=188), then returns a pointer to the data.
|
||||
/// \return A character pointer to the internal packet buffer data
|
||||
/// Checks the size of the internal packet buffer (prints error if size !=188), then returns a
|
||||
/// pointer to the data. \return A character pointer to the internal packet buffer data
|
||||
const char *Packet::checkAndGetBuffer() const{
|
||||
if (pos != 188) {
|
||||
HIGH_MSG("Size invalid (%d) - invalid data from this point on", pos);
|
||||
}
|
||||
if (pos != 188){HIGH_MSG("Size invalid (%d) - invalid data from this point on", pos);}
|
||||
return strBuf;
|
||||
}
|
||||
|
||||
|
||||
// BEGIN PES FUNCTIONS
|
||||
// pes functons do not use the internal strBuf character buffer
|
||||
///\brief Appends the PES-encoded timestamp to a string.
|
||||
|
@ -528,14 +465,11 @@ namespace TS {
|
|||
/// Prepends the lead-in to variable toSend, assumes toSend's length is all other data.
|
||||
/// \param len The length of this frame.
|
||||
/// \param PTS The timestamp of the frame.
|
||||
std::string & Packet::getPESVideoLeadIn(unsigned int len, unsigned long long PTS, unsigned long long offset, bool isAligned, uint64_t bps) {
|
||||
if (len){
|
||||
len += (offset ? 13 : 8);
|
||||
}
|
||||
std::string &Packet::getPESVideoLeadIn(unsigned int len, unsigned long long PTS,
|
||||
unsigned long long offset, bool isAligned, uint64_t bps){
|
||||
if (len){len += (offset ? 13 : 8);}
|
||||
if (bps >= 50){
|
||||
if (len){
|
||||
len += 3;
|
||||
}
|
||||
if (len){len += 3;}
|
||||
}else{
|
||||
bps = 0;
|
||||
}
|
||||
|
@ -553,9 +487,7 @@ namespace TS {
|
|||
tmpStr += (char)((offset ? 0xC0 : 0x80) | (bps ? 0x10 : 0)); // PTS/DTS + Flags
|
||||
tmpStr += (char)((offset ? 10 : 5) + (bps ? 3 : 0)); // PESHeaderDataLength
|
||||
encodePESTimestamp(tmpStr, (offset ? 0x30 : 0x20), PTS + offset);
|
||||
if (offset){
|
||||
encodePESTimestamp(tmpStr, 0x10, PTS);
|
||||
}
|
||||
if (offset){encodePESTimestamp(tmpStr, 0x10, PTS);}
|
||||
if (bps){
|
||||
char rate_buf[3];
|
||||
Bit::htob24(rate_buf, (bps / 50) | 0x800001);
|
||||
|
@ -611,12 +543,11 @@ namespace TS {
|
|||
/// \return The amount of content bytes that can be send.
|
||||
void Packet::addStuffing(){
|
||||
unsigned int numBytes = getBytesFree();
|
||||
if (!numBytes) {
|
||||
return;
|
||||
}
|
||||
if (!numBytes){return;}
|
||||
|
||||
if (getAdaptationField() == 2){
|
||||
FAIL_MSG("Can not handle adaptation field 2 - should stuff the entire packet, no data will follow after the adaptation field"); ///\todo more stuffing required
|
||||
FAIL_MSG("Can not handle adaptation field 2 - should stuff the entire packet, no data will "
|
||||
"follow after the adaptation field"); ///\todo more stuffing required
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -640,7 +571,8 @@ namespace TS {
|
|||
memset((void *)(strBuf + 5), '$', numBytes);
|
||||
pos += numBytes;
|
||||
}else{
|
||||
memmove((void*)(strBuf+5+strBuf[4]+numBytes), (void*)(strBuf+5+strBuf[4]) , 188-5-strBuf[4]-numBytes);
|
||||
memmove((void *)(strBuf + 5 + strBuf[4] + numBytes), (void *)(strBuf + 5 + strBuf[4]),
|
||||
188 - 5 - strBuf[4] - numBytes);
|
||||
memset((void *)(strBuf + 5 + strBuf[4]), '$', numBytes);
|
||||
pos += numBytes;
|
||||
}
|
||||
|
@ -676,7 +608,6 @@ namespace TS {
|
|||
return 184 - ((getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0));
|
||||
}
|
||||
|
||||
|
||||
ProgramAssociationTable &ProgramAssociationTable::operator=(const Packet &rhs){
|
||||
memcpy(strBuf, rhs.checkAndGetBuffer(), 188);
|
||||
pos = 188;
|
||||
|
@ -737,30 +668,26 @@ namespace TS {
|
|||
}
|
||||
|
||||
short ProgramAssociationTable::getProgramNumber(short index) const{
|
||||
if (index > getProgramCount()) {
|
||||
return 0;
|
||||
}
|
||||
if (index > getProgramCount()){return 0;}
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + 9;
|
||||
return ((short)(strBuf[loc + (index * 4)]) << 8) | strBuf[loc + (index * 4) + 1];
|
||||
}
|
||||
|
||||
short ProgramAssociationTable::getProgramPID(short index) const{
|
||||
if (index > getProgramCount()) {
|
||||
return 0;
|
||||
}
|
||||
if (index > getProgramCount()){return 0;}
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + 9;
|
||||
return (((short)(strBuf[loc + (index * 4) + 2]) << 8) | strBuf[loc + (index * 4) + 3]) & 0x1FFF;
|
||||
}
|
||||
|
||||
int ProgramAssociationTable::getCRC() const{
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + 9 + (getProgramCount() * 4);
|
||||
return ((int)(strBuf[loc]) << 24) | ((int)(strBuf[loc + 1]) << 16) | ((int)(strBuf[loc + 2]) << 8) | strBuf[loc + 3];
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) +
|
||||
getOffset() + 9 + (getProgramCount() * 4);
|
||||
return ((int)(strBuf[loc]) << 24) | ((int)(strBuf[loc + 1]) << 16) |
|
||||
((int)(strBuf[loc + 2]) << 8) | strBuf[loc + 3];
|
||||
}
|
||||
|
||||
void ProgramAssociationTable::parsePIDs(){
|
||||
for (int i = 0; i < getProgramCount(); i++) {
|
||||
pmt_pids.insert(getProgramPID(i));
|
||||
}
|
||||
for (int i = 0; i < getProgramCount(); i++){pmt_pids.insert(getProgramPID(i));}
|
||||
}
|
||||
|
||||
/// This function prints a program association table,
|
||||
|
@ -775,9 +702,11 @@ namespace TS {
|
|||
output << std::string(indent + 2, ' ') << "Sectionlen: " << getSectionLength() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Transport Stream ID: " << getTransportStreamId() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Version Number: " << (int)getVersionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Current/Next Indicator: " << (int)getCurrentNextIndicator() << std::endl;
|
||||
output << std::string(indent + 2, ' ')
|
||||
<< "Current/Next Indicator: " << (int)getCurrentNextIndicator() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Section number: " << (int)getSectionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Last Section number: " << (int)getLastSectionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Last Section number: " << (int)getLastSectionNumber()
|
||||
<< std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Programs [" << (int)getProgramCount() << "]" << std::endl;
|
||||
for (int i = 0; i < getProgramCount(); i++){
|
||||
output << std::string(indent + 4, ' ') << "[" << i + 1 << "] ";
|
||||
|
@ -785,9 +714,9 @@ namespace TS {
|
|||
output << (getProgramNumber(i) == 0 ? "Network" : "Program Map") << " PID: " << getProgramPID(i);
|
||||
output << std::endl;
|
||||
}
|
||||
output << std::string(indent + 2, ' ') << "CRC32: " << std::hex << std::setw(8) << std::setfill('0') << std::uppercase << getCRC() << std::dec << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "CRC32: " << std::hex << std::setw(8)
|
||||
<< std::setfill('0') << std::uppercase << getCRC() << std::dec << std::endl;
|
||||
return output.str();
|
||||
|
||||
}
|
||||
|
||||
ProgramMappingEntry::ProgramMappingEntry(char *begin, char *end){
|
||||
|
@ -795,17 +724,11 @@ namespace TS {
|
|||
boundary = end;
|
||||
}
|
||||
|
||||
ProgramMappingEntry::operator bool() const {
|
||||
return data && (data < boundary);
|
||||
}
|
||||
ProgramMappingEntry::operator bool() const{return data && (data < boundary);}
|
||||
|
||||
int ProgramMappingEntry::getStreamType() const{
|
||||
return data[0];
|
||||
}
|
||||
int ProgramMappingEntry::getStreamType() const{return data[0];}
|
||||
|
||||
void ProgramMappingEntry::setStreamType(int newType){
|
||||
data[0] = newType;
|
||||
}
|
||||
void ProgramMappingEntry::setStreamType(int newType){data[0] = newType;}
|
||||
|
||||
std::string ProgramMappingEntry::getCodec() const{
|
||||
switch (getStreamType()){
|
||||
|
@ -855,22 +778,16 @@ namespace TS {
|
|||
}
|
||||
}
|
||||
|
||||
int ProgramMappingEntry::getElementaryPid() const{
|
||||
return ((data[1] << 8) | data[2]) & 0x1FFF;
|
||||
}
|
||||
int ProgramMappingEntry::getElementaryPid() const{return ((data[1] << 8) | data[2]) & 0x1FFF;}
|
||||
|
||||
void ProgramMappingEntry::setElementaryPid(int newElementaryPid){
|
||||
data[1] = (newElementaryPid >> 8 & 0x1F) | 0xE0; // 0xE0 = three reserved bits
|
||||
data[2] = newElementaryPid & 0xFF;
|
||||
}
|
||||
|
||||
int ProgramMappingEntry::getESInfoLength() const{
|
||||
return ((data[3] << 8) | data[4]) & 0x0FFF;
|
||||
}
|
||||
int ProgramMappingEntry::getESInfoLength() const{return ((data[3] << 8) | data[4]) & 0x0FFF;}
|
||||
|
||||
const char * ProgramMappingEntry::getESInfo() const{
|
||||
return data + 5;
|
||||
}
|
||||
const char *ProgramMappingEntry::getESInfo() const{return data + 5;}
|
||||
|
||||
void ProgramMappingEntry::setESInfo(const std::string &newInfo){
|
||||
data[3] = ((newInfo.size() >> 8) & 0x0F) | 0xF0; // 0xF0 = four reserved bits
|
||||
|
@ -879,9 +796,7 @@ namespace TS {
|
|||
}
|
||||
|
||||
void ProgramMappingEntry::advance(){
|
||||
if (!(*this)) {
|
||||
return;
|
||||
}
|
||||
if (!(*this)){return;}
|
||||
data += 5 + getESInfoLength();
|
||||
}
|
||||
|
||||
|
@ -1020,22 +935,25 @@ namespace TS {
|
|||
|
||||
ProgramMappingEntry ProgramMappingTable::getEntry(int index) const{
|
||||
int dataOffset = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset();
|
||||
ProgramMappingEntry res((char*)(strBuf + dataOffset + 13 + getProgramInfoLength()), (char*)(strBuf + dataOffset + getSectionLength()) );
|
||||
for (int i = 0; i < index; i++){
|
||||
res.advance();
|
||||
}
|
||||
ProgramMappingEntry res((char *)(strBuf + dataOffset + 13 + getProgramInfoLength()),
|
||||
(char *)(strBuf + dataOffset + getSectionLength()));
|
||||
for (int i = 0; i < index; i++){res.advance();}
|
||||
return res;
|
||||
}
|
||||
|
||||
int ProgramMappingTable::getCRC() const{
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + getSectionLength();
|
||||
return ((int)(strBuf[loc]) << 24) | ((int)(strBuf[loc + 1]) << 16) | ((int)(strBuf[loc + 2]) << 8) | strBuf[loc + 3];
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) +
|
||||
getOffset() + getSectionLength();
|
||||
return ((int)(strBuf[loc]) << 24) | ((int)(strBuf[loc + 1]) << 16) |
|
||||
((int)(strBuf[loc + 2]) << 8) | strBuf[loc + 3];
|
||||
}
|
||||
|
||||
void ProgramMappingTable::calcCRC(){
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + getSectionLength();
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) +
|
||||
getOffset() + getSectionLength();
|
||||
unsigned int newVal; // this will hold the CRC32 value;
|
||||
unsigned int pidLoc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + 1;//location of PCRPID
|
||||
unsigned int pidLoc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) +
|
||||
getOffset() + 1; // location of PCRPID
|
||||
newVal = checksum::crc32(-1, strBuf + pidLoc, loc - pidLoc); // calculating checksum over all the fields from table ID to the last stream element
|
||||
updPos(188);
|
||||
strBuf[loc + 3] = (newVal >> 24) & 0xFF;
|
||||
|
@ -1049,7 +967,8 @@ namespace TS {
|
|||
void ProgramMappingTable::parseStreams(){
|
||||
ProgramMappingEntry entry = getEntry(0);
|
||||
while (entry){
|
||||
stream_pids[entry.getElementaryPid()] = entry.getCodec() + std::string(" ") + entry.getStreamTypeString();
|
||||
stream_pids[entry.getElementaryPid()] =
|
||||
entry.getCodec() + std::string(" ") + entry.getStreamTypeString();
|
||||
entry.advance();
|
||||
}
|
||||
}
|
||||
|
@ -1065,25 +984,30 @@ namespace TS {
|
|||
output << std::string(indent + 2, ' ') << "Section Length: " << getSectionLength() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Program number: " << getProgramNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Version number: " << (int)getVersionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Current next indicator: " << (int)getCurrentNextIndicator() << std::endl;
|
||||
output << std::string(indent + 2, ' ')
|
||||
<< "Current next indicator: " << (int)getCurrentNextIndicator() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Section number: " << (int)getSectionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Last Section number: " << (int)getLastSectionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Last Section number: " << (int)getLastSectionNumber()
|
||||
<< std::endl;
|
||||
output << std::string(indent + 2, ' ') << "PCR PID: " << getPCRPID() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Program Info Length: " << getProgramInfoLength() << std::endl;
|
||||
ProgramMappingEntry entry = getEntry(0);
|
||||
while (entry){
|
||||
output << std::string(indent + 4, ' ');
|
||||
stream_pids[entry.getElementaryPid()] = entry.getCodec() + std::string(" ") + entry.getStreamTypeString();
|
||||
output << "Stream " << entry.getElementaryPid() << ": " << stream_pids[entry.getElementaryPid()] << " (" << entry.getStreamType() << ")" << std::endl;
|
||||
stream_pids[entry.getElementaryPid()] =
|
||||
entry.getCodec() + std::string(" ") + entry.getStreamTypeString();
|
||||
output << "Stream " << entry.getElementaryPid() << ": " << stream_pids[entry.getElementaryPid()]
|
||||
<< " (" << entry.getStreamType() << ")" << std::endl;
|
||||
output << ProgramDescriptors(entry.getESInfo(), entry.getESInfoLength()).toPrettyString(indent + 6);
|
||||
entry.advance();
|
||||
}
|
||||
output << std::string(indent + 2, ' ') << "CRC32: " << std::hex << std::setw(8) << std::setfill('0') << std::uppercase << getCRC() << std::dec << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "CRC32: " << std::hex << std::setw(8)
|
||||
<< std::setfill('0') << std::uppercase << getCRC() << std::dec << std::endl;
|
||||
return output.str();
|
||||
}
|
||||
|
||||
ProgramDescriptors::ProgramDescriptors(const char * data, const uint32_t len) : p_data(data), p_len(len){
|
||||
}
|
||||
ProgramDescriptors::ProgramDescriptors(const char *data, const uint32_t len)
|
||||
: p_data(data), p_len(len){}
|
||||
|
||||
/// Returns the ISO-629 language code, or "und" if unknown.
|
||||
std::string ProgramDescriptors::getLanguage() const{
|
||||
|
@ -1145,16 +1069,20 @@ namespace TS {
|
|||
case 0x61: output << "AAC-HEv2, level 3"; break;
|
||||
case 0x62: output << "AAC-HEv2, level 4"; break;
|
||||
case 0x63: output << "AAC-HEv2, level 5"; break;
|
||||
default: output << std::hex << std::setw(2) << std::setfill('0') << std::uppercase << (int)p_data[p+2] << std::dec;
|
||||
default:
|
||||
output << std::hex << std::setw(2) << std::setfill('0') << std::uppercase
|
||||
<< (int)p_data[p + 2] << std::dec;
|
||||
}
|
||||
if (p_data[p + 3] & 0x80){
|
||||
output << ", type: " << std::hex << std::setw(2) << std::setfill('0') << std::uppercase << (int)p_data[p+3] << std::dec;
|
||||
output << ", type: " << std::hex << std::setw(2) << std::setfill('0') << std::uppercase
|
||||
<< (int)p_data[p + 3] << std::dec;
|
||||
}
|
||||
output << std::endl;
|
||||
if (p_data[p + 1] > 2){
|
||||
output << std::string(indent + 2, ' ') << "Extra data: ";
|
||||
for (uint32_t offset = 2; p + 2 + offset < p_data[p + 1]; ++offset){
|
||||
output << std::hex << std::setw(2) << std::setfill('0') << std::uppercase << (int)p_data[p+2+offset] << std::dec;
|
||||
output << std::hex << std::setw(2) << std::setfill('0') << std::uppercase
|
||||
<< (int)p_data[p + 2 + offset] << std::dec;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
@ -1164,7 +1092,8 @@ namespace TS {
|
|||
default:{
|
||||
output << std::string(indent, ' ') << "Undecoded descriptor: ";
|
||||
for (uint32_t i = 0; i < p_data[p + 1] + 2; ++i){
|
||||
output << std::hex << std::setw(2) << std::setfill('0') << std::uppercase << (int)p_data[p+i] << std::dec;
|
||||
output << std::hex << std::setw(2) << std::setfill('0') << std::uppercase
|
||||
<< (int)p_data[p + i] << std::dec;
|
||||
}
|
||||
output << std::endl;
|
||||
}
|
||||
|
@ -1187,9 +1116,7 @@ namespace TS {
|
|||
int sectionLen = 0;
|
||||
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
||||
sectionLen += 5;
|
||||
if (myMeta.tracks[*it].codec == "ID3"){
|
||||
sectionLen += myMeta.tracks[*it].init.size();
|
||||
}
|
||||
if (myMeta.tracks[*it].codec == "ID3"){sectionLen += myMeta.tracks[*it].init.size();}
|
||||
if (myMeta.tracks[*it].codec == "AAC"){
|
||||
sectionLen += 4; // aac descriptor
|
||||
if (myMeta.tracks[*it].lang.size() == 3 && myMeta.tracks[*it].lang != "und"){
|
||||
|
@ -1211,9 +1138,7 @@ namespace TS {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (vidTrack == -1){
|
||||
vidTrack = *(selectedTracks.begin());
|
||||
}
|
||||
if (vidTrack == -1){vidTrack = *(selectedTracks.begin());}
|
||||
PMT.setPCRPID(255 + vidTrack);
|
||||
PMT.setProgramInfoLength(0);
|
||||
short id = 0;
|
||||
|
@ -1251,51 +1176,32 @@ namespace TS {
|
|||
return PMT.checkAndGetBuffer();
|
||||
}
|
||||
|
||||
|
||||
ServiceDescriptionEntry::ServiceDescriptionEntry(char *begin, char *end){
|
||||
data = begin;
|
||||
boundary = end;
|
||||
}
|
||||
|
||||
ServiceDescriptionEntry::operator bool() const {
|
||||
return data && (data < boundary);
|
||||
}
|
||||
ServiceDescriptionEntry::operator bool() const{return data && (data < boundary);}
|
||||
|
||||
uint16_t ServiceDescriptionEntry::getServiceID() const{
|
||||
return Bit::btohs(data);
|
||||
}
|
||||
uint16_t ServiceDescriptionEntry::getServiceID() const{return Bit::btohs(data);}
|
||||
|
||||
void ServiceDescriptionEntry::setServiceID(uint16_t val){
|
||||
Bit::htobs(data, val);
|
||||
}
|
||||
void ServiceDescriptionEntry::setServiceID(uint16_t val){Bit::htobs(data, val);}
|
||||
|
||||
bool ServiceDescriptionEntry::getEITSchedule() const{
|
||||
return data[2] & 2;
|
||||
}
|
||||
bool ServiceDescriptionEntry::getEITSchedule() const{return data[2] & 2;}
|
||||
|
||||
void ServiceDescriptionEntry::setEITSchedule(bool val){
|
||||
data[2] |= 2;
|
||||
}
|
||||
void ServiceDescriptionEntry::setEITSchedule(bool val){data[2] |= 2;}
|
||||
|
||||
bool ServiceDescriptionEntry::getEITPresentFollowing() const{
|
||||
return data[2] & 1;
|
||||
}
|
||||
bool ServiceDescriptionEntry::getEITPresentFollowing() const{return data[2] & 1;}
|
||||
|
||||
void ServiceDescriptionEntry::setEITPresentFollowing(bool val){
|
||||
data[2] |= 1;
|
||||
}
|
||||
void ServiceDescriptionEntry::setEITPresentFollowing(bool val){data[2] |= 1;}
|
||||
|
||||
uint8_t ServiceDescriptionEntry::getRunningStatus() const{
|
||||
return (data[3] & 0xE0) >> 5;
|
||||
}
|
||||
uint8_t ServiceDescriptionEntry::getRunningStatus() const{return (data[3] & 0xE0) >> 5;}
|
||||
|
||||
void ServiceDescriptionEntry::setRunningStatus(uint8_t val){
|
||||
data[3] = (data[3] & 0x1F) | (val << 5);
|
||||
}
|
||||
|
||||
bool ServiceDescriptionEntry::getFreeCAM() const{
|
||||
return data[3] & 0x10;
|
||||
}
|
||||
bool ServiceDescriptionEntry::getFreeCAM() const{return data[3] & 0x10;}
|
||||
|
||||
void ServiceDescriptionEntry::setFreeCAM(bool val){
|
||||
data[3] = (data[3] & 0xEF) | (val ? 0x10 : 0);
|
||||
|
@ -1305,9 +1211,7 @@ namespace TS {
|
|||
return ((data[3] << 8) | data[4]) & 0x0FFF;
|
||||
}
|
||||
|
||||
const char * ServiceDescriptionEntry::getESInfo() const{
|
||||
return data + 5;
|
||||
}
|
||||
const char *ServiceDescriptionEntry::getESInfo() const{return data + 5;}
|
||||
|
||||
void ServiceDescriptionEntry::setESInfo(const std::string &newInfo){
|
||||
data[3] = ((newInfo.size() >> 8) & 0x0F) | (data[3] & 0xF0);
|
||||
|
@ -1316,9 +1220,7 @@ namespace TS {
|
|||
}
|
||||
|
||||
void ServiceDescriptionEntry::advance(){
|
||||
if (!(*this)) {
|
||||
return;
|
||||
}
|
||||
if (!(*this)){return;}
|
||||
data += 5 + getESInfoLength();
|
||||
}
|
||||
|
||||
|
@ -1445,20 +1347,22 @@ namespace TS {
|
|||
|
||||
ServiceDescriptionEntry ServiceDescriptionTable::getEntry(int index) const{
|
||||
int dataOffset = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset();
|
||||
ServiceDescriptionEntry res((char*)(strBuf + dataOffset + 12), (char*)(strBuf + dataOffset + getSectionLength()) );
|
||||
for (int i = 0; i < index; i++){
|
||||
res.advance();
|
||||
}
|
||||
ServiceDescriptionEntry res((char *)(strBuf + dataOffset + 12),
|
||||
(char *)(strBuf + dataOffset + getSectionLength()));
|
||||
for (int i = 0; i < index; i++){res.advance();}
|
||||
return res;
|
||||
}
|
||||
|
||||
int ServiceDescriptionTable::getCRC() const{
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + getSectionLength();
|
||||
return ((int)(strBuf[loc]) << 24) | ((int)(strBuf[loc + 1]) << 16) | ((int)(strBuf[loc + 2]) << 8) | strBuf[loc + 3];
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) +
|
||||
getOffset() + getSectionLength();
|
||||
return ((int)(strBuf[loc]) << 24) | ((int)(strBuf[loc + 1]) << 16) |
|
||||
((int)(strBuf[loc + 2]) << 8) | strBuf[loc + 3];
|
||||
}
|
||||
|
||||
void ServiceDescriptionTable::calcCRC(){
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + getSectionLength();
|
||||
unsigned int loc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) +
|
||||
getOffset() + getSectionLength();
|
||||
unsigned int newVal; // this will hold the CRC32 value;
|
||||
unsigned int pidLoc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + 1;
|
||||
newVal = checksum::crc32(-1, strBuf + pidLoc, loc - pidLoc); // calculating checksum over all the fields from table ID to the last stream element
|
||||
|
@ -1481,9 +1385,11 @@ namespace TS {
|
|||
output << std::string(indent + 2, ' ') << "Section Length: " << getSectionLength() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "TS Stream ID: " << getTSStreamID() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Version number: " << (int)getVersionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Current next indicator: " << (int)getCurrentNextIndicator() << std::endl;
|
||||
output << std::string(indent + 2, ' ')
|
||||
<< "Current next indicator: " << (int)getCurrentNextIndicator() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Section number: " << (int)getSectionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Last Section number: " << (int)getLastSectionNumber() << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Last Section number: " << (int)getLastSectionNumber()
|
||||
<< std::endl;
|
||||
output << std::string(indent + 2, ' ') << "Original Network ID: " << getOrigID() << std::endl;
|
||||
ServiceDescriptionEntry entry = getEntry(0);
|
||||
while (entry){
|
||||
|
@ -1506,7 +1412,8 @@ namespace TS {
|
|||
output << ProgramDescriptors(entry.getESInfo(), entry.getESInfoLength()).toPrettyString(indent + 6);
|
||||
entry.advance();
|
||||
}
|
||||
output << std::string(indent + 2, ' ') << "CRC32: " << std::hex << std::setw(8) << std::setfill('0') << std::uppercase << getCRC() << std::dec << std::endl;
|
||||
output << std::string(indent + 2, ' ') << "CRC32: " << std::hex << std::setw(8)
|
||||
<< std::setfill('0') << std::uppercase << getCRC() << std::dec << std::endl;
|
||||
return output.str();
|
||||
}
|
||||
|
||||
|
@ -1542,7 +1449,4 @@ namespace TS {
|
|||
return SDT.checkAndGetBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}// namespace TS
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue