# HG changeset patch # User melanson # Date 1012689347 0 # Node ID eaa4a2242552ed10a46b51978d8af803b83d641d # Parent c150a35fd22b45bc2790e3e7dabf483bf4dba0ed demuxer is now more complete, though still not perfect diff -r c150a35fd22b -r eaa4a2242552 libmpdemux/demux_roq.c --- a/libmpdemux/demux_roq.c Sat Feb 02 21:39:25 2002 +0000 +++ b/libmpdemux/demux_roq.c Sat Feb 02 22:35:47 2002 +0000 @@ -33,12 +33,17 @@ int chunk_type; off_t chunk_offset; int chunk_size; + + int video_chunk_number; // in the case of a video chunk + int running_audio_sample_count; // for an audio chunk } roq_chunk_t; typedef struct roq_data_t { int total_chunks; int current_chunk; + int total_video_chunks; + int total_audio_sample_count; roq_chunk_t *chunks; } roq_data_t; @@ -62,30 +67,26 @@ // 1 = successfully read a packet int demux_roq_fill_buffer(demuxer_t *demuxer) { + sh_video_t *sh_video = demuxer->video->sh; roq_data_t *roq_data = (roq_data_t *)demuxer->priv; roq_chunk_t roq_chunk; - demux_stream_t *ds; if (roq_data->current_chunk >= roq_data->total_chunks) return 0; roq_chunk = roq_data->chunks[roq_data->current_chunk]; - if (roq_chunk.chunk_type == CHUNK_TYPE_AUDIO) - ds = demuxer->audio; - else - ds = demuxer->video; // make sure we're at the right place in the stream and fetch the chunk stream_seek(demuxer->stream, roq_chunk.chunk_offset); - ds_read_packet( - ds, - demuxer->stream, - roq_chunk.chunk_size, -// roq_data->current_frame/sh_video->fps, - 0, - roq_chunk.chunk_offset, - 0 - ); + + if (roq_chunk.chunk_type == CHUNK_TYPE_AUDIO) + ds_read_packet(demuxer->audio, demuxer->stream, roq_chunk.chunk_size, + roq_chunk.running_audio_sample_count / 22050, + roq_chunk.chunk_offset, 0); + else + ds_read_packet(demuxer->video, demuxer->stream, roq_chunk.chunk_size, + roq_chunk.video_chunk_number / sh_video->fps, + roq_chunk.chunk_offset, 0); roq_data->current_chunk++; return 1; @@ -99,11 +100,14 @@ roq_data_t *roq_data = (roq_data_t *)malloc(sizeof(roq_data_t)); int chunk_id; int chunk_size; - int chunk_arg1; - int chunk_arg2; + int chunk_arg; int chunk_counter = 0; int last_chunk_id = 0; + int largest_audio_chunk = 0; + roq_data->total_chunks = 0; + roq_data->current_chunk = 0; + roq_data->total_video_chunks = 0; roq_data->chunks = NULL; // position the stream and start traversing @@ -111,9 +115,8 @@ while (!stream_eof(demuxer->stream)) { chunk_id = stream_read_word_le(demuxer->stream); - chunk_size = stream_read_word_le(demuxer->stream); - chunk_arg1 = stream_read_word_le(demuxer->stream); - chunk_arg2 = stream_read_word_le(demuxer->stream); + chunk_size = stream_read_dword_le(demuxer->stream); + chunk_arg = stream_read_word_le(demuxer->stream); // this is the only useful header info in the file if (chunk_id == RoQ_INFO) @@ -126,7 +129,7 @@ } else { - // make the header first + // this is a good opportunity to create a video stream header sh_video = new_sh_video(demuxer, 0); // make sure the demuxer knows about the new stream header demuxer->video->sh = sh_video; @@ -134,7 +137,6 @@ // parent video demuxer stream sh_video->ds = demuxer->video; - // this is a good opportunity to create a video stream header sh_video->disp_w = stream_read_word_le(demuxer->stream); sh_video->disp_h = stream_read_word_le(demuxer->stream); stream_skip(demuxer->stream, 4); @@ -161,19 +163,20 @@ // parent audio demuxer stream sh_audio->ds = demuxer->audio; + // go through the bother of making a WAVEFORMATEX structure + sh_audio->wf = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX)); + // custom fourcc for internal MPlayer use sh_audio->format = mmioFOURCC('R', 'o', 'Q', 'A'); - // assume it's mono until there's reason to believe otherwise - sh_audio->channels = 1; + if (chunk_id == RoQ_SOUND_STEREO) + sh_audio->wf->nChannels = 2; + else + sh_audio->wf->nChannels = 1; // always 22KHz, 16-bit - sh_audio->samplerate = 22050; - sh_audio->samplesize = 2; + sh_audio->wf->nSamplesPerSec = 22050; + sh_audio->wf->wBitsPerSample = 2; } - // if it's stereo, promote the channel number - if (chunk_id == RoQ_SOUND_STEREO) - sh_audio->channels = 2; - // index the chunk roq_data->chunks = (roq_chunk_t *)realloc(roq_data->chunks, (chunk_counter + 1) * sizeof (roq_chunk_t)); @@ -181,6 +184,14 @@ roq_data->chunks[chunk_counter].chunk_offset = stream_tell(demuxer->stream) - 8; roq_data->chunks[chunk_counter].chunk_size = chunk_size + 8; + roq_data->chunks[chunk_counter].running_audio_sample_count = + roq_data->total_audio_sample_count; + + // audio housekeeping + if (chunk_size > largest_audio_chunk) + largest_audio_chunk = chunk_size; + roq_data->total_audio_sample_count += + (chunk_size / sh_audio->wf->nChannels); stream_skip(demuxer->stream, chunk_size); chunk_counter++; @@ -196,6 +207,8 @@ roq_data->chunks[chunk_counter].chunk_offset = stream_tell(demuxer->stream) - 8; roq_data->chunks[chunk_counter].chunk_size = chunk_size + 8; + roq_data->chunks[chunk_counter].video_chunk_number = + roq_data->total_video_chunks++; stream_skip(demuxer->stream, chunk_size); chunk_counter++; @@ -215,10 +228,18 @@ last_chunk_id = chunk_id; } + // minimum output buffer size = largest audio chunk * 2, since each byte + // in the DPCM encoding effectively represents 1 16-bit sample + // (store it in wf->nBlockAlign for the time being since init_audio() will + // step on it anyway) + sh_audio->wf->nBlockAlign = largest_audio_chunk * 2; + roq_data->total_chunks = chunk_counter; roq_data->current_chunk = 0; demuxer->priv = roq_data; + stream_reset(demuxer->stream); + return demuxer; }