diff --git a/lib/dtsc.h b/lib/dtsc.h index 0ddc6793..730d7d5d 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -325,6 +325,7 @@ namespace DTSC { std::string init; std::string codec; std::string type; + std::string lang;///< ISO 639-2 Language of track, empty or und if unknown. //audio only int rate; int size; diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index 69e1e8cf..0484d420 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -1124,6 +1124,9 @@ namespace DTSC { codec = trackRef["codec"].asStringRef(); type = trackRef["type"].asStringRef(); init = trackRef["init"].asStringRef(); + if (trackRef.isMember("lang") && trackRef["lang"].asStringRef().size()){ + lang = trackRef["lang"].asStringRef(); + } if (type == "audio") { rate = trackRef["rate"].asInt(); size = trackRef["size"].asInt(); @@ -1178,6 +1181,9 @@ namespace DTSC { codec = trackRef.getMember("codec").asString(); type = trackRef.getMember("type").asString(); init = trackRef.getMember("init").asString(); + if (trackRef.getMember("lang")){ + lang = trackRef.getMember("lang").asString(); + } if (type == "audio") { rate = trackRef.getMember("rate").asInt(); size = trackRef.getMember("size").asInt(); @@ -1468,6 +1474,9 @@ namespace DTSC { str << std::hex << std::setw(2) << std::setfill('0') << (int)init[i]; } str << std::dec << std::endl; + if (lang.size()){ + str << std::string(indent + 2, ' ') << "Language: " << lang << std::endl; + } if (type == "audio") { str << std::string(indent + 2, ' ') << "Rate: " << rate << std::endl; str << std::string(indent + 2, ' ') << "Size: " << size << std::endl; @@ -1552,6 +1561,9 @@ namespace DTSC { result << width << "x" << height << "_"; result << (double)fpks / 1000 << "fps"; } + if (lang.size() && lang != "und"){ + result << "_" << lang; + } return result.str(); } @@ -1576,6 +1588,9 @@ namespace DTSC { result += parts.size() * 9 + 12; result += (ivecs.size() * 8) + 12; /*LTS*/ } + if (lang.size() && lang != "und"){ + result += 11 + lang.size(); + } if (type == "audio") { result += 49; } else if (type == "video") { @@ -1666,6 +1681,11 @@ namespace DTSC { writePointer(p, "\000\004type\002", 7); writePointer(p, convertInt(type.size()), 4); writePointer(p, type); + if (lang.size() && lang != "und"){ + writePointer(p, "\000\004lang\002", 7); + writePointer(p, convertInt(lang.size()), 4); + writePointer(p, lang); + } if (type == "audio") { writePointer(p, "\000\004rate\001", 7); writePointer(p, convertLongLong(rate), 8); @@ -1745,6 +1765,11 @@ namespace DTSC { conn.SendNow("\000\004type\002", 7); conn.SendNow(convertInt(type.size()), 4); conn.SendNow(type); + if (lang.size() && lang != "und"){ + conn.SendNow("\000\004lang\002", 7); + conn.SendNow(convertInt(lang.size()), 4); + conn.SendNow(lang); + } if (type == "audio") { conn.SendNow("\000\004rate\001", 7); conn.SendNow(convertLongLong(rate), 8); @@ -1879,6 +1904,9 @@ namespace DTSC { /*LTS-END*/ } result["init"] = init; + if (lang.size() && lang != "und"){ + result["lang"] = lang; + } result["trackid"] = trackID; result["firstms"] = (long long)firstms; result["lastms"] = (long long)lastms; diff --git a/lib/mp4_generic.cpp b/lib/mp4_generic.cpp index c0cdcc79..b035f953 100644 --- a/lib/mp4_generic.cpp +++ b/lib/mp4_generic.cpp @@ -2476,20 +2476,43 @@ namespace MP4 { void MDHD::setLanguage(uint16_t newLanguage) { if (getVersion() == 0) { - setInt16(newLanguage & 0x7F, 20); + setInt16(newLanguage & 0x7FFF, 20); } else { - setInt16(newLanguage & 0x7F, 32); + setInt16(newLanguage & 0x7FFF, 32); } } - uint16_t MDHD::getLanguage() { + uint16_t MDHD::getLanguageInt() { if (getVersion() == 0) { - return getInt16(20) & 0x7F; + return getInt16(20) & 0x7FFF; } else { - return getInt16(32) & 0x7F; + return getInt16(32) & 0x7FFF; } } + void MDHD::setLanguage(const std::string & newLanguage) { + if (newLanguage.size() != 3){ + setLanguage("und"); + return; + } + uint16_t newLang = 0; + newLang += (newLanguage[0] - 0x60) & 0x1F; + newLang <<= 5; + newLang += (newLanguage[1] - 0x60) & 0x1F; + newLang <<= 5; + newLang += (newLanguage[2] - 0x60) & 0x1F; + setLanguage(newLang); + } + + std::string MDHD::getLanguage() { + uint16_t lInt = getLanguageInt(); + std::string ret; + ret += (char)(((lInt & 0x7C00) >> 10) + 0x60); + ret += (char)(((lInt & 0x3E0) >> 5) + 0x60); + ret += (char)((lInt & 0x1F) + 0x60); + return ret; + } + std::string MDHD::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[mdhd] Media Header Box (" << boxedSize() << ")" << std::endl; @@ -2498,7 +2521,7 @@ namespace MP4 { r << std::string(indent + 1, ' ') << "ModificationTime: " << getModificationTime() << std::endl; r << std::string(indent + 1, ' ') << "TimeScale: " << getTimeScale() << std::endl; r << std::string(indent + 1, ' ') << "Duration: " << getDuration() << std::endl; - r << std::string(indent + 1, ' ') << "Language: 0x" << std::hex << getLanguage() << std::dec << std::endl; + r << std::string(indent + 1, ' ') << "Language: " << getLanguage() << std::endl; return r.str(); } diff --git a/lib/mp4_generic.h b/lib/mp4_generic.h index d2dc7b04..5e870857 100644 --- a/lib/mp4_generic.h +++ b/lib/mp4_generic.h @@ -515,9 +515,10 @@ namespace MP4 { uint32_t getTimeScale(); void setDuration(uint64_t newDuration); uint64_t getDuration(); - ///\todo return language properly void setLanguage(uint16_t newLanguage); - uint16_t getLanguage(); + uint16_t getLanguageInt(); + void setLanguage(const std::string & newLanguage); + std::string getLanguage(); std::string toPrettyString(uint32_t indent = 0); }; diff --git a/lib/ts_packet.cpp b/lib/ts_packet.cpp index 0e61f829..6fad3d8c 100644 --- a/lib/ts_packet.cpp +++ b/lib/ts_packet.cpp @@ -258,6 +258,9 @@ namespace TS { if (getRandomAccess()){ output << " [RandomXS]"; } + if (getESPriority()){ + output << " [ESPriority]"; + } if (hasPCR()) { output << " [PCR " << (double)getPCR() / 27000000 << "s]"; } @@ -286,7 +289,7 @@ namespace TS { return output.str(); } - if (detailLevel >= 3){ + if (detailLevel >= 10){ output << std::string(indent+2, ' ') << "Raw data bytes:"; unsigned int size = getDataSize(); @@ -325,12 +328,6 @@ namespace TS { } } -/// Gets the elementary stream priority indicator of a Packet -/// \return The elementary stream priority indicator of a Packet - bool Packet::hasESpriority() const{ - return strBuf[5] & 0x20; - } - bool Packet::hasDiscontinuity() const{ return strBuf[5] & 0x80; } @@ -366,6 +363,15 @@ namespace TS { 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; + } + return strBuf[5] & 0x20; + } + ///Gets the value of the PCR flag ///\return true if there is a PCR, false otherwise bool Packet::hasPCR() const{ @@ -408,6 +414,30 @@ namespace TS { } } +///Gets the value of the ES priority flag +///\return the value of the ES priority flag + void Packet::setESPriority(bool NewVal) { + updPos(6); + if (getAdaptationField() == 3) { + if (!strBuf[4]) { + strBuf[4] = 1; + } + if (NewVal) { + strBuf[5] |= 0x20; + } else { + strBuf[5] &= 0xDF; + } + } else { + setAdaptationField(3); + strBuf[4] = 1; + if (NewVal) { + strBuf[5] = 0x20; + } else { + strBuf[5] = 0x00; + } + } + } + /// Transforms the Packet into a standard Program Association Table void Packet::setDefaultPAT() { static int MyCntr = 0; @@ -959,17 +989,85 @@ namespace TS { 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() << "), Info (" << entry.getESInfoLength() << ") = "; - for (unsigned int i = 0; i p_len){continue;}//skip broken data + output << std::string(indent, ' ') << "AAC profile: "; + switch (p_data[p+2]){ + case 0x50: output << "AAC, level 1"; break; + case 0x51: output << "AAC, level 2"; break; + case 0x52: output << "AAC, level 4"; break; + case 0x53: output << "AAC, level 5"; break; + case 0x58: output << "AAC-HE, level 2"; break; + case 0x59: output << "AAC-HE, level 3"; break; + case 0x5A: output << "AAC-HE, level 4"; break; + case 0x5B: output << "AAC-HE, level 5"; break; + case 0x60: output << "AAC-HEv2, level 2"; break; + 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; + } + 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 << 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; + } + } + } break; + default:{ + output << std::string(indent, ' ') << "Undecoded descriptor: "; + for (uint32_t i = 0; i "; time += thisPacket.getInt("duration"); + if (time == thisPacket.getTime()){ + time += len * 100 + 1000; + } tmpLen = sprintf(tmpBuf, "%.2llu:%.2llu:%.2llu,%.3llu", (time / 3600000), ((time % 3600000) / 60000), (((time % 3600000) % 60000) / 1000), time % 1000); tmp.write(tmpBuf, tmpLen); tmp << std::endl; diff --git a/src/output/output_ts_base.cpp b/src/output/output_ts_base.cpp index ecb61e4d..1c1b08fa 100644 --- a/src/output/output_ts_base.cpp +++ b/src/output/output_ts_base.cpp @@ -40,7 +40,8 @@ namespace Mist { packData.setDiscontinuity(true); if (myMeta.tracks[thisPacket.getTrackId()].type == "video"){ if (thisPacket.getInt("keyframe")){ - packData.setRandomAccess(1); + packData.setRandomAccess(true); + packData.setESPriority(true); } packData.setPCR(thisPacket.getTime() * 27000); }