[Mplayer-cvslog] CVS: main roqav.c,1.1,1.2 roqav.h,1.1,1.2 dec_audio.c,1.80,1.81 dec_video.c,1.94,1.95

Mike Melanson melanson at mplayer.dev.hu
Sat Feb 2 23:45:42 CET 2002


Update of /cvsroot/mplayer/main
In directory mplayer:/var/tmp.root/cvs-serv6088

Modified Files:
	roqav.c roqav.h dec_audio.c dec_video.c 
Log Message:
further work on the RoQ audio decoder


Index: roqav.c
===================================================================
RCS file: /cvsroot/mplayer/main/roqav.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- roqav.c	1 Feb 2002 05:33:40 -0000	1.1
+++ roqav.c	2 Feb 2002 22:45:39 -0000	1.2
@@ -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 @@
 {
 }
 
+// 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);
 }

Index: roqav.h
===================================================================
RCS file: /cvsroot/mplayer/main/roqav.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- roqav.h	1 Feb 2002 05:33:40 -0000	1.1
+++ roqav.h	2 Feb 2002 22:45:39 -0000	1.2
@@ -7,6 +7,6 @@
 
 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

Index: dec_audio.c
===================================================================
RCS file: /cvsroot/mplayer/main/dec_audio.c,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -r1.80 -r1.81
--- dec_audio.c	30 Jan 2002 22:05:46 -0000	1.80
+++ dec_audio.c	2 Feb 2002 22:45:39 -0000	1.81
@@ -20,6 +20,8 @@
 
 #include "dec_audio.h"
 
+#include "roqav.h"
+
 //==========================================================================
 
 #include "libao2/afmt.h"
@@ -433,6 +435,13 @@
   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 @@
   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:
@@ -1164,6 +1178,27 @@
           break; // EOF
         len = 2 * fox62_adpcm_decode_block(
           (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

Index: dec_video.c
===================================================================
RCS file: /cvsroot/mplayer/main/dec_video.c,v
retrieving revision 1.94
retrieving revision 1.95
diff -u -r1.94 -r1.95
--- dec_video.c	1 Feb 2002 11:41:38 -0000	1.94
+++ dec_video.c	2 Feb 2002 22:45:39 -0000	1.95
@@ -34,6 +34,8 @@
 
 #include "dec_video.h"
 
+#include "roqav.h"
+
 // ===================================================================
 
 extern double video_time_usage;
@@ -424,6 +426,15 @@
 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;
@@ -1078,6 +1089,11 @@
  case VFM_CYUV:
    decode_cyuv(start, in_size, sh_video->our_out_buffer,
       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




More information about the MPlayer-cvslog mailing list