Mercurial > mplayer.hg
comparison libmpdemux/demux_film.c @ 5143:3958674b696b
added proper PTS support for FILM demuxer
author | melanson |
---|---|
date | Sat, 16 Mar 2002 19:58:07 +0000 |
parents | 1504901deed8 |
children | f67b321e1eda |
comparison
equal
deleted
inserted
replaced
5142:7fc559dbc607 | 5143:3958674b696b |
---|---|
21 // chunk types found in a FILM file | 21 // chunk types found in a FILM file |
22 #define CHUNK_FILM mmioFOURCC('F', 'I', 'L', 'M') | 22 #define CHUNK_FILM mmioFOURCC('F', 'I', 'L', 'M') |
23 #define CHUNK_FDSC mmioFOURCC('F', 'D', 'S', 'C') | 23 #define CHUNK_FDSC mmioFOURCC('F', 'D', 'S', 'C') |
24 #define CHUNK_STAB mmioFOURCC('S', 'T', 'A', 'B') | 24 #define CHUNK_STAB mmioFOURCC('S', 'T', 'A', 'B') |
25 | 25 |
26 #define VERSION_1_01 mmioFOURCC('1', '.', '0', '1') | |
27 | |
28 #define MAGIC_FPS_CONSTANT 27 | |
29 | |
30 typedef struct _film_chunk_t | 26 typedef struct _film_chunk_t |
31 { | 27 { |
32 off_t chunk_offset; | 28 off_t chunk_offset; |
33 int chunk_size; | 29 int chunk_size; |
34 | 30 |
35 unsigned int flags1; | 31 unsigned int syncinfo1; |
36 unsigned int flags2; | 32 unsigned int syncinfo2; |
37 | 33 |
38 unsigned int video_chunk_number; // in the case of a video chunk | 34 unsigned int video_chunk_number; // in the case of a video chunk |
39 unsigned int running_audio_sample_count; // for an audio chunk | 35 unsigned int running_audio_sample_count; // for an audio chunk |
40 } film_chunk_t; | 36 } film_chunk_t; |
41 | 37 |
91 // position stream and fetch chunk | 87 // position stream and fetch chunk |
92 stream_seek(demuxer->stream, film_chunk.chunk_offset); | 88 stream_seek(demuxer->stream, film_chunk.chunk_offset); |
93 | 89 |
94 // load the chunks manually (instead of using ds_read_packet()), since | 90 // load the chunks manually (instead of using ds_read_packet()), since |
95 // they require some adjustment | 91 // they require some adjustment |
96 // (all ones in flags1 indicates an audio chunk) | 92 // (all ones in syncinfo1 indicates an audio chunk) |
97 if (film_chunk.flags1 == 0xFFFFFFFF) | 93 if (film_chunk.syncinfo1 == 0xFFFFFFFF) |
98 { | 94 { |
99 demux_packet_t* dp=new_demux_packet(film_chunk.chunk_size); | 95 demux_packet_t* dp=new_demux_packet(film_chunk.chunk_size); |
100 stream_read(demuxer->stream, dp->buffer, film_chunk.chunk_size); | 96 stream_read(demuxer->stream, dp->buffer, film_chunk.chunk_size); |
101 dp->pts = 0; | 97 dp->pts = 0; |
102 dp->pos = film_chunk.chunk_offset; | 98 dp->pos = film_chunk.chunk_offset; |
120 ds_add_packet(demuxer->audio, dp); | 116 ds_add_packet(demuxer->audio, dp); |
121 film_data->current_chunk++; | 117 film_data->current_chunk++; |
122 } | 118 } |
123 else | 119 else |
124 { | 120 { |
125 // check the tick to see if it's time to dispatch a new frame | |
126 if ((film_data->film_version == VERSION_1_01) && | |
127 ((film_chunk.flags1 & 0x7FFFFFFF) != film_data->ticks++)) | |
128 { | |
129 demux_packet_t* dp=new_demux_packet(0); | |
130 dp->pts = 0; | |
131 dp->pos = 0; | |
132 dp->flags = 0; | |
133 ds_add_packet(demuxer->video, dp); | |
134 } | |
135 // if the demuxer is dealing with CVID data, deal with it a special way | 121 // if the demuxer is dealing with CVID data, deal with it a special way |
136 else if (sh_video->format == mmioFOURCC('c', 'v', 'i', 'd')) | 122 if (sh_video->format == mmioFOURCC('c', 'v', 'i', 'd')) |
137 { | 123 { |
138 // account for 2 extra bytes | 124 // account for 2 extra bytes |
139 demux_packet_t* dp=new_demux_packet(film_chunk.chunk_size - 2); | 125 demux_packet_t* dp=new_demux_packet(film_chunk.chunk_size - 2); |
140 | 126 |
141 // these CVID data chunks appear to have 2 extra bytes; skip them | 127 // these CVID data chunks appear to have 2 extra bytes; skip them |
142 stream_read(demuxer->stream, dp->buffer, 10); | 128 stream_read(demuxer->stream, dp->buffer, 10); |
143 stream_skip(demuxer->stream, 2); | 129 stream_skip(demuxer->stream, 2); |
144 stream_read(demuxer->stream, dp->buffer + 10, film_chunk.chunk_size - 12); | 130 stream_read(demuxer->stream, dp->buffer + 10, film_chunk.chunk_size - 12); |
145 dp->pts = film_chunk.video_chunk_number / sh_video->fps; | 131 dp->pts = (film_chunk.syncinfo1 & 0x7FFFFFFF) / sh_video->fps; |
146 dp->pos = film_chunk.chunk_offset; | 132 dp->pos = film_chunk.chunk_offset; |
147 dp->flags = (film_chunk.flags1 & 0x80000000) ? 1 : 0; | 133 dp->flags = (film_chunk.syncinfo1 & 0x80000000) ? 1 : 0; |
148 | 134 |
149 // fix the CVID chunk size by adding 6 | 135 // fix the CVID chunk size by adding 6 |
150 cvid_size = (dp->buffer[1] << 16) | (dp->buffer[2] << 8) | dp->buffer[3]; | 136 cvid_size = (dp->buffer[1] << 16) | (dp->buffer[2] << 8) | dp->buffer[3]; |
151 cvid_size += 6; | 137 cvid_size += 6; |
152 dp->buffer[1] = (cvid_size >> 16) & 0xFF; | 138 dp->buffer[1] = (cvid_size >> 16) & 0xFF; |
158 film_data->current_chunk++; | 144 film_data->current_chunk++; |
159 } | 145 } |
160 else | 146 else |
161 { | 147 { |
162 ds_read_packet(demuxer->video, demuxer->stream, film_chunk.chunk_size, | 148 ds_read_packet(demuxer->video, demuxer->stream, film_chunk.chunk_size, |
163 film_chunk.video_chunk_number / sh_video->fps, /* pts */ | 149 (film_chunk.syncinfo1 & 0x7FFFFFFF) / sh_video->fps, |
164 film_chunk.chunk_offset, (film_chunk.flags1 & 0x80000000) ? 1 : 0); | 150 film_chunk.chunk_offset, (film_chunk.syncinfo1 & 0x80000000) ? 1 : 0); |
165 film_data->current_chunk++; | 151 film_data->current_chunk++; |
166 } | 152 } |
167 } | 153 } |
168 | 154 |
169 return 1; | 155 return 1; |
284 | 270 |
285 // FPS hack based on empirical observation | 271 // FPS hack based on empirical observation |
286 if (sh_video) | 272 if (sh_video) |
287 { | 273 { |
288 sh_video->fps = stream_read_dword(demuxer->stream); | 274 sh_video->fps = stream_read_dword(demuxer->stream); |
289 if (film_data->film_version != VERSION_1_01) | 275 // if (film_data->film_version != VERSION_1_01) |
290 sh_video->fps = MAGIC_FPS_CONSTANT; | 276 // sh_video->fps = MAGIC_FPS_CONSTANT; |
291 sh_video->frametime = 1 / sh_video->fps; | 277 sh_video->frametime = 1.0 / sh_video->fps; |
292 } | 278 } |
293 | 279 |
294 // fetch the number of chunks | 280 // fetch the number of chunks |
295 film_data->total_chunks = stream_read_dword(demuxer->stream); | 281 film_data->total_chunks = stream_read_dword(demuxer->stream); |
296 film_data->current_chunk = 0; | 282 film_data->current_chunk = 0; |
306 { | 292 { |
307 film_chunk = film_data->chunks[i]; | 293 film_chunk = film_data->chunks[i]; |
308 film_chunk.chunk_offset = | 294 film_chunk.chunk_offset = |
309 demuxer->movi_start + stream_read_dword(demuxer->stream); | 295 demuxer->movi_start + stream_read_dword(demuxer->stream); |
310 film_chunk.chunk_size = stream_read_dword(demuxer->stream); | 296 film_chunk.chunk_size = stream_read_dword(demuxer->stream); |
311 film_chunk.flags1 = stream_read_dword(demuxer->stream); | 297 film_chunk.syncinfo1 = stream_read_dword(demuxer->stream); |
312 film_chunk.flags2 = stream_read_dword(demuxer->stream); | 298 film_chunk.syncinfo2 = stream_read_dword(demuxer->stream); |
313 film_data->chunks[i] = film_chunk; | 299 film_data->chunks[i] = film_chunk; |
314 | 300 |
315 // audio housekeeping | 301 // audio housekeeping |
316 if (sh_audio) | 302 if (sh_audio) |
317 { | 303 { |
318 if ((film_chunk.flags1 == 0xFFFFFFFF) && | 304 if ((film_chunk.syncinfo1 == 0xFFFFFFFF) && |
319 (film_chunk.chunk_size > largest_audio_chunk)) | 305 (film_chunk.chunk_size > largest_audio_chunk)) |
320 largest_audio_chunk = film_chunk.chunk_size; | 306 largest_audio_chunk = film_chunk.chunk_size; |
321 film_data->total_audio_sample_count += | 307 film_data->total_audio_sample_count += |
322 (chunk_size / sh_audio->wf->nChannels); | 308 (chunk_size / sh_audio->wf->nChannels); |
323 } | 309 } |
324 | 310 |
325 // video housekeeping | 311 // video housekeeping |
326 if (sh_video) | 312 if (sh_video) |
327 { | 313 { |
328 if (film_chunk.flags1 != 0xFFFFFFFF) | 314 if (film_chunk.syncinfo1 != 0xFFFFFFFF) |
329 film_chunk.video_chunk_number = | 315 film_chunk.video_chunk_number = |
330 film_data->total_video_chunks++; | 316 film_data->total_video_chunks++; |
331 } | 317 } |
332 } | 318 } |
333 break; | 319 break; |