2 * Copyright (C) 2005 Gabest
\r
3 * http://www.gabest.org
\r
5 * This file format is free to use as long as its specification is not
\r
6 * modified or extended without the permission of Gabest. Suggestions
\r
7 * can be sent in email or posted to the forum at sf.net/projects/guliverkli.
\r
11 -----------------------
\r
12 The .dsm file structure
\r
13 -----------------------
\r
15 FileInfo + Header Packets + Samples + Footer Packets
\r
17 Header & Footer Packets:
\r
18 - Required: MediaType
\r
19 - Optional: StreamInfo, Chapters, SyncPoints, Resource
\r
22 - SyncPoints is optional because seeking can be performed simply by searching for packet syncpoints and their timestamps.
\r
23 - This layout is fine for streaming. On connection send everything up to Sample packets, build the graph at the other end, then the rest when playing. (TODO: introduce NewSegment packet, to support seeking over network)
\r
24 - The resolution of timestamp and duration is 100ns.
\r
25 - Strings are zero terminated utf-8 strings.
\r
26 - Date format string: "%Y-%m-%d %H:%M:%S". (GMT)
\r
27 - Byte order is big-endian
\r
34 DSMSW = 44534D53 ("DSMS")
\r
48 DSMSW (DSMSW_SIZE bytes) (DirectShow Media SyncWord)
\r
50 data size length (3 bits -> 1-8 bytes)
\r
51 data size (1-8 bytes)
\r
55 FileInfo : extends Packet (DSMP_FILEINFO)
\r
56 -----------------------------------------
\r
58 version (1 byte, DSMF_VERSION)
\r
60 ... repeated n times ...
\r
62 id (4 bytes, alphanum)
\r
65 ... repeated n times ...
\r
68 - Parsers should not open files with higher "version" than they were compiled for.
\r
69 - Suggested values of "id":
\r
77 "DATE": Encoding date
\r
78 ... more to be defined ...
\r
80 MediaType : extends Packet (DSMP_MEDIATYPE)
\r
81 -------------------------------------------
\r
85 majortype (sizeof(GUID))
\r
86 subtype (sizeof(GUID))
\r
87 bFixedSizeSamples (1 bit)
\r
88 bTemporalCompression (1 bit)
\r
89 lSampleSize (30 bit)
\r
90 formattype (sizeof(GUID))
\r
92 [... format data ...]
\r
95 - Multiple MediaTypes per stream is NOT allowed
\r
96 - bFixedSizeSamples, bTemporalCompression, lSampleSize are only there to preserve compatibility with dshow's media type structure, they aren't playing a role in anything really.
\r
98 StreamInfo : extends Packet (DSMP_STREAMINFO)
\r
99 ---------------------------------------------
\r
103 ... repeated n times ...
\r
105 id (4 bytes, alphanum)
\r
108 ... repeated n times ...
\r
111 - Suggested values of "id":
\r
112 "NAME": Stream name
\r
113 "SGRP": Stream group (groupped streams can be useful if the splitter is able to group and switch between them, but it's not a strict requirement towards dsm splitters)
\r
114 "LANG": Language code (ISO 639-2)
\r
115 "DESC": Description
\r
116 ... more to be defined ...
\r
118 Chapters : extends Packet (DSMP_CHAPTERS)
\r
119 -----------------------------------------
\r
121 ... repeated n times ...
\r
123 timestamp delta sign (1 bit, <0?)
\r
124 timestamp delta length (3 bits -> 0-7 bytes)
\r
126 timestamp delta (0-7 bytes)
\r
129 ... repeated n times ...
\r
132 - "timestamp delta" holds the difference to the previous value, starts at 0.
\r
134 Sample : extends Packet (DSMP_SAMPLE)
\r
135 -------------------------------------
\r
140 timestamp sign (1 bit, <0?)
\r
141 timestamp length (3 bits -> 0-7 bytes)
\r
142 duration length (3 bits -> 0-7 bytes)
\r
144 timestamp (0-7 bytes)
\r
145 duration (0-7 bytes)
\r
150 - sign == 1 && timestamp length == 0 -> timestamp and duration is unknown (but for syncpoints it cannot be unknown!)
\r
151 - sign == 0 && timestamp length == 0 -> simply means the value is stored on zero bytes and its value is zero too.
\r
152 - timestamps of syncpoints must be strictly in increasing order.
\r
153 - timestamps can be negative (to allow cutting a file at anywhere, preroll samples may need to be saved)
\r
155 SyncPoints : extends Packet (DSMP_SYNCPOINTS)
\r
156 ---------------------------------------------
\r
158 ... repeated n times ...
\r
160 timestamp delta sign (1 bit, <0?)
\r
161 timestamp delta length (3 bits -> 0-7 bytes)
\r
162 file position delta length (3 bits -> 0-7 bytes)
\r
165 timestamp delta (0-7 bytes)
\r
166 file position delta (0-7 bytes)
\r
168 ... repeated n times ...
\r
171 - "timestamp delta" / "file position delta" holds the difference to the previous value, both start at 0.
\r
173 The algorithm of SyncPoints generation
\r
174 --------------------------------------
\r
178 stream 1: 1,5,8 (video)
\r
179 stream 2: 2,3,6,7,9 (audio)
\r
180 stream 3: 4 (subtitle)
\r
182 1 ----| 1->2 1 +2 -> 1 (t 1, fp 1)
\r
183 |---- 2 2->3 1,2 +3 -2 -> 1
\r
184 |---- 3 3->4 1,3 +4 -> 1
\r
185 +-|-- 4 (start) 4->5 1,3,4 +5 -1 -> 1
\r
186 5 --|-| 5->6 3,4,5 +6 -3 -> 3 (t 5, fp 3)
\r
187 | |---- 6 6->7 4,5,6 +7 -6 -> 4 (t 6, fp 4)
\r
188 | |---- 7 7->8 4,5,7 +8 -7 -4 -> 4
\r
190 |---- 8 8->9 5,8 +9 -5 -> 5 (t 8, fp 5)
\r
191 9 ----| 9->10 8,9 +10 -8 -> 8 (t 9, fp 8)
\r
192 |---- 10 10-> 9,10 -> 9 (t 10, fp 9)
\r
194 Notice how it is the values of the first and last elements of the queue are used.
\r
196 In the end it represents the following: (timestamp ranges mapped to file positions)
\r
207 Seeking to 7 would mean we need to start decoding at the file position of 4, which
\r
208 makes sure we hit at least one syncpoint from every stream (4,5,7 and 6 too, but 6
\r
209 can be skipped) until we reach 7.
\r
215 This is going to be a bit more complicated case. (I hope you like my ascii art :)
\r
217 stream 1: 1,4,5,6,7 (video)
\r
218 stream 2: 2,3 (subtitle)
\r
220 1 -----| 1->2 1 +2 -> 1 (t 1, fp 1)
\r
221 +-|--- 2 (start) 2->3 1,2 (+3 NOT!) -> 1
\r
222 +-|-|- 3 (start) 3->4 1,2 +4 -1 -> 1
\r
223 4 -|-|-| 4->5 2,4 +5 -4 -> 2 (t 4, fp 2)
\r
224 5 -|-|-| 5->6 2,5 +6 -5 -2 -> 2
\r
227 6 -----| 6->7 6 +7 -6 -> 6 (t 6, fp 6)
\r
228 7 -----| 7-> 7 -> 7 (t 7, fp 7)
\r
230 The problem with subtitles that they are discontinous, overlapped and can totally hide
\r
231 other syncpoints, just like 2 hides 4, 5 and even 3 fully (which requires special handling,
\r
232 see "NOT!"). That means such a subtitle, when it is too long, can influence seeking time
\r
233 by a lot. It might be wise and worth limiting the duration of samples to a couple of minutes,
\r
234 possibly sacrificing a bit of correctness by it. Splitters can also choose to ignore the
\r
235 suggested seek position, when it falls too far from the required, and go on searching the
\r
236 stream for syncpoints themselves.
\r
238 Resource : extends Packet (DSMP_RESOURCE)
\r
239 -----------------------------------------
\r
241 compression type (2 bits, 0: none, 1: gzip, 2-3: reserved)
\r