Fixes/improvements to H264 lib and analyser

This commit is contained in:
Thulinma 2017-12-28 14:35:21 +01:00
parent f6af45cd82
commit 8658efc04c
3 changed files with 40 additions and 11 deletions

View file

@ -801,6 +801,7 @@ namespace h264 {
seiUnit::seiUnit(const char * data, size_t len) : nalUnit(data, len) {
Utils::bitstream bs;
payloadOffset = 1;
for (size_t i = 1; i < len; i++) {
if (i + 2 < len && (memcmp(data + i, "\000\000\003", 3) == 0)){//Emulation prevention bytes
//Yes, we increase i here
@ -812,26 +813,46 @@ namespace h264 {
}
}
uint8_t tmp = bs.get(8);
++payloadOffset;
payloadType = 0;
while (tmp == 0xFF){
payloadType += tmp;
tmp = bs.get(8);
++payloadOffset;
}
payloadType += tmp;
tmp = bs.get(8);
++payloadOffset;
payloadSize = 0;
while (tmp == 0xFF){
payloadSize += tmp;
tmp = bs.get(8);
++payloadOffset;
}
payloadSize += tmp;
}
void seiUnit::toPrettyString(std::ostream & out) {
out << "Nal unit of type " << (((uint8_t)payload[0]) & 0x1F) << " [Supplemental Enhancement Unit] , " << payload.size() << " bytes long" << std::endl;
switch (payloadType){
case 5:{//User data, unregistered
out << " Type 5: User data, unregistered." << std::endl;
std::stringstream uuid;
for (uint32_t i = payloadOffset; i < payloadOffset+16; ++i){
uuid << std::setw(2) << std::setfill('0') << std::hex << (int)(payload.data()[i]);
}
if (uuid.str() == "dc45e9bde6d948b7962cd820d923eeef"){
uuid.str("x264 encoder configuration");
}
out << " UUID: " << uuid.str() << 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;
}
}
nalUnit * nalFactory(const char * _data, size_t _len, size_t & offset, bool annexb) {
if (annexb){
@ -855,7 +876,7 @@ namespace h264 {
if (!annexb){
//read the 4b size in front
pktLen = Bit::btohl(_data+offset);
if (_len < 4 + pktLen){
if (_len - offset < 4 + pktLen){
WARN_MSG("Not at least 4+%lu bytes available - cancelling", pktLen);
return 0;
}
@ -867,9 +888,9 @@ namespace h264 {
//search for the next start marker
for (size_t i = 1; i < len-2; ++i){
if (data[i] == 0 && data[i+1] == 0 && data[i+2] == 1){
offset += i+3;
while (i && !data[i]){--i;}
pktLen = i + 1;
pktLen = i+1;
offset += pktLen;
break;
}
}
@ -883,6 +904,7 @@ namespace h264 {
switch (data[0] & 0x1F){
case 1:
case 5:
case 19:
return new codedSliceUnit(data, pktLen);
case 6:
return new seiUnit(data, pktLen);
@ -920,6 +942,7 @@ namespace h264 {
switch (data[0] & 0x1F){
case 1:
case 5:
case 19:
result = new codedSliceUnit(data, nextPos);
break;
case 6:

View file

@ -294,6 +294,7 @@ namespace h264 {
uint32_t payloadType;
uint32_t payloadSize;
uint32_t payloadOffset;
};

View file

@ -22,7 +22,6 @@ AnalyserH264::AnalyserH264(Util::Config &conf) : Analyser(conf){
}
bool AnalyserH264::parsePacket(){
prePos = curPos;
// Read in smart bursts until we have enough data
while (isOpen() && dataBuffer.size() < neededBytes()){
uint64_t needed = neededBytes();
@ -35,16 +34,22 @@ bool AnalyserH264::parsePacket(){
}
size_t size = 0;
h264::nalUnit *nalPtr =
h264::nalFactory(dataBuffer.data(), dataBuffer.size(), size, !sizePrepended);
h264::nalUnit *nalPtr;
do {
size = 0;
nalPtr = h264::nalFactory(dataBuffer.data(), dataBuffer.size(), size, !sizePrepended);
if (nalPtr){
HIGH_MSG("Read a %lu-byte NAL unit at position %llu", size, prePos);
if (detail >= 2){nalPtr->toPrettyString(std::cout);}
dataBuffer.erase(0, size); // erase the NAL unit we just read
prePos += size;
}
///\TODO update mediaTime with current timestamp
} while(nalPtr);
if (!nalPtr){
FAIL_MSG("Could not read a NAL unit at position %llu", prePos);
return false;
}
HIGH_MSG("Read a %lu-byte NAL unit at position %llu", size, prePos);
dataBuffer.erase(0, size); // erase the NAL unit we just read
if (detail >= 2){nalPtr->toPrettyString(std::cout);}
///\TODO update mediaTime with current timestamp
return true;
}