Mercurial > mplayer.hg
comparison DOCS/tech/mpcf.txt @ 9294:7159ed6a4d0b
nonsense (MPlayer container format draft 0.01)
author | michael |
---|---|
date | Thu, 06 Feb 2003 15:33:02 +0000 |
parents | |
children | 6d845dfe66db |
comparison
equal
deleted
inserted
replaced
9293:96bcc9def790 | 9294:7159ed6a4d0b |
---|---|
1 MPlayer container format draft 0.01 | |
2 | |
3 | |
4 | |
5 Intro: | |
6 | |
7 Features / goals: | |
8 (supported by the format, not necessary by a specific implementation) | |
9 | |
10 Simple | |
11 use the same encoding for nearly all fields | |
12 Extendible | |
13 no limit for the possible values for all fields (using universal vlc) | |
14 allow adding of new headers in the future | |
15 allow adding more fields at the end of headers | |
16 Compact | |
17 ~0.2% overhead, for normal bitrates | |
18 index is <10kb per hour (1 keyframe every 3sec) | |
19 Error resistant | |
20 seeking / playback without an index | |
21 headers & index can be repeated | |
22 audio packet reshuffle | |
23 checksums to allow quick redownloading of damaged parts | |
24 gurantees that no mpeg startcode prefixes occur in the headers with the | |
25 exception of codec specific headers (really?) | |
26 | |
27 | |
28 | |
29 Definitions: | |
30 | |
31 MUST the specific part must be done to conform to this standard | |
32 SHOULD its recommanded to be done that way but its not strictly required | |
33 | |
34 | |
35 | |
36 Syntax: | |
37 | |
38 packet header | |
39 forward ptr v | |
40 backward ptr v | |
41 | |
42 align_byte | |
43 while(not byte aligned) | |
44 one f(1) | |
45 | |
46 reserved_bytes | |
47 for(i=0; i<forward_ptr - length_of_non_reserved; i++) | |
48 reserved u(8) | |
49 | |
50 main header: | |
51 packet header | |
52 main_startcode f(64) | |
53 version v | |
54 stream_count v | |
55 file_size v | |
56 length_in msec v | |
57 reserved_bytes | |
58 checksum u(32) | |
59 | |
60 stream_header: | |
61 packet_header | |
62 stream_startcode f(64) | |
63 stream_id v | |
64 stream_class v | |
65 fourcc v | |
66 average_bitrate v | |
67 language_code v | |
68 time_base v | |
69 lsb_timestamp_length v | |
70 fixed_fps u(1) | |
71 codec_specific_header_flag u(1) | |
72 reserved u(6) | |
73 | |
74 video_stream_header: | |
75 stream_header | |
76 width v | |
77 height v | |
78 sample_width v | |
79 sample_height v | |
80 colorspace_type v | |
81 depth v | |
82 reserved_bytes | |
83 checksum u(32) | |
84 | |
85 audio_stream_header: | |
86 stream_header | |
87 samplerate v | |
88 channel_count v | |
89 sub_packet_size v | |
90 shuffle_type v | |
91 reserved_bytes | |
92 checksum u(32) | |
93 | |
94 codec_specific_header: | |
95 packet_header | |
96 codec_specific_startcode f(64) | |
97 stream_id v | |
98 codec_specific data | |
99 checksum | |
100 | |
101 frame | |
102 packet header | |
103 if(keyframe){ | |
104 keyframe_startcode f(64) | |
105 } | |
106 lsb_timestamp u(lsb_timestamp_length) | |
107 stream_id u(log2_stream_count) | |
108 priority u(2) | |
109 checksum_flag u(1) | |
110 msb_timestamp_flag u(1) | |
111 align_byte | |
112 if(msb_timestamp_flag) | |
113 msb_timestamp v | |
114 bitstream | |
115 if(checksum_flag) | |
116 checksum u(32) | |
117 | |
118 Index: | |
119 packet header | |
120 index_startcode f(64) | |
121 stream_id v | |
122 index_length v | |
123 for(i=0; i<index_length; i++){ | |
124 index_timestamp v | |
125 index_position v | |
126 } | |
127 checksum u(32) | |
128 | |
129 info_header: (optional) | |
130 packet header | |
131 info_startcode f(64) | |
132 title sz | |
133 author sz | |
134 copyright sz | |
135 description sz | |
136 checksum u(32) | |
137 | |
138 v | |
139 value=0 | |
140 do{ | |
141 more_data u(1) | |
142 data u(7) | |
143 value= 128*value + data | |
144 }while(more_data) | |
145 value-=4 | |
146 | |
147 sz (zero terminated string) | |
148 for(i=0; next_byte != 0; i++){ | |
149 string[i] u(8) | |
150 } | |
151 zero_byte f(8) | |
152 Note: the string MUST not be 0 bytes long (only a zero byte coded), instead | |
153 {'?', 0} should be used instead | |
154 | |
155 f(x) n fixed bits | |
156 u(x) unsigned number encoded in x bits in MSB first order | |
157 | |
158 | |
159 forward_ptr | |
160 backward_ptr | |
161 pointer to the next / previous packet | |
162 Note: a frame with 0 bytes means that its skiped | |
163 | |
164 version | |
165 0 for now | |
166 | |
167 file_size | |
168 size in bytes, can be 0 if not meaningfull (realtime streams, ...) | |
169 | |
170 length_in_msec | |
171 length of the file in milli seconds (can be 0 if realtime or such) | |
172 | |
173 stream_id | |
174 Note: streams with a lower relative class MUST have a lower relative id | |
175 so a stream with class 0 MUST allways have a id which is lower then any | |
176 stream with class > 0 | |
177 if there is a stream with id n>0 then there MUST be a stream with id n-1 | |
178 | |
179 stream_class | |
180 0 video | |
181 32 audio | |
182 64 subtiles | |
183 Note the remaining values are reserved and MUST NOT be used | |
184 | |
185 fourcc | |
186 identification for the codec | |
187 example: 'h'<<24 + '2'<<16 + '6'<<8 + '4' | |
188 | |
189 language_code | |
190 something like 'u'<<24 + 's'<<16 + 'e'<<8 + 'n' (US english), can be 0 | |
191 if unknown | |
192 | |
193 time_base | |
194 the number of timer ticks per second, this MUST be equal to the fps | |
195 if the fixed_fps is 1 | |
196 MUST be < 2^15 | |
197 | |
198 lsb_timestamp_length | |
199 length in bits of the lsb_timestamp | |
200 MUST be <16 | |
201 | |
202 fixed_fps | |
203 1 indicates that the fps is fixed | |
204 | |
205 codec_specific_header_flag | |
206 1 indicates that this stream has a codec specific header | |
207 | |
208 msb_timestamp_flag | |
209 indicates that the msb_timestamp is coded | |
210 MUST be 1 for keyframes | |
211 | |
212 msb_timestamp | |
213 most significant bits of the timestamp, SHOULD be 0 for the first frame | |
214 | |
215 lsb_timestamp | |
216 most significant bits of the timestamp in time_base precission, with | |
217 lsb_timestamp_length bits | |
218 Example: IBBP display order | |
219 keyframe msb_timestamp=0 lsb_timestamp=0 -> timestamp=0 | |
220 frame lsb_timestamp=3 -> timestamp=3 | |
221 frame lsb_timestamp=1 -> timestamp=1 | |
222 frame lsb_timestamp=2 -> timestamp=2 | |
223 ... | |
224 keyframe msb_timestamp=1 lsb_timestamp=1 -> timestamp=257 | |
225 frame msb_timestamp=0 lsb_timestamp=255->timestamp=255 | |
226 frame msb_timestamp=1 lsb_timestamp=0 -> timestamp=256 | |
227 frame lsb_timestamp=4 -> timestamp=260 | |
228 frame lsb_timestamp=2 -> timestamp=258 | |
229 frame lsb_timestamp=3 -> timestamp=259 | |
230 | |
231 width/height | |
232 MUST be set to the coded width/height | |
233 | |
234 sample_width/sample_height (aspect ratio) | |
235 sample_width is the horizontal distance between samples | |
236 sample_width and sample_height MUST be relative prime if not zero | |
237 MUST be 0 if unknown | |
238 | |
239 depth | |
240 for compatibility with some win32 codecs | |
241 | |
242 priority | |
243 if 0 then the frame isnt used as reference (b frame) and can be droped | |
244 MUST be > 0 for keyframes | |
245 | |
246 sub_packet_size | |
247 size of an audio packet | |
248 Note a subpacket MUST be in exactly one packet, it cannot be split | |
249 | |
250 shuffle_type | |
251 audio is often encoded in small fixed size packets, and to increase the | |
252 error robustness these can be shuffled | |
253 0 -> no shuffle | |
254 1-16 -> interleave packets by 2^n | |
255 | |
256 checksum | |
257 crc32 checksum using the generator polynomial=0x04c11db7 (same as ogg) | |
258 bit 23 is forced to 1 to avoid MPEG startcode emulation | |
259 | |
260 checksum_flag | |
261 indicates that the frame_checksum is coded | |
262 must be 1 for the last non keyframe before a keyframe | |
263 | |
264 frame_checksum | |
265 identical to checksum, but instead of covering just the current | |
266 packet, it covers all frames of the same stream id since the last | |
267 checksum | |
268 this field is only coded if checksum_flag=1 | |
269 | |
270 index_timestamp | |
271 value in time_base precission, relative to the last index_timestamp | |
272 | |
273 index_position | |
274 position in bytes of the first byte of the keyframe header, relative | |
275 to the last index_position | |
276 | |
277 | |
278 | |
279 Structure: | |
280 | |
281 the headers MUST be in exactly the following order (to simplify demuxer design) | |
282 main header | |
283 stream_header (id=0) | |
284 codec_specific_header (id=0) | |
285 stream_header (id=1) | |
286 codec_specific_header (id=1) | |
287 ... | |
288 stream_header (id=n) | |
289 codec_specific_header (id=n) | |
290 | |
291 headers may be repated, but if they are then they MUST all be repeated together | |
292 and repeated headers MUST be identical | |
293 | |
294 headers MUST be repeated every 10sec at least ? FIXME | |
295 | |
296 | |
297 Sample code (GPL, & untested) | |
298 | |
299 typedef BufferContext{ | |
300 uint8_t *buf; | |
301 uint8_t *buf_ptr; | |
302 }BufferContext; | |
303 | |
304 static inline uint64_t get_bytes(BufferContext *bc, int count){ | |
305 uint64_t val=0; | |
306 | |
307 assert(count>0 && count<9) | |
308 | |
309 for(i=0; i<count; i++){ | |
310 val <<=8; | |
311 val += *(bc->buf_ptr++); | |
312 } | |
313 | |
314 return val; | |
315 } | |
316 | |
317 static inline void put_bytes(BufferContext *bc, int count, uint64_t val){ | |
318 uint64_t val=0; | |
319 | |
320 assert(count>0 && count<9) | |
321 | |
322 for(i=count-1; i>=0; i--){ | |
323 *(bc->buf_ptr++)= val >> (8*i); | |
324 } | |
325 | |
326 return val; | |
327 } | |
328 | |
329 static inline uint64_t get_v(BufferContext *bc){ | |
330 uint64_t val= 0; | |
331 | |
332 for(;;){ | |
333 int tmp= *(bc->buf_ptr++); | |
334 if(tmp&0x80) | |
335 val= (val<<7) + tmp - 0x80; | |
336 else | |
337 return (val<<7) + tmp - 4; | |
338 } | |
339 } | |
340 | |
341 static inline void put_v(BufferContext *bc, uint64_t val){ | |
342 int i; | |
343 val+=4; | |
344 | |
345 assert(val); | |
346 | |
347 for(i=56;; i-=8){ | |
348 if(val>>i) break; | |
349 } | |
350 | |
351 for(;i>0; i-=8){ | |
352 *(bc->buf_ptr++)= 0x80 | (val>>i); | |
353 } | |
354 *(bc->buf_ptr++)= val&0x7F; | |
355 } | |
356 | |
357 | |
358 Example stream | |
359 | |
360 main header | |
361 video_stream_header (stream 0, video jpjp, timebase 30, lsb_timestamp_length=8) | |
362 codec_specific_header (stream 0) | |
363 video_stream_header (stream 1 subtitle usen, timebase 30, lsb_timestamp_length=8) | |
364 video_stream_header (stream 2 subtitle atde, timebase 30, lsb_timestamp_length=8) | |
365 audio_stream_header (stream 3, audio jpjp, timebase 1 , lsb_timestamp_length=8) | |
366 audio_stream_header (stream 4, audio usen, timebase 1 , lsb_timestamp_length=8) | |
367 index (stream 0) | |
368 keyframe (stream 0, msb_timestamp=0, lsb_timestamp=0) | |
369 keyframe (stream 1, msb_timestamp=0, lsb_timestamp=0) | |
370 keyframe (stream 2, msb_timestamp=0, lsb_timestamp=0) | |
371 keyframe (stream 3, msb_timestamp=0, lsb_timestamp=0) | |
372 keyframe (stream 4, msb_timestamp=0, lsb_timestamp=0) | |
373 frame (stream 0, lsb_timestamp=1) | |
374 frame (stream 0, lsb_timestamp=2) | |
375 ... | |
376 frame (stream 0, lsb_timestamp=30) | |
377 keyframe (stream 3, msb_timestamp=0, lsb_timestamp=1) | |
378 keyframe (stream 4, msb_timestamp=0, lsb_timestamp=1) | |
379 frame (stream 0, lsb_timestamp=31) | |
380 frame (stream 0, lsb_timestamp=32) | |
381 ... | |
382 frame (stream 0, lsb_timestamp=60) | |
383 frame (stream 1, lsb_timestamp=60) | |
384 frame (stream 2, lsb_timestamp=60) | |
385 keyframe (stream 3, msb_timestamp=0, lsb_timestamp=2) | |
386 keyframe (stream 4, msb_timestamp=0, lsb_timestamp=2) | |
387 frame (stream 0, lsb_timestamp=61) | |
388 frame (stream 0, lsb_timestamp=62) | |
389 ... | |
390 main header | |
391 video_stream_header (stream 0, video jpjp, timebase 30, lsb_timestamp_length=8) | |
392 codec_specific_header (stream 0) | |
393 video_stream_header (stream 1 subtitle usen, timebase 30, lsb_timestamp_length=8) | |
394 video_stream_header (stream 2 subtitle atde, timebase 30, lsb_timestamp_length=8) | |
395 audio_stream_header (stream 3, audio jpjp, timebase 1 , lsb_timestamp_length=8) | |
396 audio_stream_header (stream 4, audio usen, timebase 1 , lsb_timestamp_length=8) | |
397 frame (stream 0, lsb_timestamp=255) | |
398 frame (stream 0, msb_timestamp=1 lsb_timestamp=0) | |
399 frame (stream 0, lsb_timestamp=1) | |
400 frame (stream 0, lsb_timestamp=2) | |
401 frame (stream 1, msb_timestamp=1 lsb_timestamp=2) | |
402 frame (stream 2, msb_timestamp=1 lsb_timestamp=2) | |
403 frame (stream 0, lsb_timestamp=3) | |
404 frame (stream 0, lsb_timestamp=4) | |
405 ... | |
406 keyframe (stream 3, msb_timestamp=0, lsb_timestamp=9) | |
407 keyframe (stream 4, msb_timestamp=0, lsb_timestamp=9) | |
408 main header | |
409 video_stream_header (stream 0, video jpjp, timebase 30, lsb_timestamp_length=8) | |
410 codec_specific_header (stream 0) | |
411 video_stream_header (stream 1 subtitle usen, timebase 30, lsb_timestamp_length=8) | |
412 video_stream_header (stream 2 subtitle atde, timebase 30, lsb_timestamp_length=8) | |
413 audio_stream_header (stream 3, audio jpjp, timebase 1 , lsb_timestamp_length=8) | |
414 audio_stream_header (stream 4, audio usen, timebase 1 , lsb_timestamp_length=8) | |
415 index (stream 0) |