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

View file

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

View file

@ -22,7 +22,6 @@ AnalyserH264::AnalyserH264(Util::Config &conf) : Analyser(conf){
} }
bool AnalyserH264::parsePacket(){ bool AnalyserH264::parsePacket(){
prePos = curPos;
// Read in smart bursts until we have enough data // Read in smart bursts until we have enough data
while (isOpen() && dataBuffer.size() < neededBytes()){ while (isOpen() && dataBuffer.size() < neededBytes()){
uint64_t needed = neededBytes(); uint64_t needed = neededBytes();
@ -35,16 +34,22 @@ bool AnalyserH264::parsePacket(){
} }
size_t size = 0; size_t size = 0;
h264::nalUnit *nalPtr = h264::nalUnit *nalPtr;
h264::nalFactory(dataBuffer.data(), dataBuffer.size(), size, !sizePrepended); 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){ if (!nalPtr){
FAIL_MSG("Could not read a NAL unit at position %llu", prePos); FAIL_MSG("Could not read a NAL unit at position %llu", prePos);
return false; 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; return true;
} }