Fixes/improvements to H264 lib and analyser
This commit is contained in:
parent
f6af45cd82
commit
8658efc04c
3 changed files with 40 additions and 11 deletions
27
lib/h264.cpp
27
lib/h264.cpp
|
@ -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,26 +813,46 @@ 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;
|
||||||
|
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;
|
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) {
|
||||||
if (annexb){
|
if (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:
|
||||||
|
|
|
@ -294,6 +294,7 @@ namespace h264 {
|
||||||
|
|
||||||
uint32_t payloadType;
|
uint32_t payloadType;
|
||||||
uint32_t payloadSize;
|
uint32_t payloadSize;
|
||||||
|
uint32_t payloadOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue