Mercurial > mplayer.hg
annotate libmpdemux/demux_film.c @ 5189:c663455448e8
updates by Jiri.Svoboda@seznam.cz
author | arpi |
---|---|
date | Mon, 18 Mar 2002 23:20:13 +0000 |
parents | 81ef0f0b285f |
children | 2a449fba2049 |
rev | line source |
---|---|
4189 | 1 /* |
2 FILM file parser for the MPlayer program | |
3 by Mike Melanson | |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
4 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
5 Details of the FILM file format can be found at: |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
6 http://www.pcisys.net/~melanson/codecs/ |
4189 | 7 */ |
8 | |
9 #include <stdio.h> | |
10 #include <stdlib.h> | |
11 #include <unistd.h> | |
12 | |
13 #include "config.h" | |
14 #include "mp_msg.h" | |
15 #include "help_mp.h" | |
16 | |
17 #include "stream.h" | |
18 #include "demuxer.h" | |
19 #include "stheader.h" | |
20 | |
21 // chunk types found in a FILM file | |
22 #define CHUNK_FILM mmioFOURCC('F', 'I', 'L', 'M') | |
23 #define CHUNK_FDSC mmioFOURCC('F', 'D', 'S', 'C') | |
24 #define CHUNK_STAB mmioFOURCC('S', 'T', 'A', 'B') | |
25 | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
26 typedef struct _film_chunk_t |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
27 { |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
28 off_t chunk_offset; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
29 int chunk_size; |
5143 | 30 unsigned int syncinfo1; |
31 unsigned int syncinfo2; | |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
32 |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
33 float pts; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
34 } film_chunk_t; |
4189 | 35 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
36 typedef struct _film_data_t |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
37 { |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
38 unsigned int total_chunks; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
39 unsigned int current_chunk; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
40 film_chunk_t *chunks; |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
41 unsigned int chunks_per_second; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
42 } film_data_t; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
43 |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
44 void demux_seek_film(demuxer_t *demuxer, float rel_seek_secs, int flags) |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
45 { |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
46 film_data_t *film_data = (film_data_t *)demuxer->priv; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
47 int new_current_chunk; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
48 |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
49 // bit 2 of the flags apparently means that the seek is relative to |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
50 // the beginning of the file |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
51 if (flags & 1) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
52 new_current_chunk = |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
53 rel_seek_secs * film_data->chunks_per_second; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
54 else |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
55 new_current_chunk = film_data->current_chunk + |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
56 rel_seek_secs * film_data->chunks_per_second; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
57 |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
58 printf ("current, total chunks = %d, %d; seek %5.3f sec, new chunk guess = %d\n", |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
59 film_data->current_chunk, film_data->total_chunks, |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
60 rel_seek_secs, new_current_chunk); |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
61 |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
62 // check if the new chunk number is valid |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
63 if (new_current_chunk < 0) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
64 new_current_chunk = 0; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
65 if ((unsigned int)new_current_chunk > film_data->total_chunks) |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
66 new_current_chunk = film_data->total_chunks - 1; |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
67 |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
68 while (((film_data->chunks[new_current_chunk].syncinfo1 == 0xFFFFFFFF) || |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
69 (film_data->chunks[new_current_chunk].syncinfo1 & 0x80000000)) && |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
70 (new_current_chunk > 0)) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
71 new_current_chunk--; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
72 |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
73 film_data->current_chunk = new_current_chunk; |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
74 |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
75 printf (" (flags = %X) actual new chunk = %d (syncinfo1 = %08X)\n", |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
76 flags, film_data->current_chunk, film_data->chunks[film_data->current_chunk].syncinfo1); |
4189 | 77 } |
78 | |
79 // return value: | |
80 // 0 = EOF or no stream found | |
81 // 1 = successfully read a packet | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
82 int demux_film_fill_buffer(demuxer_t *demuxer) |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
83 { |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
84 int i; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
85 unsigned char byte_swap; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
86 int cvid_size; |
4189 | 87 sh_video_t *sh_video = demuxer->video->sh; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
88 sh_audio_t *sh_audio = demuxer->audio->sh; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
89 film_data_t *film_data = (film_data_t *)demuxer->priv; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
90 film_chunk_t film_chunk; |
4189 | 91 |
92 // see if the end has been reached | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
93 if (film_data->current_chunk >= film_data->total_chunks) |
4189 | 94 return 0; |
95 | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
96 film_chunk = film_data->chunks[film_data->current_chunk]; |
4189 | 97 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
98 // position stream and fetch chunk |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
99 stream_seek(demuxer->stream, film_chunk.chunk_offset); |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
100 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
101 // load the chunks manually (instead of using ds_read_packet()), since |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
102 // they require some adjustment |
5143 | 103 // (all ones in syncinfo1 indicates an audio chunk) |
104 if (film_chunk.syncinfo1 == 0xFFFFFFFF) | |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
105 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
106 demux_packet_t* dp=new_demux_packet(film_chunk.chunk_size); |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
107 if (stream_read(demuxer->stream, dp->buffer, film_chunk.chunk_size) != |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
108 film_chunk.chunk_size) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
109 return 0; |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
110 dp->pts = film_chunk.pts; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
111 dp->pos = film_chunk.chunk_offset; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
112 dp->flags = 0; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
113 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
114 // adjust the data before queuing it: |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
115 // 8-bit: signed -> unsigned |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
116 // 16-bit: big-endian -> little-endian |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
117 if (sh_audio->wf->wBitsPerSample == 8) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
118 for (i = 0; i < film_chunk.chunk_size; i++) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
119 dp->buffer[i] += 128; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
120 else |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
121 for (i = 0; i < film_chunk.chunk_size; i += 2) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
122 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
123 byte_swap = dp->buffer[i]; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
124 dp->buffer[i] = dp->buffer[i + 1]; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
125 dp->buffer[i + 1] = byte_swap; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
126 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
127 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
128 // append packet to DS stream |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
129 ds_add_packet(demuxer->audio, dp); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
130 film_data->current_chunk++; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
131 } |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
132 else |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
133 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
134 // if the demuxer is dealing with CVID data, deal with it a special way |
5143 | 135 if (sh_video->format == mmioFOURCC('c', 'v', 'i', 'd')) |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
136 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
137 // account for 2 extra bytes |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
138 demux_packet_t* dp=new_demux_packet(film_chunk.chunk_size - 2); |
4189 | 139 |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
140 // these CVID data chunks appear to have 2 extra bytes; skip them |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
141 if (stream_read(demuxer->stream, dp->buffer, 10) != 10) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
142 return 0; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
143 stream_skip(demuxer->stream, 2); |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
144 if (stream_read(demuxer->stream, dp->buffer + 10, |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
145 film_chunk.chunk_size - 12) != (film_chunk.chunk_size - 12)) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
146 return 0; |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
147 dp->pts = film_chunk.pts; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
148 dp->pos = film_chunk.chunk_offset; |
5143 | 149 dp->flags = (film_chunk.syncinfo1 & 0x80000000) ? 1 : 0; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
150 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
151 // fix the CVID chunk size by adding 6 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
152 cvid_size = (dp->buffer[1] << 16) | (dp->buffer[2] << 8) | dp->buffer[3]; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
153 cvid_size += 6; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
154 dp->buffer[1] = (cvid_size >> 16) & 0xFF; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
155 dp->buffer[2] = (cvid_size >> 8) & 0xFF; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
156 dp->buffer[3] = (cvid_size >> 0) & 0xFF; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
157 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
158 // append packet to DS stream |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
159 ds_add_packet(demuxer->video, dp); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
160 film_data->current_chunk++; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
161 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
162 else |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
163 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
164 ds_read_packet(demuxer->video, demuxer->stream, film_chunk.chunk_size, |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
165 film_chunk.pts, |
5143 | 166 film_chunk.chunk_offset, (film_chunk.syncinfo1 & 0x80000000) ? 1 : 0); |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
167 film_data->current_chunk++; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
168 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
169 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
170 |
4189 | 171 return 1; |
172 } | |
173 | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
174 demuxer_t* demux_open_film(demuxer_t* demuxer) |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
175 { |
4189 | 176 sh_video_t *sh_video = NULL; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
177 sh_audio_t *sh_audio = NULL; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
178 film_data_t *film_data; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
179 film_chunk_t film_chunk; |
4189 | 180 int header_size; |
181 unsigned int chunk_type; | |
182 unsigned int chunk_size; | |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
183 unsigned int i; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
184 unsigned int video_format; |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
185 int audio_channels; |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
186 unsigned int film_version; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
187 int counting_chunks; |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
188 unsigned int total_audio_bytes = 0; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
189 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
190 film_data = (film_data_t *)malloc(sizeof(film_data_t)); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
191 film_data->total_chunks = 0; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
192 film_data->current_chunk = 0; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
193 film_data->chunks = NULL; |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
194 film_data->chunks_per_second = 0; |
4189 | 195 |
196 // go back to the beginning | |
197 stream_reset(demuxer->stream); | |
198 stream_seek(demuxer->stream, 0); | |
199 | |
200 // read the master chunk type | |
201 chunk_type = stream_read_fourcc(demuxer->stream); | |
202 // validate the chunk type | |
203 if (chunk_type != CHUNK_FILM) | |
204 { | |
205 mp_msg(MSGT_DEMUX, MSGL_ERR, "Not a FILM file\n"); | |
206 return(NULL); | |
207 } | |
208 | |
209 // get the header size, which implicitly points past the header and | |
210 // to the start of the data | |
211 header_size = stream_read_dword(demuxer->stream); | |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
212 film_version = stream_read_fourcc(demuxer->stream); |
4189 | 213 demuxer->movi_start = header_size; |
214 demuxer->movi_end = demuxer->stream->end_pos; | |
215 header_size -= 16; | |
216 | |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
217 mp_msg(MSGT_DEMUX, MSGL_HINT, "FILM version %.4s\n", &film_version); |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
218 |
4189 | 219 // skip to where the next chunk should be |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
220 stream_skip(demuxer->stream, 4); |
4189 | 221 |
222 // traverse through the header | |
223 while (header_size > 0) | |
224 { | |
225 // fetch the chunk type and size | |
226 chunk_type = stream_read_fourcc(demuxer->stream); | |
227 chunk_size = stream_read_dword(demuxer->stream); | |
228 header_size -= chunk_size; | |
229 | |
230 switch (chunk_type) | |
231 { | |
232 case CHUNK_FDSC: | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
233 mp_msg(MSGT_DECVIDEO, MSGL_V, "parsing FDSC chunk\n"); |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
234 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
235 // fetch the video codec fourcc to see if there's any video |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
236 video_format = stream_read_fourcc(demuxer->stream); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
237 if (video_format) |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
238 { |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
239 // create and initialize the video stream header |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
240 sh_video = new_sh_video(demuxer, 0); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
241 demuxer->video->sh = sh_video; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
242 sh_video->ds = demuxer->video; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
243 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
244 sh_video->format = video_format; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
245 sh_video->disp_h = stream_read_dword(demuxer->stream); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
246 sh_video->disp_w = stream_read_dword(demuxer->stream); |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
247 stream_skip(demuxer->stream, 1); // unknown byte |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
248 mp_msg(MSGT_DECVIDEO, MSGL_V, |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
249 " FILM video: %d x %d\n", sh_video->disp_w, |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
250 sh_video->disp_h); |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
251 } |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
252 else |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
253 stream_skip(demuxer->stream, 9); |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
254 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
255 // fetch the audio channels to see if there's any audio |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
256 audio_channels = stream_read_char(demuxer->stream); |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
257 if (audio_channels > 0) |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
258 { |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
259 // create and initialize the audio stream header |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
260 sh_audio = new_sh_audio(demuxer, 0); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
261 demuxer->audio->sh = sh_audio; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
262 sh_audio->ds = demuxer->audio; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
263 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
264 sh_audio->wf = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX)); |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
265 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
266 // uncompressed PCM format |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
267 sh_audio->wf->wFormatTag = 1; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
268 sh_audio->format = 1; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
269 sh_audio->wf->nChannels = audio_channels; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
270 sh_audio->wf->wBitsPerSample = stream_read_char(demuxer->stream); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
271 stream_skip(demuxer->stream, 1); // skip unknown byte |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
272 sh_audio->wf->nSamplesPerSec = stream_read_word(demuxer->stream); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
273 sh_audio->wf->nAvgBytesPerSec = |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
274 sh_audio->wf->nSamplesPerSec * sh_audio->wf->wBitsPerSample |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
275 * sh_audio->wf->nChannels / 8; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
276 stream_skip(demuxer->stream, 6); // skip the rest of the unknown |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
277 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
278 mp_msg(MSGT_DECVIDEO, MSGL_V, |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
279 " FILM audio: %d channels, %d bits, %d Hz\n", |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
280 sh_audio->wf->nChannels, 8 * sh_audio->wf->wBitsPerSample, |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
281 sh_audio->wf->nSamplesPerSec); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
282 } |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
283 else |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
284 stream_skip(demuxer->stream, 10); |
4189 | 285 break; |
286 | |
287 case CHUNK_STAB: | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
288 mp_msg(MSGT_DECVIDEO, MSGL_V, "parsing STAB chunk\n"); |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
289 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
290 if (sh_video) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
291 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
292 sh_video->fps = stream_read_dword(demuxer->stream); |
5143 | 293 sh_video->frametime = 1.0 / sh_video->fps; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
294 } |
4189 | 295 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
296 // fetch the number of chunks |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
297 film_data->total_chunks = stream_read_dword(demuxer->stream); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
298 film_data->current_chunk = 0; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
299 mp_msg(MSGT_DECVIDEO, MSGL_V, |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
300 " STAB chunk contains %d chunks\n", film_data->total_chunks); |
4189 | 301 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
302 // allocate enough entries for the chunk |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
303 film_data->chunks = |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
304 (film_chunk_t *)malloc(film_data->total_chunks * sizeof(film_chunk_t)); |
4189 | 305 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
306 // build the chunk index |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
307 counting_chunks = 1; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
308 for (i = 0; i < film_data->total_chunks; i++) |
4189 | 309 { |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
310 film_chunk = film_data->chunks[i]; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
311 film_chunk.chunk_offset = |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
312 demuxer->movi_start + stream_read_dword(demuxer->stream); |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
313 film_chunk.chunk_size = stream_read_dword(demuxer->stream); |
5143 | 314 film_chunk.syncinfo1 = stream_read_dword(demuxer->stream); |
315 film_chunk.syncinfo2 = stream_read_dword(demuxer->stream); | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
316 |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
317 // count chunks for the purposes of seeking |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
318 if (counting_chunks) |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
319 { |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
320 // if we're counting chunks, always count an audio chunk |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
321 if (film_chunk.syncinfo1 == 0xFFFFFFFF) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
322 film_data->chunks_per_second++; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
323 // if it's a video chunk, check if it's time to stop counting |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
324 else if ((film_chunk.syncinfo1 & 0x7FFFFFFF) >= sh_video->fps) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
325 counting_chunks = 0; |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
326 else |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
327 film_data->chunks_per_second++; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
328 } |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
329 |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
330 // precalculate PTS |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
331 if (film_chunk.syncinfo1 == 0xFFFFFFFF) |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
332 { |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
333 film_chunk.pts = |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
334 (float)total_audio_bytes / (float)sh_audio->wf->nAvgBytesPerSec; |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
335 total_audio_bytes += film_chunk.chunk_size; |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
336 } |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
337 else |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
338 film_chunk.pts = |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
339 (film_chunk.syncinfo1 & 0x7FFFFFFF) / sh_video->fps; |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
340 |
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
341 film_data->chunks[i] = film_chunk; |
4189 | 342 } |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
343 |
5181
81ef0f0b285f
added PTS for audio, but seeking still doesn't work
melanson
parents:
5157
diff
changeset
|
344 // in some FILM files (notably '1.09'), the length of the FDSC chunk |
5157
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
345 // follows different rules |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
346 if (chunk_size == (film_data->total_chunks * 16)) |
f67b321e1eda
FILM demuxer is leaner, meaner, and cleaner, also with proper bailout on
melanson
parents:
5143
diff
changeset
|
347 header_size -= 16; |
4189 | 348 break; |
349 | |
350 default: | |
351 mp_msg(MSGT_DEMUX, MSGL_ERR, "Unrecognized FILM header chunk: %08X\n", | |
352 chunk_type); | |
353 return(NULL); | |
354 break; | |
355 } | |
356 } | |
357 | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
358 demuxer->priv = film_data; |
4189 | 359 |
360 return demuxer; | |
361 } |