From 06bda0240c7268358ae695a896e1730f2294cc61 Mon Sep 17 00:00:00 2001
From: Thulinma <jaron@vietors.com>
Date: Mon, 23 Apr 2018 10:48:20 +0200
Subject: [PATCH] Add codec/resolution/framerate information to HLS index

---
 src/output/output_hls.cpp | 48 ++++++++++++++++++++++++++++++++-------
 src/output/output_hls.h   |  4 +++-
 2 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/src/output/output_hls.cpp b/src/output/output_hls.cpp
index e0afa6fc..b7cc9d68 100644
--- a/src/output/output_hls.cpp
+++ b/src/output/output_hls.cpp
@@ -12,6 +12,16 @@ namespace Mist {
     return false;
   }
 
+  std::string OutHLS::h264init(const std::string & initData){
+    std::stringstream r;
+    MP4::AVCC avccBox;
+    avccBox.setPayload(initData);
+    r << std::hex << std::setw(2) << std::setfill('0') << (int)initData[1] << std::dec;
+    r << std::hex << std::setw(2) << std::setfill('0') << (int)initData[2] << std::dec;
+    r << std::hex << std::setw(2) << std::setfill('0') << (int)initData[3] << std::dec;
+    return r.str();
+  }
+
   ///\brief Builds an index file for HTTP Live streaming.
   ///\return The index file for HTTP Live Streaming.
   std::string OutHLS::liveIndex(){
@@ -35,7 +45,26 @@ namespace Mist {
         if (audioId != -1){
           bWidth += myMeta.tracks[audioId].bps;
         }
-        result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" << (bWidth * 8) << "\r\n";
+        result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" << (bWidth * 8);
+        result << ",RESOLUTION=" << it->second.width << "x" << it->second.height;
+        if (it->second.fpks){
+          result << ",FRAME-RATE=" << (float)it->second.fpks / 1000; 
+        }
+        if (it->second.codec == "H264"){
+          result << ",CODECS=\"";
+          if (it->second.codec == "H264"){
+            result << "avc1." << h264init(it->second.init);
+          }
+          if (audioId != -1){
+            if (myMeta.tracks[audioId].codec == "AAC"){
+              result << ",mp4a.40.2";
+            }else if (myMeta.tracks[audioId].codec == "MP3" ){
+              result << ",mp4a.40.34";
+            }
+          }
+          result << "\"";
+        }
+        result <<"\r\n";
         result << it->first;
         if (audioId != -1){
           result << "_" << audioId;
@@ -43,8 +72,14 @@ namespace Mist {
         result << "/index.m3u8?sessId=" << getpid() << "\r\n";
       }
     }
-    if (!vidTracks && audioId){
-      result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" << (myMeta.tracks[audioId].bps * 8) << "\r\n";
+    if (!vidTracks && audioId) {
+      result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" << (myMeta.tracks[audioId].bps * 8);
+      if (myMeta.tracks[audioId].codec == "AAC"){
+        result << ",CODECS=\"mp4a.40.2\"";
+      }else if (myMeta.tracks[audioId].codec == "MP3" ){
+        result << ",CODECS=\"mp4a.40.34\"";
+      }
+      result << "\r\n";
       result << audioId << "/index.m3u8\r\n";
     }
     DEBUG_MSG(DLVL_HIGH, "Sending this index: %s", result.str().c_str());
@@ -68,11 +103,8 @@ namespace Mist {
         duration = myMeta.tracks[tid].lastms - starttime;
       }
       char lineBuf[400];
-      if (sessId.size()){
-        snprintf(lineBuf, 400, "#EXTINF:%f,\r\n%lld_%lld.ts?sessId=%s\r\n", (double)duration/1000, starttime, starttime + duration, sessId.c_str());
-      }else{
-        snprintf(lineBuf, 400, "#EXTINF:%f,\r\n%lld_%lld.ts\r\n", (double)duration/1000, starttime, starttime + duration);
-      }
+
+      snprintf(lineBuf, 400, "#EXTINF:%f,\r\n%lld_%lld.ts\r\n", (double)duration/1000, starttime, starttime + duration);
       durs.push_back(duration);
       total_dur += duration;
       lines.push_back(lineBuf);
diff --git a/src/output/output_hls.h b/src/output/output_hls.h
index 903baf7d..739b89b1 100644
--- a/src/output/output_hls.h
+++ b/src/output/output_hls.h
@@ -11,7 +11,9 @@ namespace Mist {
       void sendNext();
       void onHTTP();      
       bool isReadyForPlay();
-    protected:      
+    protected:
+      std::string h264init(const std::string & initData);
+
       bool hasSessionIDs(){return true;}
       std::string liveIndex();
       std::string liveIndex(int tid, std::string & sessId);