Mercurial > mplayer.hg
annotate libmpdemux/demux_film.c @ 5037:0ef48d850bc9
hopefully fixed divx5 header + xvid conflict
author | arpi |
---|---|
date | Mon, 11 Mar 2002 00:39:40 +0000 |
parents | 1504901deed8 |
children | 3958674b696b |
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 | |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
26 #define VERSION_1_01 mmioFOURCC('1', '.', '0', '1') |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
27 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
28 #define MAGIC_FPS_CONSTANT 27 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
29 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
30 typedef struct _film_chunk_t |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
31 { |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
32 off_t chunk_offset; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
33 int chunk_size; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
34 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
35 unsigned int flags1; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
36 unsigned int flags2; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
37 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
38 unsigned int video_chunk_number; // in the case of a video chunk |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
39 unsigned int running_audio_sample_count; // for an audio chunk |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
40 } film_chunk_t; |
4189 | 41 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
42 typedef struct _film_data_t |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
43 { |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
44 int total_chunks; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
45 int current_chunk; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
46 int total_video_chunks; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
47 int total_audio_sample_count; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
48 film_chunk_t *chunks; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
49 unsigned int ticks; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
50 unsigned int film_version; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
51 } film_data_t; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
52 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
53 #if 0 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
54 void demux_seek_film(demuxer_t *demuxer,float rel_seek_secs,int flags) |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
55 { |
4189 | 56 film_frames_t *frames = (film_frames_t *)demuxer->priv; |
57 sh_video_t *sh_video = demuxer->video->sh; | |
58 int newpos=(flags&1)?0:frames->current_frame; | |
59 if(flags&2){ | |
60 // float 0..1 | |
61 newpos+=rel_seek_secs*frames->num_frames; | |
62 } else { | |
63 // secs | |
64 newpos+=rel_seek_secs*sh_video->fps; | |
65 } | |
66 if(newpos<0) newpos=0; else | |
67 if(newpos>frames->num_frames) newpos=frames->num_frames; | |
68 frames->current_frame=newpos; | |
69 } | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
70 #endif |
4189 | 71 |
72 // return value: | |
73 // 0 = EOF or no stream found | |
74 // 1 = successfully read a packet | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
75 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
|
76 { |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
77 int i; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
78 unsigned char byte_swap; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
79 int cvid_size; |
4189 | 80 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
|
81 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
|
82 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
|
83 film_chunk_t film_chunk; |
4189 | 84 |
85 // 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
|
86 if (film_data->current_chunk >= film_data->total_chunks) |
4189 | 87 return 0; |
88 | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
89 film_chunk = film_data->chunks[film_data->current_chunk]; |
4189 | 90 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
91 // position stream and fetch chunk |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
92 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
|
93 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
94 // 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
|
95 // they require some adjustment |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
96 // (all ones in flags1 indicates an audio chunk) |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
97 if (film_chunk.flags1 == 0xFFFFFFFF) |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
98 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
99 demux_packet_t* dp=new_demux_packet(film_chunk.chunk_size); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
100 stream_read(demuxer->stream, dp->buffer, film_chunk.chunk_size); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
101 dp->pts = 0; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
102 dp->pos = film_chunk.chunk_offset; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
103 dp->flags = 0; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
104 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
105 // adjust the data before queuing it: |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
106 // 8-bit: signed -> unsigned |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
107 // 16-bit: big-endian -> little-endian |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
108 if (sh_audio->wf->wBitsPerSample == 8) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
109 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
|
110 dp->buffer[i] += 128; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
111 else |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
112 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
|
113 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
114 byte_swap = dp->buffer[i]; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
115 dp->buffer[i] = dp->buffer[i + 1]; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
116 dp->buffer[i + 1] = byte_swap; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
117 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
118 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
119 // append packet to DS stream |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
120 ds_add_packet(demuxer->audio, dp); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
121 film_data->current_chunk++; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
122 } |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
123 else |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
124 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
125 // check the tick to see if it's time to dispatch a new frame |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
126 if ((film_data->film_version == VERSION_1_01) && |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
127 ((film_chunk.flags1 & 0x7FFFFFFF) != film_data->ticks++)) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
128 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
129 demux_packet_t* dp=new_demux_packet(0); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
130 dp->pts = 0; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
131 dp->pos = 0; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
132 dp->flags = 0; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
133 ds_add_packet(demuxer->video, dp); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
134 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
135 // if the demuxer is dealing with CVID data, deal with it a special way |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
136 else if (sh_video->format == mmioFOURCC('c', 'v', 'i', 'd')) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
137 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
138 // account for 2 extra bytes |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
139 demux_packet_t* dp=new_demux_packet(film_chunk.chunk_size - 2); |
4189 | 140 |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
141 // these CVID data chunks appear to have 2 extra bytes; skip them |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
142 stream_read(demuxer->stream, dp->buffer, 10); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
143 stream_skip(demuxer->stream, 2); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
144 stream_read(demuxer->stream, dp->buffer + 10, film_chunk.chunk_size - 12); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
145 dp->pts = film_chunk.video_chunk_number / sh_video->fps; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
146 dp->pos = film_chunk.chunk_offset; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
147 dp->flags = (film_chunk.flags1 & 0x80000000) ? 1 : 0; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
148 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
149 // 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
|
150 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
|
151 cvid_size += 6; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
152 dp->buffer[1] = (cvid_size >> 16) & 0xFF; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
153 dp->buffer[2] = (cvid_size >> 8) & 0xFF; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
154 dp->buffer[3] = (cvid_size >> 0) & 0xFF; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
155 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
156 // append packet to DS stream |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
157 ds_add_packet(demuxer->video, dp); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
158 film_data->current_chunk++; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
159 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
160 else |
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 ds_read_packet(demuxer->video, demuxer->stream, film_chunk.chunk_size, |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
163 film_chunk.video_chunk_number / sh_video->fps, /* pts */ |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
164 film_chunk.chunk_offset, (film_chunk.flags1 & 0x80000000) ? 1 : 0); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
165 film_data->current_chunk++; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
166 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
167 } |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
168 |
4189 | 169 return 1; |
170 } | |
171 | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
172 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
|
173 { |
4189 | 174 sh_video_t *sh_video = NULL; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
175 sh_audio_t *sh_audio = NULL; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
176 film_data_t *film_data; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
177 film_chunk_t film_chunk; |
4189 | 178 int header_size; |
179 unsigned int chunk_type; | |
180 unsigned int chunk_size; | |
181 int i; | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
182 unsigned int video_format; |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
183 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
184 int largest_audio_chunk = 0; |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
185 int audio_channels; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
186 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
187 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
|
188 film_data->total_chunks = 0; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
189 film_data->current_chunk = 0; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
190 film_data->total_video_chunks = 0; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
191 film_data->chunks = NULL; |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
192 film_data->ticks = 0; |
4189 | 193 |
194 // go back to the beginning | |
195 stream_reset(demuxer->stream); | |
196 stream_seek(demuxer->stream, 0); | |
197 | |
198 // read the master chunk type | |
199 chunk_type = stream_read_fourcc(demuxer->stream); | |
200 // validate the chunk type | |
201 if (chunk_type != CHUNK_FILM) | |
202 { | |
203 mp_msg(MSGT_DEMUX, MSGL_ERR, "Not a FILM file\n"); | |
204 return(NULL); | |
205 } | |
206 | |
207 // get the header size, which implicitly points past the header and | |
208 // to the start of the data | |
209 header_size = stream_read_dword(demuxer->stream); | |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
210 film_data->film_version = stream_read_fourcc(demuxer->stream); |
4189 | 211 demuxer->movi_start = header_size; |
212 demuxer->movi_end = demuxer->stream->end_pos; | |
213 header_size -= 16; | |
214 | |
215 // 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
|
216 stream_skip(demuxer->stream, 4); |
4189 | 217 |
218 // traverse through the header | |
219 while (header_size > 0) | |
220 { | |
221 // fetch the chunk type and size | |
222 chunk_type = stream_read_fourcc(demuxer->stream); | |
223 chunk_size = stream_read_dword(demuxer->stream); | |
224 header_size -= chunk_size; | |
225 | |
226 switch (chunk_type) | |
227 { | |
228 case CHUNK_FDSC: | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
229 mp_msg(MSGT_DECVIDEO, MSGL_V, "parsing FDSC chunk\n"); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
230 // 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
|
231 video_format = stream_read_fourcc(demuxer->stream); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
232 if (video_format) |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
233 { |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
234 // create and initialize the video stream header |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
235 sh_video = new_sh_video(demuxer, 0); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
236 demuxer->video->sh = sh_video; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
237 sh_video->ds = demuxer->video; |
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 sh_video->format = video_format; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
240 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
|
241 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
|
242 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
|
243 mp_msg(MSGT_DECVIDEO, MSGL_V, |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
244 " 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
|
245 sh_video->disp_h); |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
246 } |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
247 else |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
248 stream_skip(demuxer->stream, 9); |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
249 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
250 // 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
|
251 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
|
252 if (audio_channels > 0) |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
253 { |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
254 // create and initialize the audio stream header |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
255 sh_audio = new_sh_audio(demuxer, 0); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
256 demuxer->audio->sh = sh_audio; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
257 sh_audio->ds = demuxer->audio; |
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 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
|
260 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
261 // uncompressed PCM format |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
262 sh_audio->wf->wFormatTag = 1; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
263 sh_audio->format = 1; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
264 sh_audio->wf->nChannels = audio_channels; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
265 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
|
266 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
|
267 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
|
268 sh_audio->wf->nAvgBytesPerSec = |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
269 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
|
270 * sh_audio->wf->nChannels / 8; |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
271 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
|
272 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
273 mp_msg(MSGT_DECVIDEO, MSGL_V, |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
274 " 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
|
275 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
|
276 sh_audio->wf->nSamplesPerSec); |
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 else |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
279 stream_skip(demuxer->stream, 10); |
4189 | 280 break; |
281 | |
282 case CHUNK_STAB: | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
283 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
|
284 |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
285 // FPS hack based on empirical observation |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
286 if (sh_video) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
287 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
288 sh_video->fps = stream_read_dword(demuxer->stream); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
289 if (film_data->film_version != VERSION_1_01) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
290 sh_video->fps = MAGIC_FPS_CONSTANT; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
291 sh_video->frametime = 1 / sh_video->fps; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
292 } |
4189 | 293 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
294 // fetch the number of chunks |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
295 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
|
296 film_data->current_chunk = 0; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
297 mp_msg(MSGT_DECVIDEO, MSGL_V, |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
298 " STAB chunk contains %d chunks\n", film_data->total_chunks); |
4189 | 299 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
300 // allocate enough entries for the chunk |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
301 film_data->chunks = |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
302 (film_chunk_t *)malloc(film_data->total_chunks * sizeof(film_chunk_t)); |
4189 | 303 |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
304 // build the chunk index |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
305 for (i = 0; i < film_data->total_chunks; i++) |
4189 | 306 { |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
307 film_chunk = film_data->chunks[i]; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
308 film_chunk.chunk_offset = |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
309 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
|
310 film_chunk.chunk_size = stream_read_dword(demuxer->stream); |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
311 film_chunk.flags1 = stream_read_dword(demuxer->stream); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
312 film_chunk.flags2 = stream_read_dword(demuxer->stream); |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
313 film_data->chunks[i] = film_chunk; |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
314 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
315 // audio housekeeping |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
316 if (sh_audio) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
317 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
318 if ((film_chunk.flags1 == 0xFFFFFFFF) && |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
319 (film_chunk.chunk_size > largest_audio_chunk)) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
320 largest_audio_chunk = film_chunk.chunk_size; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
321 film_data->total_audio_sample_count += |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
322 (chunk_size / sh_audio->wf->nChannels); |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
323 } |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
324 |
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
325 // video housekeeping |
4628
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
326 if (sh_video) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
327 { |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
328 if (film_chunk.flags1 != 0xFFFFFFFF) |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
329 film_chunk.video_chunk_number = |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
330 film_data->total_video_chunks++; |
1504901deed8
Fixed FILM demuxer so that it now plays (my) FILM files
melanson
parents:
4564
diff
changeset
|
331 } |
4189 | 332 } |
333 break; | |
334 | |
335 default: | |
336 mp_msg(MSGT_DEMUX, MSGL_ERR, "Unrecognized FILM header chunk: %08X\n", | |
337 chunk_type); | |
338 return(NULL); | |
339 break; | |
340 } | |
341 } | |
342 | |
4564
5e1221d4655e
completely reworked FILM demuxer to support both audio and video...neither
melanson
parents:
4226
diff
changeset
|
343 demuxer->priv = film_data; |
4189 | 344 |
345 return demuxer; | |
346 } |