summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demux_film.c
diff options
context:
space:
mode:
authormelanson <melanson@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-02-07 05:55:29 +0000
committermelanson <melanson@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-02-07 05:55:29 +0000
commitc3c9527d3eccd66fd2ade4dfaddaa03a8b77e3eb (patch)
tree6456d6cac9bbf0c65490624e16e9c260e6565e8e /libmpdemux/demux_film.c
parent37892b081974cd5a7305587155a10aaf9a6bc893 (diff)
downloadmpv-c3c9527d3eccd66fd2ade4dfaddaa03a8b77e3eb.tar.bz2
mpv-c3c9527d3eccd66fd2ade4dfaddaa03a8b77e3eb.tar.xz
completely reworked FILM demuxer to support both audio and video...neither
of which work yet (CVID video and uncompressed audio)...but the demuxer is working well now git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4565 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux/demux_film.c')
-rw-r--r--libmpdemux/demux_film.c226
1 files changed, 138 insertions, 88 deletions
diff --git a/libmpdemux/demux_film.c b/libmpdemux/demux_film.c
index 1a70bceafc..0c8650ca79 100644
--- a/libmpdemux/demux_film.c
+++ b/libmpdemux/demux_film.c
@@ -20,16 +20,30 @@
#define CHUNK_FDSC mmioFOURCC('F', 'D', 'S', 'C')
#define CHUNK_STAB mmioFOURCC('S', 'T', 'A', 'B')
-typedef struct _film_frames_t {
- int num_frames;
- int current_frame;
- off_t *filepos;
- unsigned int *frame_size;
- unsigned int *flags1;
- unsigned int *flags2;
-} film_frames_t;
-
-void demux_seek_film(demuxer_t *demuxer,float rel_seek_secs,int flags){
+typedef struct _film_chunk_t
+{
+ off_t chunk_offset;
+ int chunk_size;
+
+ unsigned int flags1;
+ unsigned int flags2;
+
+ unsigned int video_chunk_number; // in the case of a video chunk
+ unsigned int running_audio_sample_count; // for an audio chunk
+} film_chunk_t;
+
+typedef struct _film_data_t
+{
+ int total_chunks;
+ int current_chunk;
+ int total_video_chunks;
+ int total_audio_sample_count;
+ film_chunk_t *chunks;
+} film_data_t;
+
+#if 0
+void demux_seek_film(demuxer_t *demuxer,float rel_seek_secs,int flags)
+{
film_frames_t *frames = (film_frames_t *)demuxer->priv;
sh_video_t *sh_video = demuxer->video->sh;
int newpos=(flags&1)?0:frames->current_frame;
@@ -44,48 +58,58 @@ void demux_seek_film(demuxer_t *demuxer,float rel_seek_secs,int flags){
if(newpos>frames->num_frames) newpos=frames->num_frames;
frames->current_frame=newpos;
}
+#endif
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
-int demux_film_fill_buffer(demuxer_t *demuxer){
- film_frames_t *frames = (film_frames_t *)demuxer->priv;
+int demux_film_fill_buffer(demuxer_t *demuxer)
+{
sh_video_t *sh_video = demuxer->video->sh;
+ film_data_t *film_data = (film_data_t *)demuxer->priv;
+ film_chunk_t film_chunk;
// see if the end has been reached
- if (frames->current_frame >= frames->num_frames)
+ if (film_data->current_chunk >= film_data->total_chunks)
return 0;
- // fetch the frame from the file
- // first, position the file properly since ds_read_packet() doesn't
- // seem to do it, even though it takes a file offset as a parameter
- stream_seek(demuxer->stream, frames->filepos[frames->current_frame]);
- ds_read_packet(demuxer->video,
- demuxer->stream,
- frames->frame_size[frames->current_frame],
- frames->current_frame/sh_video->fps,
- frames->filepos[frames->current_frame],
- 0 /* what flags? -> demuxer.h (alex) */
- );
-
- // get the next frame ready
- frames->current_frame++;
+ film_chunk = film_data->chunks[film_data->current_chunk];
+
+ // position stream and fetch chunk
+ stream_seek(demuxer->stream, film_chunk.chunk_offset);
+ if (film_chunk.flags1 == 0xFFFFFFFF)
+ ds_read_packet(demuxer->audio, demuxer->stream, film_chunk.chunk_size,
+ 0, /* pts */
+ film_chunk.chunk_offset, 0);
+ else
+ ds_read_packet(demuxer->video, demuxer->stream, film_chunk.chunk_size,
+ film_chunk.video_chunk_number / sh_video->fps,
+ film_chunk.chunk_offset, 0);
+ film_data->current_chunk++;
return 1;
}
-demuxer_t* demux_open_film(demuxer_t* demuxer){
+demuxer_t* demux_open_film(demuxer_t* demuxer)
+{
sh_video_t *sh_video = NULL;
- film_frames_t *frames = (film_frames_t *)malloc(sizeof(film_frames_t));
+ sh_audio_t *sh_audio = NULL;
+ film_data_t *film_data;
+ film_chunk_t film_chunk;
int header_size;
unsigned int chunk_type;
unsigned int chunk_size;
int i;
- int frame_number;
+ unsigned int video_format;
+ int largest_audio_chunk = 0;
int audio_channels;
- int audio_bits;
- int audio_frequency;
+
+ film_data = (film_data_t *)malloc(sizeof(film_data_t));
+ film_data->total_chunks = 0;
+ film_data->current_chunk = 0;
+ film_data->total_video_chunks = 0;
+ film_data->chunks = NULL;
// go back to the beginning
stream_reset(demuxer->stream);
@@ -110,17 +134,6 @@ demuxer_t* demux_open_film(demuxer_t* demuxer){
// skip to where the next chunk should be
stream_skip(demuxer->stream, 8);
- // create a new video stream header
- sh_video = new_sh_video(demuxer, 0);
-
- // make sure the demuxer knows about the new video stream header
- demuxer->video->sh = sh_video;
-
- // make sure that the video demuxer stream header knows about its
- // parent video demuxer stream, or else
- // video_read_properties() will choke
- sh_video->ds = demuxer->video;
-
// traverse through the header
while (header_size > 0)
{
@@ -132,57 +145,98 @@ demuxer_t* demux_open_film(demuxer_t* demuxer){
switch (chunk_type)
{
case CHUNK_FDSC:
-printf ("parsing FDSC chunk\n");
- // fetch the video codec fourcc, height, then width
- sh_video->format = stream_read_fourcc(demuxer->stream);
- sh_video->disp_h = stream_read_dword(demuxer->stream);
- sh_video->disp_w = stream_read_dword(demuxer->stream);
- sh_video->fps = stream_read_char(demuxer->stream);
- sh_video->frametime = 1/sh_video->fps;
-printf (" FILM video: %d x %d, %f fps\n", sh_video->disp_w,
- sh_video->disp_h, sh_video->fps);
-
- // temporary: These will eventually go directly into an audio structure
- // of some sort
- audio_channels = stream_read_char(demuxer->stream);
- audio_bits = stream_read_char(demuxer->stream);
- stream_skip(demuxer->stream, 1); // skip unknown byte
- audio_frequency = stream_read_word(demuxer->stream);
-printf (" FILM audio: %d channels, %d bits, %d Hz\n",
- audio_channels, audio_bits, audio_frequency);
+ mp_msg(MSGT_DECVIDEO, MSGL_V, "parsing FDSC chunk\n");
+ // fetch the video codec fourcc to see if there's any video
+ video_format = stream_read_fourcc(demuxer->stream);
+ if (video_format)
+ {
+ // create and initialize the video stream header
+ sh_video = new_sh_video(demuxer, 0);
+ demuxer->video->sh = sh_video;
+ sh_video->ds = demuxer->video;
+
+ sh_video->format = video_format;
+ sh_video->disp_h = stream_read_dword(demuxer->stream);
+ sh_video->disp_w = stream_read_dword(demuxer->stream);
+ sh_video->fps = stream_read_char(demuxer->stream);
+ sh_video->frametime = 1/sh_video->fps;
+ mp_msg(MSGT_DECVIDEO, MSGL_V,
+ " FILM video: %d x %d, %f fps\n", sh_video->disp_w,
+ sh_video->disp_h, sh_video->fps);
+ }
+ else
+ stream_skip(demuxer->stream, 9);
- stream_skip(demuxer->stream, 6);
+ // fetch the audio channels to see if there's any audio
+ audio_channels = stream_read_char(demuxer->stream);
+ if (audio_channels > 0)
+ {
+ // create and initialize the audio stream header
+ sh_audio = new_sh_audio(demuxer, 0);
+ demuxer->audio->sh = sh_audio;
+ sh_audio->ds = demuxer->audio;
+
+ // go through the bother of making a WAVEFORMATEX structure
+ sh_audio->wf = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX));
+
+ // uncompressed PCM format
+ sh_audio->wf->wFormatTag = 1;
+ sh_audio->format = 1;
+ sh_audio->wf->nChannels = audio_channels;
+ sh_audio->wf->wBitsPerSample = stream_read_char(demuxer->stream);
+ stream_skip(demuxer->stream, 1); // skip unknown byte
+ sh_audio->wf->nSamplesPerSec = stream_read_word(demuxer->stream);
+ sh_audio->wf->nAvgBytesPerSec =
+ sh_audio->wf->nSamplesPerSec * sh_audio->wf->wBitsPerSample / 8;
+ stream_skip(demuxer->stream, 6); // skip the rest of the unknown
+
+ mp_msg(MSGT_DECVIDEO, MSGL_V,
+ " FILM audio: %d channels, %d bits, %d Hz\n",
+ sh_audio->wf->nChannels, 8 * sh_audio->wf->wBitsPerSample,
+ sh_audio->wf->nSamplesPerSec);
+ }
+ else
+ stream_skip(demuxer->stream, 10);
break;
case CHUNK_STAB:
-printf ("parsing STAB chunk\n");
+ mp_msg(MSGT_DECVIDEO, MSGL_V, "parsing STAB chunk\n");
// skip unknown dword
stream_skip(demuxer->stream, 4);
- // fetch the number of frames
- frames->num_frames = stream_read_dword(demuxer->stream);
- frames->current_frame = 0;
+ // fetch the number of chunks
+ film_data->total_chunks = stream_read_dword(demuxer->stream);
+ film_data->current_chunk = 0;
+ mp_msg(MSGT_DECVIDEO, MSGL_V,
+ " STAB chunk contains %d chunks\n", film_data->total_chunks);
- // allocate enough entries for the indices
- frames->filepos = (off_t *)malloc(frames->num_frames * sizeof(off_t));
- frames->frame_size = (int *)malloc(frames->num_frames * sizeof(int));
- frames->flags1 = (int *)malloc(frames->num_frames * sizeof(int));
- frames->flags2 = (int *)malloc(frames->num_frames * sizeof(int));
+ // allocate enough entries for the chunk
+ film_data->chunks =
+ (film_chunk_t *)malloc(film_data->total_chunks * sizeof(film_chunk_t));
- // build the frame index
- frame_number = 0;
- for (i = 0; i < frames->num_frames; i++)
+ // build the chunk index
+ for (i = 0; i < film_data->total_chunks; i++)
{
- if (frames->flags1[i] == 0)
- {
- frames->filepos[frame_number] = demuxer->movi_start + stream_read_dword(demuxer->stream);
- frames->frame_size[frame_number] = stream_read_dword(demuxer->stream) - 8;
- frames->flags1[frame_number] = stream_read_dword(demuxer->stream);
- frames->flags2[frame_number] = stream_read_dword(demuxer->stream);
- frame_number++;
- }
+ film_chunk = film_data->chunks[i];
+ film_chunk.chunk_offset =
+ demuxer->movi_start + stream_read_dword(demuxer->stream);
+ film_chunk.chunk_size = stream_read_dword(demuxer->stream) - 8;
+ film_chunk.flags1 = stream_read_dword(demuxer->stream);
+ film_chunk.flags2 = stream_read_dword(demuxer->stream);
+ film_data->chunks[i] = film_chunk;
+
+ // audio housekeeping
+ if ((film_chunk.flags1 == 0xFFFFFFFF) &&
+ (film_chunk.chunk_size > largest_audio_chunk))
+ largest_audio_chunk = film_chunk.chunk_size;
+ film_data->total_audio_sample_count +=
+ (chunk_size / sh_audio->wf->nChannels);
+
+ // video housekeeping
+ if (film_chunk.flags1 != 0xFFFFFFFF)
+ film_chunk.video_chunk_number =
+ film_data->total_video_chunks++;
}
- frames->num_frames = frame_number;
break;
default:
@@ -193,11 +247,7 @@ printf ("parsing STAB chunk\n");
}
}
- // hard code the speed for now
- sh_video->fps = 1;
- sh_video->frametime = 1;
-
- demuxer->priv = frames;
+ demuxer->priv = film_data;
return demuxer;
}