summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dec_audio.c35
-rw-r--r--dec_video.c16
-rw-r--r--roqav.c57
-rw-r--r--roqav.h2
4 files changed, 108 insertions, 2 deletions
diff --git a/dec_audio.c b/dec_audio.c
index 1f2d8b00fa..5aba84344b 100644
--- a/dec_audio.c
+++ b/dec_audio.c
@@ -20,6 +20,8 @@ extern int verbose; // defined in mplayer.c
#include "dec_audio.h"
+#include "roqav.h"
+
//==========================================================================
#include "libao2/afmt.h"
@@ -433,6 +435,13 @@ case AFM_FOX62ADPCM:
sh_audio->ds->ss_div=FOX62_ADPCM_SAMPLES_PER_BLOCK;
sh_audio->ds->ss_mul=FOX62_ADPCM_BLOCK_SIZE;
break;
+case AFM_ROQAUDIO:
+ // minsize was stored in wf->nBlockAlign by the RoQ demuxer
+ sh_audio->audio_out_minsize=sh_audio->wf->nBlockAlign;
+ sh_audio->ds->ss_div=FOX62_ADPCM_SAMPLES_PER_BLOCK;
+ sh_audio->ds->ss_mul=FOX62_ADPCM_BLOCK_SIZE;
+ sh_audio->context = roq_decode_audio_init();
+ break;
case AFM_MPEG:
// MPEG Audio:
sh_audio->audio_out_minsize=4608;
@@ -726,6 +735,11 @@ case AFM_FOX62ADPCM:
sh_audio->i_bps=FOX62_ADPCM_BLOCK_SIZE*
(sh_audio->channels*sh_audio->samplerate) / FOX62_ADPCM_SAMPLES_PER_BLOCK;
break;
+case AFM_ROQAUDIO:
+ sh_audio->channels=sh_audio->wf->nChannels;
+ sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
+ sh_audio->i_bps = (sh_audio->channels * 22050) / 2;
+ break;
case AFM_MPEG: {
// MPEG Audio:
dec_audio_sh=sh_audio; // save sh_audio for the callback:
@@ -1166,6 +1180,27 @@ int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){
(unsigned short*)buf,ibuf);
break;
}
+ case AFM_ROQAUDIO:
+ {
+ static unsigned char *ibuf = NULL;
+ unsigned char header_data[6];
+ int read_len;
+
+ if (!ibuf)
+ ibuf = (unsigned char *)malloc(sh_audio->audio_out_minsize / 2);
+
+ // figure out how much data to read
+ if (demux_read_data(sh_audio->ds, header_data, 6) != 6)
+ break; // EOF
+ read_len = (header_data[5] << 24) | (header_data[4] << 16) |
+ (header_data[3] << 8) | header_data[2];
+ read_len += 2; // 16-bit arguments
+ if (demux_read_data(sh_audio->ds, ibuf, read_len) != read_len)
+ break;
+ len = 2 * roq_decode_audio((unsigned short *)buf, ibuf,
+ read_len, sh_audio->channels, sh_audio->context);
+ break;
+ }
#ifdef USE_LIBAC3
case AFM_AC3: // AC3 decoder
//printf("{1:%d}",avi_header.idx_pos);fflush(stdout);
diff --git a/dec_video.c b/dec_video.c
index d9b928d2d5..90980c5bb2 100644
--- a/dec_video.c
+++ b/dec_video.c
@@ -34,6 +34,8 @@ extern int verbose; // defined in mplayer.c
#include "dec_video.h"
+#include "roqav.h"
+
// ===================================================================
extern double video_time_usage;
@@ -424,6 +426,15 @@ sh_video->image=new_mp_image(sh_video->disp_w,sh_video->disp_h);
mp_image_setfmt(sh_video->image,out_fmt);
switch(sh_video->codec->driver){
+ case VFM_ROQVIDEO:
+#ifdef USE_MP_IMAGE
+ sh_video->image->type=MP_IMGTYPE_STATIC;
+#else
+ sh_video->our_out_buffer =
+ (char*)memalign(64, sh_video->disp_w * sh_video->disp_h * 1.5);
+#endif
+ sh_video->context = roq_decode_video_init();
+ break;
case VFM_CINEPAK: {
#ifdef USE_MP_IMAGE
sh_video->image->type=MP_IMGTYPE_STATIC;
@@ -1080,6 +1091,11 @@ if(verbose>1){
sh_video->disp_w, sh_video->disp_h, (out_fmt==IMGFMT_YUY2)?16:(out_fmt&255));
blit_frame = 3;
break;
+ case VFM_ROQVIDEO:
+ roq_decode_video(start, in_size, sh_video->our_out_buffer,
+ sh_video->disp_w, sh_video->disp_h, sh_video->context);
+ blit_frame = 3;
+ break;
} // switch
//------------------------ frame decoded. --------------------
diff --git a/roqav.c b/roqav.c
index f1bcd51b98..40eac00673 100644
--- a/roqav.c
+++ b/roqav.c
@@ -1,17 +1,24 @@
/*
RoQ A/V decoder for the MPlayer program
by Mike Melanson
- based on Dr. Tim Ferguson's RoQ document found at:
+ based on Dr. Tim Ferguson's RoQ document and accompanying source
+ code found at:
http://www.csse.monash.edu.au/~timf/videocodec.html
*/
#include "config.h"
#include "bswap.h"
#include <stdio.h>
+#include <stdlib.h>
#define LE_16(x) (le2me_16(*(unsigned short *)(x)))
#define LE_32(x) (le2me_32(*(unsigned int *)(x)))
+#define CLAMP_S16(x) if (x < -32768) x = -32768; \
+ else if (x > 32767) x = 32767;
+#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000;
+// sign extend a 4-bit value
+
void *roq_decode_video_init(void)
{
}
@@ -26,14 +33,62 @@ void roq_decode_video(
{
}
+// Initialize the RoQ audio decoder, which is to say, initialize the table
+// of squares.
void *roq_decode_audio_init(void)
{
+ short *square_array;
+ short square;
+ int i;
+
+ square_array = (short *)malloc(256 * sizeof(short));
+ if (!square_array)
+ return NULL;
+
+ for (i = 0; i < 128; i++)
+ {
+ square = i * i;
+ square_array[i] = square;
+ square_array[i + 128] = -square;
+ }
+
+ return square_array;
}
int roq_decode_audio(
unsigned short *output,
unsigned char *input,
+ int encoded_size,
int channels,
void *context)
{
+ short *square_array = (short *)context;
+ int i;
+ int predictor[2];
+ int channel_number = 0;
+
+ // prepare the initial predictors
+ if (channels == 1)
+ predictor[0] = LE_16(&input[0]);
+ else
+ {
+ predictor[0] = input[1] << 8;
+ predictor[1] = input[0] << 8;
+ }
+ SE_16BIT(predictor[0]);
+ SE_16BIT(predictor[1]);
+
+ // decode the samples
+ for (i = 2; i < encoded_size; i++)
+ {
+ predictor[channel_number] += square_array[input[i]];
+ CLAMP_S16(predictor[channel_number]);
+ output[i - 2] = predictor[channel_number];
+
+ // toggle channel
+ channel_number ^= channels - 1;
+ }
+
+ // return the number of samples decoded
+ return (encoded_size - 2);
}
diff --git a/roqav.h b/roqav.h
index a049713e9a..be88916311 100644
--- a/roqav.h
+++ b/roqav.h
@@ -7,6 +7,6 @@ void roq_decode_video(unsigned char *encoded, int encoded_size,
void *roq_decode_audio_init(void);
int roq_decode_audio(unsigned short *output, unsigned char *input,
- int channels, void *context);
+ int encoded_size, int channels, void *context);
#endif // ROQAV_H