Commits

Frédéric Yhuel  committed dece328

build_moov_box: add MS codec support

  • Participants
  • Parent commits 69f18a6

Comments (0)

Files changed (1)

File build_moov_box.py

     duration = ss_media.attributes["Duration"].value
     res["duration"] = int(duration)
     vstream = None
+    astream = None
     streams = ss_media.getElementsByTagName("StreamIndex")
     for stream in streams:
         if stream.attributes["Type"].value == "video":
             vstream = stream
-    DisplayWidth = vstream.attributes["DisplayWidth"].value
+        if stream.attributes["Type"].value == "audio":
+            astream = stream
+
+    try:
+        DisplayWidth = vstream.attributes["DisplayWidth"].value
+    except KeyError:
+        DisplayWidth = 1280
     res["DisplayWidth"] = int(DisplayWidth)
-    DisplayHeight = vstream.attributes["DisplayHeight"].value
+    try:
+        DisplayHeight = vstream.attributes["DisplayHeight"].value
+    except KeyError:
+        DisplayHeight = 720
     res["DisplayHeight"] = int(DisplayHeight)
     if cqlevel > 0:
         res["QualityLevels"] = 1
     else:
-        QualityLevels = vstream.attributes["QualityLevels"].value
+        try:
+            QualityLevels = vstream.attributes["QualityLevels"].value
+        except KeyError:
+            QualityLevels = 1
         res["QualityLevels"] = int(QualityLevels)
 
+    # VIDEO ###################################################################
     qlevels = vstream.getElementsByTagName("QualityLevel")
     mark = "00000001"
+    count = 0
     for qlevel in qlevels:
-        Index = int(qlevel.attributes["Index"].value)
+        try:
+            Index = int(qlevel.attributes["Index"].value)
+        except KeyError, e:
+            Index = count
+            count += 1
         Bitrate = int(qlevel.attributes["Bitrate"].value)
+        FourCC = qlevel.attributes["FourCC"].value
+        MaxWidth = qlevel.attributes["MaxWidth"].value
+        MaxHeight = qlevel.attributes["MaxHeight"].value
+        res["vcodec"] = FourCC
         if cqlevel > 0:
             if Bitrate == cqlevel:
                 Index = 0
             else:
                 continue
         CodecPrivateData = qlevel.attributes["CodecPrivateData"].value
-        assert(CodecPrivateData[0:8] == mark)
-        CodecPrivateData = CodecPrivateData[8:]
-        partition = CodecPrivateData.partition(mark)
-        sequenceParameterSetNALUnit = partition[0]
-        pictureParameterSetNALUnit = partition[2]
-        res[("sequenceParameterSetNALUnit", Index)] = b16decode(sequenceParameterSetNALUnit)
-        res[("pictureParameterSetNALUnit", Index)] = b16decode(pictureParameterSetNALUnit)
+
+        if FourCC == "H264":
+            assert(CodecPrivateData[0:8] == mark)
+            CodecPrivateData = CodecPrivateData[8:]
+            partition = CodecPrivateData.partition(mark)
+            sequenceParameterSetNALUnit = partition[0]
+            pictureParameterSetNALUnit = partition[2]
+            res[("sequenceParameterSetNALUnit", Index)] = b16decode(sequenceParameterSetNALUnit)
+            res[("pictureParameterSetNALUnit", Index)] = b16decode(pictureParameterSetNALUnit)
+
+        elif FourCC == "WVC1":
+            res[("VideoInfoHeader", Index)] = b16decode(CodecPrivateData)
+
         if cqlevel > 0 and Bitrate == cqlevel:
             break
+    res["MaxWidth"] = int(MaxWidth)
+    res["MaxHeight"] = int(MaxHeight)
+    ###########################################################################
+
+    # AUDIO
+    qlevels = astream.getElementsByTagName("QualityLevel")
+    for qlevel in qlevels:
+        try:
+            Index = int(qlevel.attributes["Index"].value)
+        except KeyError, e:
+            Index = 0
+        Bitrate = int(qlevel.attributes["Bitrate"].value)
+        try:
+            FourCC = qlevel.attributes["FourCC"].value
+        except KeyError:
+            FourCC = "WMAP"
+        res["acodec"] = FourCC
+        try:
+            CodecPrivateData = qlevel.attributes["CodecPrivateData"].value
+        except KeyError:
+            CodecPrivateData = qlevel.attributes["WaveFormatEx"].value
+
+        if FourCC == "WMAP":
+            res[("WaveFormatEx", Index)] = b16decode(CodecPrivateData)
+
+        elif FourCC == "AACL":
+            res[("AACL", Index)] = ""
+
 
     pprint(res)
     return res
         volume = 0
     if track_type == "video":
         #width  = 0x00e00000 #FIXME
-        width  = params["DisplayWidth"]
+        width  = params["MaxWidth"]
+        width <<= 16
         #height = 0x00800000 #FIXME
-        height = params["DisplayHeight"]
+        height = params["MaxHeight"]
+        height <<= 16
     else:
         width  = 0
         height = 0
 
     stsz = pack(">L4sLLL", 20, "stsz", 0, 0, 0)
 
-    #video_extra = pack(">19LB", 0x0000004d, 0x61766343, 0x0164400d, 0xffe10035,\
-    #        0x6764000d, 0xac2ca50e, 0x11bff040, 0x003f0520, 0xc0c0c800, 0x44aa180c, 0xdfe60300,\
-    #        0x001c1200, 0x038273f8, 0xc7180000, 0xe090001c, 0x139fc638, 0x76848945, 0x80010005,\
-    #        0x68e90935, 0x25)
-
     if track_type == "video":
-        video_extra = build_avcC(params)
+        if params["vcodec"] == "H264":
+            video_fmt = "avc1"
+            video_extra = build_avcC(params)
+        elif params["vcodec"] == "WVC1":
+            video_fmt = "vc-1"
+            video_extra = build_dvc1(params)
+
         sample_entry_size = 86 + len(video_extra)
-        video_fmt = "avc1" #FIXME
         #width = 224 #FIXME
-        width = params["DisplayWidth"]
+        width = params["MaxWidth"]
         #height = 128 #FIXME
-        height = params["DisplayHeight"]
+        height = params["MaxHeight"]
         horiz_resolution = 0x00480000
         vert_resolution = 0x00480000
         compressor_name = "\x00"*32
         SampleEntry += video_extra
 
     elif track_type == "audio":
-        #FIXME
-        audio_extra = pack(">H31LHB", 0x0000, 0x00816573, 0x64730000, 0x00000380,\
-                0x80807000, 0x00000480, 0x80806240, 0x15003000, 0x0001f400,\
-                0x0001f400, 0x05808080, 0x50121008, 0xc4000020, 0x00000000,\
-                0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,\
-                0x00000000, 0x01000000, 0,0,0,0,0,0,0,0,0,0, 0x00068080,\
-                0x8001, 0x02)
+        if params["acodec"] == "AACL":
+            audio_fmt = "mp4a"
+            audio_extra = pack(">H31LHB", 0x0000, 0x00816573, 0x64730000, 0x00000380,\
+                    0x80807000, 0x00000480, 0x80806240, 0x15003000, 0x0001f400,\
+                    0x0001f400, 0x05808080, 0x50121008, 0xc4000020, 0x00000000,\
+                    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,\
+                    0x00000000, 0x01000000, 0,0,0,0,0,0,0,0,0,0, 0x00068080,\
+                    0x8001, 0x02)
+
+        elif params["acodec"] == "WMAP":
+            audio_fmt = "wma "
+            audio_extra = build_wfex(params)
 
         sample_entry_size = 36 + len(audio_extra)
-        audio_fmt = "mp4a" #FIXME
         sample_rate = 0xac440000 #FIXME 0xac44 = 44100
         SampleEntry = pack(">L4sLHH", sample_entry_size, audio_fmt, 0, 0, 1)
         SampleEntry += pack(">QHHLL", 0, 2, 16, 0, sample_rate)
     stbl = stbl_header + stts + ctts + stsc + stco + stsz + stsd
     return stbl
 
+def build_wfex(params):
+    const = pack(">4LH", 0x62010200, 0x44ac0000, 0xe32e0000, 0x6b111000, 0x1200)
+    WaveFormatEx = params[("WaveFormatEx", 0)]
+    wfex_size = 8 + len(const) + len(WaveFormatEx)
+    wfex_header = pack(">L4s", wfex_size, "wfex")
+    wfex = wfex_header + const + WaveFormatEx
+
+    return wfex
+
+def build_dvc1(params):
+    const = pack(">L3B", 0xc8802418, 0x18, 0xbd, 0x19)
+    VideoInfoHeader = params[("VideoInfoHeader", 0)]
+    dvc1_size = 8 + len(const) + len(VideoInfoHeader)
+    dvc1_header = pack(">L4s", dvc1_size, "dvc1")
+    dvc1 = dvc1_header + const + VideoInfoHeader
+
+    return dvc1
+
 def build_avcC(params):
     print("Enter build_avcC")
     AVCProfileIndication = 0x64 #FIXME