Mercurial > mplayer.hg
annotate libmpdemux/demux_film.c @ 4364:819eeb32159f
goto man mplayer, leyma
author | gabucino |
---|---|
date | Sat, 26 Jan 2002 20:12:20 +0000 |
parents | 63baf6de03e1 |
children | 5e1221d4655e |
rev | line source |
---|---|
4189 | 1 /* |
2 FILM file parser for the MPlayer program | |
3 by Mike Melanson | |
4 */ | |
5 | |
6 #include <stdio.h> | |
7 #include <stdlib.h> | |
8 #include <unistd.h> | |
9 | |
10 #include "config.h" | |
11 #include "mp_msg.h" | |
12 #include "help_mp.h" | |
13 | |
14 #include "stream.h" | |
15 #include "demuxer.h" | |
16 #include "stheader.h" | |
17 | |
18 // chunk types found in a FILM file | |
19 #define CHUNK_FILM mmioFOURCC('F', 'I', 'L', 'M') | |
20 #define CHUNK_FDSC mmioFOURCC('F', 'D', 'S', 'C') | |
21 #define CHUNK_STAB mmioFOURCC('S', 'T', 'A', 'B') | |
22 | |
23 typedef struct _film_frames_t { | |
24 int num_frames; | |
25 int current_frame; | |
26 off_t *filepos; | |
27 unsigned int *frame_size; | |
28 unsigned int *flags1; | |
29 unsigned int *flags2; | |
30 } film_frames_t; | |
31 | |
32 void demux_seek_film(demuxer_t *demuxer,float rel_seek_secs,int flags){ | |
33 film_frames_t *frames = (film_frames_t *)demuxer->priv; | |
34 sh_video_t *sh_video = demuxer->video->sh; | |
35 int newpos=(flags&1)?0:frames->current_frame; | |
36 if(flags&2){ | |
37 // float 0..1 | |
38 newpos+=rel_seek_secs*frames->num_frames; | |
39 } else { | |
40 // secs | |
41 newpos+=rel_seek_secs*sh_video->fps; | |
42 } | |
43 if(newpos<0) newpos=0; else | |
44 if(newpos>frames->num_frames) newpos=frames->num_frames; | |
45 frames->current_frame=newpos; | |
46 } | |
47 | |
48 // return value: | |
49 // 0 = EOF or no stream found | |
50 // 1 = successfully read a packet | |
51 int demux_film_fill_buffer(demuxer_t *demuxer){ | |
52 film_frames_t *frames = (film_frames_t *)demuxer->priv; | |
53 sh_video_t *sh_video = demuxer->video->sh; | |
54 | |
55 // see if the end has been reached | |
56 if (frames->current_frame >= frames->num_frames) | |
57 return 0; | |
58 | |
59 // fetch the frame from the file | |
60 // first, position the file properly since ds_read_packet() doesn't | |
61 // seem to do it, even though it takes a file offset as a parameter | |
62 stream_seek(demuxer->stream, frames->filepos[frames->current_frame]); | |
63 ds_read_packet(demuxer->video, | |
64 demuxer->stream, | |
65 frames->frame_size[frames->current_frame], | |
66 frames->current_frame/sh_video->fps, | |
67 frames->filepos[frames->current_frame], | |
68 0 /* what flags? -> demuxer.h (alex) */ | |
69 ); | |
70 | |
71 // get the next frame ready | |
72 frames->current_frame++; | |
73 | |
74 return 1; | |
75 } | |
76 | |
77 demuxer_t* demux_open_film(demuxer_t* demuxer){ | |
78 sh_video_t *sh_video = NULL; | |
79 film_frames_t *frames = (film_frames_t *)malloc(sizeof(film_frames_t)); | |
80 int header_size; | |
81 unsigned int chunk_type; | |
82 unsigned int chunk_size; | |
83 int i; | |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
84 int frame_number; |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
85 |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
86 int audio_channels; |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
87 int audio_bits; |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
88 int audio_frequency; |
4189 | 89 |
90 // go back to the beginning | |
91 stream_reset(demuxer->stream); | |
92 stream_seek(demuxer->stream, 0); | |
93 | |
94 // read the master chunk type | |
95 chunk_type = stream_read_fourcc(demuxer->stream); | |
96 // validate the chunk type | |
97 if (chunk_type != CHUNK_FILM) | |
98 { | |
99 mp_msg(MSGT_DEMUX, MSGL_ERR, "Not a FILM file\n"); | |
100 return(NULL); | |
101 } | |
102 | |
103 // get the header size, which implicitly points past the header and | |
104 // to the start of the data | |
105 header_size = stream_read_dword(demuxer->stream); | |
106 demuxer->movi_start = header_size; | |
107 demuxer->movi_end = demuxer->stream->end_pos; | |
108 header_size -= 16; | |
109 | |
110 // skip to where the next chunk should be | |
111 stream_skip(demuxer->stream, 8); | |
112 | |
113 // create a new video stream header | |
114 sh_video = new_sh_video(demuxer, 0); | |
115 | |
116 // make sure the demuxer knows about the new video stream header | |
117 demuxer->video->sh = sh_video; | |
118 | |
119 // make sure that the video demuxer stream header knows about its | |
120 // parent video demuxer stream, or else | |
121 // video_read_properties() will choke | |
122 sh_video->ds = demuxer->video; | |
123 | |
124 // traverse through the header | |
125 while (header_size > 0) | |
126 { | |
127 // fetch the chunk type and size | |
128 chunk_type = stream_read_fourcc(demuxer->stream); | |
129 chunk_size = stream_read_dword(demuxer->stream); | |
130 header_size -= chunk_size; | |
131 | |
132 switch (chunk_type) | |
133 { | |
134 case CHUNK_FDSC: | |
135 printf ("parsing FDSC chunk\n"); | |
136 // fetch the video codec fourcc, height, then width | |
137 sh_video->format = stream_read_fourcc(demuxer->stream); | |
138 sh_video->disp_h = stream_read_dword(demuxer->stream); | |
139 sh_video->disp_w = stream_read_dword(demuxer->stream); | |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
140 sh_video->fps = stream_read_char(demuxer->stream); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
141 sh_video->frametime = 1/sh_video->fps; |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
142 printf (" FILM video: %d x %d, %f fps\n", sh_video->disp_w, |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
143 sh_video->disp_h, sh_video->fps); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
144 |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
145 // temporary: These will eventually go directly into an audio structure |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
146 // of some sort |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
147 audio_channels = stream_read_char(demuxer->stream); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
148 audio_bits = stream_read_char(demuxer->stream); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
149 stream_skip(demuxer->stream, 1); // skip unknown byte |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
150 audio_frequency = stream_read_word(demuxer->stream); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
151 printf (" FILM audio: %d channels, %d bits, %d Hz\n", |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
152 audio_channels, audio_bits, audio_frequency); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
153 |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
154 stream_skip(demuxer->stream, 6); |
4189 | 155 break; |
156 | |
157 case CHUNK_STAB: | |
158 printf ("parsing STAB chunk\n"); | |
159 // skip unknown dword | |
160 stream_skip(demuxer->stream, 4); | |
161 | |
162 // fetch the number of frames | |
163 frames->num_frames = stream_read_dword(demuxer->stream); | |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
164 frames->current_frame = 0; |
4189 | 165 |
166 // allocate enough entries for the indices | |
167 frames->filepos = (off_t *)malloc(frames->num_frames * sizeof(off_t)); | |
168 frames->frame_size = (int *)malloc(frames->num_frames * sizeof(int)); | |
169 frames->flags1 = (int *)malloc(frames->num_frames * sizeof(int)); | |
170 frames->flags2 = (int *)malloc(frames->num_frames * sizeof(int)); | |
171 | |
172 // build the frame index | |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
173 frame_number = 0; |
4189 | 174 for (i = 0; i < frames->num_frames; i++) |
175 { | |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
176 if (frames->flags1[i] == 0) |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
177 { |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
178 frames->filepos[frame_number] = demuxer->movi_start + stream_read_dword(demuxer->stream); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
179 frames->frame_size[frame_number] = stream_read_dword(demuxer->stream) - 8; |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
180 frames->flags1[frame_number] = stream_read_dword(demuxer->stream); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
181 frames->flags2[frame_number] = stream_read_dword(demuxer->stream); |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
182 frame_number++; |
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
183 } |
4189 | 184 } |
4226
63baf6de03e1
made a little more headway but it still doesn't work properly
melanson
parents:
4189
diff
changeset
|
185 frames->num_frames = frame_number; |
4189 | 186 break; |
187 | |
188 default: | |
189 mp_msg(MSGT_DEMUX, MSGL_ERR, "Unrecognized FILM header chunk: %08X\n", | |
190 chunk_type); | |
191 return(NULL); | |
192 break; | |
193 } | |
194 } | |
195 | |
196 // hard code the speed for now | |
197 sh_video->fps = 1; | |
198 sh_video->frametime = 1; | |
199 | |
200 demuxer->priv = frames; | |
201 | |
202 return demuxer; | |
203 } |