summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demux_roq.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmpdemux/demux_roq.c')
-rw-r--r--libmpdemux/demux_roq.c281
1 files changed, 0 insertions, 281 deletions
diff --git a/libmpdemux/demux_roq.c b/libmpdemux/demux_roq.c
deleted file mode 100644
index af9e4c5a8e..0000000000
--- a/libmpdemux/demux_roq.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * RoQ file demuxer
- * copyright (c) 2002 Mike Melanson
- * based on Dr. Tim Ferguson's RoQ document found at:
- * http://www.csse.monash.edu.au/~timf/videocodec.html
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-#include "libavutil/attributes.h"
-
-#define RoQ_INFO 0x1001
-#define RoQ_QUAD_CODEBOOK 0x1002
-#define RoQ_QUAD_VQ 0x1011
-#define RoQ_SOUND_MONO 0x1020
-#define RoQ_SOUND_STEREO 0x1021
-
-#define CHUNK_TYPE_AUDIO 0
-#define CHUNK_TYPE_VIDEO 1
-
-typedef struct roq_chunk_t
-{
- int chunk_type;
- off_t chunk_offset;
- int chunk_size;
-
- float 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;
-
-// Check if a stream qualifies as a RoQ file based on the magic numbers
-// at the start of the file:
-// 84 10 FF FF FF FF xx xx
-static int roq_check_file(demuxer_t *demuxer)
-{
- if ((stream_read_dword(demuxer->stream) == 0x8410FFFF) &&
- ((stream_read_dword(demuxer->stream) & 0xFFFF0000) == 0xFFFF0000))
- return DEMUXER_TYPE_ROQ;
- else
- return 0;
-}
-
-// return value:
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_roq_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
-{
- sh_video_t *sh_video = demuxer->video->sh;
- roq_data_t *roq_data = (roq_data_t *)demuxer->priv;
- roq_chunk_t roq_chunk;
-
- if (roq_data->current_chunk >= roq_data->total_chunks)
- return 0;
-
- roq_chunk = roq_data->chunks[roq_data->current_chunk];
-
- // make sure we're at the right place in the stream and fetch the chunk
- stream_seek(demuxer->stream, roq_chunk.chunk_offset);
-
- if (roq_chunk.chunk_type == CHUNK_TYPE_AUDIO)
- ds_read_packet(demuxer->audio, demuxer->stream, roq_chunk.chunk_size,
- 0,
- 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;
-}
-
-static demuxer_t* demux_open_roq(demuxer_t* demuxer)
-{
- sh_video_t *sh_video = NULL;
- sh_audio_t *sh_audio = NULL;
-
- roq_data_t *roq_data = malloc(sizeof(roq_data_t));
- int chunk_id;
- int chunk_size;
- int chunk_arg av_unused;
- int last_chunk_id = 0;
- int largest_audio_chunk = 0;
- int fps;
-
- 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
- stream_seek(demuxer->stream, 6);
- fps = stream_read_word_le(demuxer->stream);
- while (!stream_eof(demuxer->stream))
- {
- chunk_id = 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)
- {
- // there should only be one RoQ_INFO chunk per file
- if (sh_video)
- {
- mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Found more than one RoQ_INFO chunk\n");
- stream_skip(demuxer->stream, 8);
- }
- else
- {
- // 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;
- // make sure that the video demuxer stream header knows about its
- // parent video demuxer stream
- sh_video->ds = demuxer->video;
-
- 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);
-
- // custom fourcc for internal MPlayer use
- sh_video->format = mmioFOURCC('R', 'o', 'Q', 'V');
-
- // constant frame rate
- sh_video->fps = fps;
- sh_video->frametime = 1 / sh_video->fps;
- }
- }
- else if ((chunk_id == RoQ_SOUND_MONO) ||
- (chunk_id == RoQ_SOUND_STEREO))
- {
- // create the audio stream header if it hasn't been created it
- if (sh_audio == NULL)
- {
- // make the header first
- sh_audio = new_sh_audio(demuxer, 0);
- // make sure the demuxer knows about the new stream header
- demuxer->audio->id = 0;
- demuxer->audio->sh = sh_audio;
- // make sure that the audio demuxer stream header knows about its
- // parent audio demuxer stream
- sh_audio->ds = demuxer->audio;
-
- // go through the bother of making a WAVEFORMATEX structure
- sh_audio->wf = malloc(sizeof(*sh_audio->wf));
-
- // custom fourcc for internal MPlayer use
- sh_audio->format = mmioFOURCC('R', 'o', 'Q', 'A');
- if (chunk_id == RoQ_SOUND_STEREO)
- sh_audio->wf->nChannels = 2;
- else
- sh_audio->wf->nChannels = 1;
- // always 22KHz, 16-bit
- sh_audio->wf->nSamplesPerSec = 22050;
- sh_audio->wf->wBitsPerSample = 16;
- }
-
- // index the chunk
- roq_data->chunks = realloc(roq_data->chunks,
- (roq_data->total_chunks + 1) * sizeof (roq_chunk_t));
- roq_data->chunks[roq_data->total_chunks].chunk_type = CHUNK_TYPE_AUDIO;
- roq_data->chunks[roq_data->total_chunks].chunk_offset =
- stream_tell(demuxer->stream) - 8;
- roq_data->chunks[roq_data->total_chunks].chunk_size = chunk_size + 8;
- roq_data->chunks[roq_data->total_chunks].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);
- roq_data->total_chunks++;
- }
- else if ((chunk_id == RoQ_QUAD_CODEBOOK) ||
- ((chunk_id == RoQ_QUAD_VQ) && (last_chunk_id != RoQ_QUAD_CODEBOOK)))
- {
- // index a new chunk if it's a codebook or quad VQ not following a
- // codebook
- roq_data->chunks = realloc(roq_data->chunks,
- (roq_data->total_chunks + 1) * sizeof (roq_chunk_t));
- roq_data->chunks[roq_data->total_chunks].chunk_type = CHUNK_TYPE_VIDEO;
- roq_data->chunks[roq_data->total_chunks].chunk_offset =
- stream_tell(demuxer->stream) - 8;
- roq_data->chunks[roq_data->total_chunks].chunk_size = chunk_size + 8;
- roq_data->chunks[roq_data->total_chunks].video_chunk_number =
- roq_data->total_video_chunks++;
-
- stream_skip(demuxer->stream, chunk_size);
- roq_data->total_chunks++;
- }
- else if ((chunk_id == RoQ_QUAD_VQ) && (last_chunk_id == RoQ_QUAD_CODEBOOK))
- {
- // if it's a quad VQ chunk following a codebook chunk, extend the last
- // chunk
- roq_data->chunks[roq_data->total_chunks - 1].chunk_size += (chunk_size + 8);
- stream_skip(demuxer->stream, chunk_size);
- }
- else if (!stream_eof(demuxer->stream))
- {
- mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Unknown RoQ chunk ID: %04X\n", chunk_id);
- }
-
- 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)
- if (sh_audio)
- sh_audio->wf->nBlockAlign = largest_audio_chunk * 2;
-
- roq_data->current_chunk = 0;
-
- demuxer->priv = roq_data;
-
- stream_reset(demuxer->stream);
-
- return demuxer;
-}
-
-static void demux_close_roq(demuxer_t* demuxer) {
- roq_data_t *roq_data = demuxer->priv;
-
- free(roq_data);
-}
-
-
-const demuxer_desc_t demuxer_desc_roq = {
- "RoQ demuxer",
- "roq",
- "ROQ",
- "Mike Melanson",
- "",
- DEMUXER_TYPE_ROQ,
- 0, // unsafe autodetect
- roq_check_file,
- demux_roq_fill_buffer,
- demux_open_roq,
- demux_close_roq,
- NULL,
- NULL
-};