From 073a80e079acced39acd6c1a06476db779861569 Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Tue, 7 May 2013 11:22:00 +0200 Subject: [PATCH] Updated MistConnHTTPSmooth to output a proper Manifest for DTSCv2 files. --- src/buffer/player.cpp | 13 ++-- src/connectors/conn_http_smooth.cpp | 110 +++++++++++++++++----------- 2 files changed, 74 insertions(+), 49 deletions(-) diff --git a/src/buffer/player.cpp b/src/buffer/player.cpp index 6dcb505e..9292caad 100644 --- a/src/buffer/player.cpp +++ b/src/buffer/player.cpp @@ -152,10 +152,13 @@ int main(int argc, char** argv){ json_sts["vod"]["start"] = Util::epoch() - sts.conntime; if ( !meta_sent){ json_sts["vod"]["meta"] = meta; - json_sts["vod"]["meta"]["audio"].removeMember("init"); - json_sts["vod"]["meta"]["video"].removeMember("init"); - json_sts["vod"]["meta"].removeMember("keytime"); - json_sts["vod"]["meta"].removeMember("keybpos"); + for (JSON::ObjIter oIt = json_sts["vod"]["meta"]["tracks"].ObjBegin(); oIt != json_sts["vod"]["meta"]["tracks"].ObjEnd(); oIt++){ + oIt->second.removeMember("init"); + oIt->second.removeMember("keytime"); + oIt->second.removeMember("keybpos"); + oIt->second.removeMember("keynum"); + oIt->second.removeMember("frags"); + } meta_sent = true; } StatsSocket.Send(json_sts.toString().c_str()); @@ -226,7 +229,7 @@ int main(int argc, char** argv){ }else{ lasttime = Util::epoch(); //insert proper header for this type of data - in_out.Send("DTPD"); + in_out.Send("DTP2"); //insert the packet length unsigned int size = htonl(source.getPacket().size()); in_out.Send((char*) &size, 4); diff --git a/src/connectors/conn_http_smooth.cpp b/src/connectors/conn_http_smooth.cpp index 7a74b796..919fc5e8 100644 --- a/src/connectors/conn_http_smooth.cpp +++ b/src/connectors/conn_http_smooth.cpp @@ -48,71 +48,93 @@ namespace Connector_HTTP { "CanPause=\"TRUE\" "; } Result << ">\n"; + JSON::Value allAudio; + JSON::Value allVideo; + long long int maxWidth = 0; + long long int maxHeight = 0; + long long int minWidth = 99999999; + long long int minHeight = 99999999; + for (JSON::ObjIter oIt = metadata["tracks"].ObjBegin(); oIt != metadata["tracks"].ObjEnd(); oIt++){ + if (oIt->second["type"].asString() == "audio"){ + allAudio[oIt->first] = oIt->second; + } + if (oIt->second["type"].asString() == "video"){ + allVideo[oIt->first] = oIt->second; + if (oIt->second["width"].asInt() > maxWidth){ maxWidth = oIt->second["width"].asInt(); } + if (oIt->second["width"].asInt() < minWidth){ minWidth = oIt->second["width"].asInt(); } + if (oIt->second["height"].asInt() > maxHeight){ maxHeight = oIt->second["height"].asInt(); } + if (oIt->second["height"].asInt() < minHeight){ minHeight = oIt->second["height"].asInt(); } + } + } + //Add audio entries - if (metadata.isMember("audio") && metadata["audio"]["codec"].asString() == "AAC"){ + if (allAudio.size()){ Result << "second["keytime"].size() << "\" " "Url=\"Q({bitrate})/A({start time})\">\n"; - //Add audio qualities - Result << "second["trackid"].asInt() << "\" " + "Bitrate=\"" << oIt->second["bps"].asInt() * 8 << "\" " + "CodecPrivateData=\"" << std::hex; + for (int i = 0; i < oIt->second["init"].asString().size(); i++){ + Result << std::setfill('0') << std::setw(2) << std::right << (int)oIt->second["init"].asString()[i]; + } + Result << std::dec << "\" " + "SamplingRate=\"" << oIt->second["rate"].asInt() << "\" " + "Channels=\"2\" " + "BitsPerSample=\"16\" " + "PacketSize=\"4\" " + "AudioTag=\"255\" " + "FourCC=\"AACL\" />\n"; } - Result << std::dec << "\" " - "SamplingRate=\"" << metadata["audio"]["rate"].asInt() << "\" " - "Channels=\"2\" " - "BitsPerSample=\"16\" " - "PacketSize=\"4\" " - "AudioTag=\"255\" " - "FourCC=\"AACL\" />\n"; - for (unsigned int i = 0; i < metadata["keylen"].size(); i++){ + for (unsigned int i = 0; i < allAudio.ObjBegin()->second["keylen"].size(); i++){ Result << "second["keytime"][i].asInt() * 10000 << "\" "; } - Result << "d=\"" << metadata["keylen"][i].asInt() * 10000 << "\" />\n"; + Result << "d=\"" << allAudio.ObjBegin()->second["keylen"][i].asInt() * 10000 << "\" />\n"; } - Result << " \n"; + Result << "\n"; } //Add video entries - if (metadata.isMember("video") && metadata["video"]["codec"].asString() == "H264"){ + if (allVideo.size()){ Result << "second["keytime"].size() << "\" " "Url=\"Q({bitrate})/V({start time})\" " - "MaxWidth=\"" << metadata["video"]["width"].asInt() << "\" " - "MaxHeight=\"" << metadata["video"]["height"].asInt() << "\" " - "DisplayWidth=\"" << metadata["video"]["width"].asInt() << "\" " - "DisplayHeight=\"" << metadata["video"]["height"].asInt() << "\">\n"; + "MaxWidth=\"" << maxWidth << "\" " + "MaxHeight=\"" << maxHeight << "\" " + "DisplayWidth=\"" << maxWidth << "\" " + "DisplayHeight=\"" << maxHeight << "\">\n"; + for (JSON::ObjIter oIt = allVideo.ObjBegin(); oIt != allVideo.ObjEnd(); oIt++){ //Add video qualities - Result << "second["trackid"].asInt() << "\" " + "Bitrate=\"" << oIt->second["bps"].asInt() * 8 << "\" " + "CodecPrivateData=\"" << std::hex; + MP4::AVCC avccbox; + avccbox.setPayload(oIt->second["init"].asString()); + std::string tmpString = avccbox.asAnnexB(); + for (int i = 0; i < tmpString.size(); i++){ + Result << std::setfill('0') << std::setw(2) << std::right << (int)tmpString[i]; + } + Result << std::dec << "\" " + "MaxWidth=\"" << oIt->second["width"].asInt() << "\" " + "MaxHeight=\"" << oIt->second["height"].asInt() << "\" " + "FourCC=\"AVC1\" />\n"; } - Result << std::dec << "\" " - "MaxWidth=\"" << metadata["video"]["width"].asInt() << "\" " - "MaxHeight=\"" << metadata["video"]["height"].asInt() << "\" " - "FourCC=\"AVC1\" />\n"; - for (unsigned int i = 0; i < metadata["keylen"].size(); i++){ + for (unsigned int i = 0; i < allVideo.ObjBegin()->second["keylen"].size(); i++){ Result << "second["keytime"][i].asInt() * 10000 << "\" "; } - Result << "d=\"" << metadata["keylen"][i].asInt() * 10000 << "\" />\n"; + Result << "d=\"" << allVideo.ObjBegin()->second["keylen"][i].asInt() * 10000 << "\" />\n"; } Result << "\n"; }