Merge branch 'development' into LTS_development
# Conflicts: # lib/h264.cpp
This commit is contained in:
commit
5c8ebdc5ec
11 changed files with 111 additions and 36 deletions
|
@ -102,6 +102,16 @@ namespace Encodings {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decodes a hex-encoded std::string to a raw binary std::string.
|
||||||
|
std::string Hex::decode(const std::string & in){
|
||||||
|
std::string ret(in.size()/2, '\000');
|
||||||
|
for (size_t i = 0; i < in.size(); ++i){
|
||||||
|
char c = in[i];
|
||||||
|
ret[i>>1] |= ((c&15) + (((c&64)>>6) | ((c&64)>>3))) << ((~i&1) << 2);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/// urlencodes std::string data, leaving only the characters A-Za-z0-9~!&()' alone.
|
/// urlencodes std::string data, leaving only the characters A-Za-z0-9~!&()' alone.
|
||||||
std::string URL::encode(const std::string & c){
|
std::string URL::encode(const std::string & c){
|
||||||
std::string escaped = "";
|
std::string escaped = "";
|
||||||
|
|
|
@ -33,6 +33,9 @@ namespace Encodings {
|
||||||
}
|
}
|
||||||
/// Encodes a single character as two hex digits in string form.
|
/// Encodes a single character as two hex digits in string form.
|
||||||
static std::string chr(char dec);
|
static std::string chr(char dec);
|
||||||
|
|
||||||
|
/// Decodes a hex-encoded std::string to a raw binary std::string.
|
||||||
|
static std::string decode(const std::string & in);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
32
lib/h264.cpp
32
lib/h264.cpp
|
@ -102,13 +102,13 @@ namespace h264 {
|
||||||
|
|
||||||
SPSMeta sequenceParameterSet::getCharacteristics() const {
|
SPSMeta sequenceParameterSet::getCharacteristics() const {
|
||||||
SPSMeta result;
|
SPSMeta result;
|
||||||
|
result.sep_col_plane = false;
|
||||||
|
|
||||||
//For calculating width
|
//For calculating width
|
||||||
unsigned int widthInMbs = 0;
|
unsigned int widthInMbs = 0;
|
||||||
unsigned int cropHorizontal = 0;
|
unsigned int cropHorizontal = 0;
|
||||||
|
|
||||||
//For calculating height
|
//For calculating height
|
||||||
bool mbsOnlyFlag = 0;
|
|
||||||
unsigned int heightInMapUnits = 0;
|
unsigned int heightInMapUnits = 0;
|
||||||
unsigned int cropVertical = 0;
|
unsigned int cropVertical = 0;
|
||||||
|
|
||||||
|
@ -135,11 +135,11 @@ namespace h264 {
|
||||||
//chroma format idc
|
//chroma format idc
|
||||||
char chromaFormatIdc = bs.getUExpGolomb();
|
char chromaFormatIdc = bs.getUExpGolomb();
|
||||||
if (chromaFormatIdc == 3) {
|
if (chromaFormatIdc == 3) {
|
||||||
bs.skip(1);
|
result.sep_col_plane = (bs.get(1) == 1);
|
||||||
}
|
}
|
||||||
bs.getUExpGolomb();
|
bs.getUExpGolomb();//luma
|
||||||
bs.getUExpGolomb();
|
bs.getUExpGolomb();//chroma
|
||||||
bs.skip(1);
|
bs.skip(1);//transform bypass
|
||||||
if (bs.get(1)) {//Scaling matrix is present
|
if (bs.get(1)) {//Scaling matrix is present
|
||||||
char listSize = (chromaFormatIdc == 3 ? 12 : 8);
|
char listSize = (chromaFormatIdc == 3 ? 12 : 8);
|
||||||
for (size_t i = 0; i < listSize; i++){
|
for (size_t i = 0; i < listSize; i++){
|
||||||
|
@ -154,23 +154,23 @@ namespace h264 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bs.getUExpGolomb();
|
result.log2_max_frame_num = bs.getUExpGolomb() + 4;
|
||||||
unsigned int pic_order_cnt_type = bs.getUExpGolomb();
|
result.cnt_type = bs.getUExpGolomb();
|
||||||
if (!pic_order_cnt_type) {
|
if (!result.cnt_type) {
|
||||||
bs.getUExpGolomb();
|
result.log2_max_order_cnt = bs.getUExpGolomb() + 4;
|
||||||
} else if (pic_order_cnt_type == 1) {
|
} else if (result.cnt_type == 1) {
|
||||||
DEBUG_MSG(DLVL_DEVEL, "This part of the implementation is incomplete(2), to be continued. If this message is shown, contact developers immediately.");
|
DEBUG_MSG(DLVL_DEVEL, "This part of the implementation is incomplete(2), to be continued. If this message is shown, contact developers immediately.");
|
||||||
}
|
}
|
||||||
bs.getUExpGolomb();
|
result.max_ref_frames = bs.getUExpGolomb();//max_num_ref_frames
|
||||||
bs.skip(1);
|
result.gaps = (bs.get(1) == 1);//gaps in frame num allowed
|
||||||
//Stop skipping data and start doing usefull stuff
|
//Stop skipping data and start doing useful stuff
|
||||||
|
|
||||||
|
|
||||||
widthInMbs = bs.getUExpGolomb() + 1;
|
widthInMbs = bs.getUExpGolomb() + 1;
|
||||||
heightInMapUnits = bs.getUExpGolomb() + 1;
|
heightInMapUnits = bs.getUExpGolomb() + 1;
|
||||||
|
|
||||||
mbsOnlyFlag = bs.get(1);//Gets used in height calculation
|
result.mbs_only = (bs.get(1) == 1);//Gets used in height calculation
|
||||||
if (!mbsOnlyFlag) {
|
if (!result.mbs_only) {
|
||||||
bs.skip(1);
|
bs.skip(1);
|
||||||
}
|
}
|
||||||
bs.skip(1);
|
bs.skip(1);
|
||||||
|
@ -214,7 +214,7 @@ namespace h264 {
|
||||||
}
|
}
|
||||||
|
|
||||||
result.width = (widthInMbs * 16) - (cropHorizontal * 2);
|
result.width = (widthInMbs * 16) - (cropHorizontal * 2);
|
||||||
result.height = ((mbsOnlyFlag ? 1 : 2) * heightInMapUnits * 16) - (cropVertical * 2);
|
result.height = ((result.mbs_only ? 1 : 2) * heightInMapUnits * 16) - (cropVertical * 2);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,13 @@ namespace h264 {
|
||||||
double fps;
|
double fps;
|
||||||
uint8_t profile;
|
uint8_t profile;
|
||||||
uint8_t level;
|
uint8_t level;
|
||||||
|
bool sep_col_plane;
|
||||||
|
uint8_t cnt_type;
|
||||||
|
bool gaps;///< Gaps in frame num allowed flag
|
||||||
|
bool mbs_only;///<MBS only flag
|
||||||
|
uint16_t log2_max_frame_num;
|
||||||
|
uint16_t log2_max_order_cnt;
|
||||||
|
uint16_t max_ref_frames;///<Maximum number of reference frames
|
||||||
};
|
};
|
||||||
|
|
||||||
///Class for analyzing generic nal units
|
///Class for analyzing generic nal units
|
||||||
|
|
|
@ -305,12 +305,28 @@ std::string HTTP::Parser::getUrl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns header i, if set.
|
/// Returns header i, if set.
|
||||||
std::string HTTP::Parser::GetHeader(std::string i) {
|
const std::string & HTTP::Parser::GetHeader(const std::string & i) const {
|
||||||
return headers[i];
|
if (headers.count(i)){
|
||||||
|
return headers.at(i);
|
||||||
|
}else{
|
||||||
|
static const std::string empty;
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns header i, if set.
|
||||||
|
bool HTTP::Parser::hasHeader(const std::string & i) const {
|
||||||
|
return headers.count(i);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns POST variable i, if set.
|
/// Returns POST variable i, if set.
|
||||||
std::string HTTP::Parser::GetVar(std::string i) {
|
const std::string & HTTP::Parser::GetVar(const std::string & i) const {
|
||||||
return vars[i];
|
if (vars.count(i)){
|
||||||
|
return vars.at(i);
|
||||||
|
}else{
|
||||||
|
static const std::string empty;
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HTTP::Parser::allVars(){
|
std::string HTTP::Parser::allVars(){
|
||||||
|
|
|
@ -16,9 +16,10 @@ namespace HTTP {
|
||||||
Parser();
|
Parser();
|
||||||
bool Read(Socket::Connection & conn);
|
bool Read(Socket::Connection & conn);
|
||||||
bool Read(std::string & strbuf);
|
bool Read(std::string & strbuf);
|
||||||
std::string GetHeader(std::string i);
|
const std::string & GetHeader(const std::string & i) const;
|
||||||
|
bool hasHeader(const std::string & i) const;
|
||||||
void clearHeader(const std::string & i);
|
void clearHeader(const std::string & i);
|
||||||
std::string GetVar(std::string i);
|
const std::string & GetVar(const std::string & i) const;
|
||||||
std::string getUrl();
|
std::string getUrl();
|
||||||
std::string allVars();
|
std::string allVars();
|
||||||
void SetHeader(std::string i, std::string v);
|
void SetHeader(std::string i, std::string v);
|
||||||
|
|
|
@ -1029,8 +1029,12 @@ Socket::UDPConnection::UDPConnection(const UDPConnection & o) {
|
||||||
destAddr = 0;
|
destAddr = 0;
|
||||||
destAddr_size = 0;
|
destAddr_size = 0;
|
||||||
}
|
}
|
||||||
data = 0;
|
data = (char*)malloc(1024);
|
||||||
data_size = 0;
|
if (data){
|
||||||
|
data_size = 1024;
|
||||||
|
}else{
|
||||||
|
data_size = 0;
|
||||||
|
}
|
||||||
data_len = 0;
|
data_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,6 +1113,19 @@ void Socket::UDPConnection::GetDestination(std::string & destIp, uint32_t & port
|
||||||
DEBUG_MSG(DLVL_FAIL, "Could not get destination for UDP socket");
|
DEBUG_MSG(DLVL_FAIL, "Could not get destination for UDP socket");
|
||||||
}//Socket::UDPConnection GetDestination
|
}//Socket::UDPConnection GetDestination
|
||||||
|
|
||||||
|
/// Returns the port number of the receiving end of this socket.
|
||||||
|
/// Returns 0 on error.
|
||||||
|
uint32_t Socket::UDPConnection::getDestPort() const{
|
||||||
|
if (!destAddr || !destAddr_size){return 0;}
|
||||||
|
if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET6) {
|
||||||
|
return ntohs(((struct sockaddr_in6 *)destAddr)->sin6_port);
|
||||||
|
}
|
||||||
|
if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET) {
|
||||||
|
return ntohs(((struct sockaddr_in *)destAddr)->sin_port);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the socket to be blocking if the parameters is true.
|
/// Sets the socket to be blocking if the parameters is true.
|
||||||
/// Sets the socket to be non-blocking otherwise.
|
/// Sets the socket to be non-blocking otherwise.
|
||||||
void Socket::UDPConnection::setBlocking(bool blocking) {
|
void Socket::UDPConnection::setBlocking(bool blocking) {
|
||||||
|
@ -1220,20 +1237,22 @@ bool Socket::UDPConnection::Receive() {
|
||||||
data_size = SOCKETSIZE;
|
data_size = SOCKETSIZE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
int r = recvfrom(sock, data, data_size, MSG_PEEK | MSG_TRUNC, 0, 0);
|
int r = recvfrom(sock, data, data_size, MSG_PEEK | MSG_TRUNC | MSG_DONTWAIT, 0, 0);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN) {
|
||||||
INFO_MSG("Found an error: %d (%s)", errno, strerror(errno));
|
INFO_MSG("UDP receive: %d (%s)", errno, strerror(errno));
|
||||||
}
|
}
|
||||||
data_len = 0;
|
data_len = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (data_size < (unsigned int)r) {
|
if (data_size < (unsigned int)r) {
|
||||||
data = (char *)realloc(data, r);
|
char* tmp = (char*)realloc(data, r);
|
||||||
if (data) {
|
if (tmp) {
|
||||||
|
data = tmp;
|
||||||
data_size = r;
|
data_size = r;
|
||||||
} else {
|
}else{
|
||||||
data_size = 0;
|
FAIL_MSG("Could not resize socket buffer to %d bytes!", r);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
socklen_t destsize = destAddr_size;
|
socklen_t destsize = destAddr_size;
|
||||||
|
|
|
@ -142,6 +142,7 @@ namespace Socket {
|
||||||
void setBlocking(bool blocking);
|
void setBlocking(bool blocking);
|
||||||
void SetDestination(std::string hostname, uint32_t port);
|
void SetDestination(std::string hostname, uint32_t port);
|
||||||
void GetDestination(std::string & hostname, uint32_t & port);
|
void GetDestination(std::string & hostname, uint32_t & port);
|
||||||
|
uint32_t getDestPort() const;
|
||||||
bool Receive();
|
bool Receive();
|
||||||
void SendNow(const std::string & data);
|
void SendNow(const std::string & data);
|
||||||
void SendNow(const char * data);
|
void SendNow(const char * data);
|
||||||
|
|
|
@ -735,7 +735,7 @@ namespace Mist {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MEDIUM_MSG("Buffer has indicated that incoming track %lu should start writing on track %lu, page %lu", tid, finalTid, firstPage);
|
MEDIUM_MSG("Buffer says %s:%lu should start writing on track %lu, page %lu", streamName.c_str(), tid, finalTid, firstPage);
|
||||||
trackMap[tid] = finalTid;
|
trackMap[tid] = finalTid;
|
||||||
if (myMeta.tracks.count(finalTid) && myMeta.tracks[finalTid].lastms){
|
if (myMeta.tracks.count(finalTid) && myMeta.tracks[finalTid].lastms){
|
||||||
myMeta.tracks[finalTid].lastms = 0;
|
myMeta.tracks[finalTid].lastms = 0;
|
||||||
|
|
|
@ -552,14 +552,31 @@ namespace Mist {
|
||||||
return buffer.begin()->time;
|
return buffer.begin()->time;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Return the end time of the VoD asset, or 0 if unknown.
|
///Return the start time of the selected tracks.
|
||||||
|
uint64_t Output::startTime(){
|
||||||
|
uint64_t start = 0xFFFFFFFFFFFFFFFFull;
|
||||||
|
if (selectedTracks.size()){
|
||||||
|
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
||||||
|
if (myMeta.tracks.count(*it)){
|
||||||
|
if (start < myMeta.tracks[*it].firstms){
|
||||||
|
start = myMeta.tracks[*it].firstms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
///Return the end time of the selected tracks, or 0 if unknown or live.
|
||||||
uint64_t Output::endTime(){
|
uint64_t Output::endTime(){
|
||||||
if (myMeta.live){return 0;}
|
if (myMeta.live){return 0;}
|
||||||
uint64_t end = 0;
|
uint64_t end = 0;
|
||||||
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
if (selectedTracks.size()){
|
||||||
if (myMeta.tracks.count(*it)){
|
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
||||||
if (end < myMeta.tracks[*it].lastms){
|
if (myMeta.tracks.count(*it)){
|
||||||
end = myMeta.tracks[*it].lastms;
|
if (end < myMeta.tracks[*it].lastms){
|
||||||
|
end = myMeta.tracks[*it].lastms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace Mist {
|
||||||
bool seek(unsigned int tid, unsigned long long pos, bool getNextKey = false);
|
bool seek(unsigned int tid, unsigned long long pos, bool getNextKey = false);
|
||||||
void stop();
|
void stop();
|
||||||
uint64_t currentTime();
|
uint64_t currentTime();
|
||||||
|
uint64_t startTime();
|
||||||
uint64_t endTime();
|
uint64_t endTime();
|
||||||
void setBlocking(bool blocking);
|
void setBlocking(bool blocking);
|
||||||
long unsigned int getMainSelectedTrack();
|
long unsigned int getMainSelectedTrack();
|
||||||
|
|
Loading…
Add table
Reference in a new issue