1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-19 21:31:52 +00:00

further work on the RoQ audio decoder

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4487 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
melanson 2002-02-02 22:45:39 +00:00
parent 9996ca0ac9
commit 80168a072d
4 changed files with 108 additions and 2 deletions

View File

@ -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);

View File

@ -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. --------------------

57
roqav.c
View File

@ -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);
}

View File

@ -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