Am Fri, 10 Aug 2007 10:26:40 +0200
schrieb Francesco Romani <[EMAIL PROTECTED]>:

> On Thu, 2007-08-09 at 18:17 +0200, Stefan Scheffler wrote:
> > Hi,
> > 
> > some cameras or phones produce avis's with audio in ulaw format
> > and since it came up again on irc, I've thrown together a decoder
> > for it.
> > 
> > I had a pretty hard time finding sample files and only got one from
> > mplayers sample library, so it's not well tested but seems to work
> > ok.
> 
> Hi, thanks for this contribute
> I've a concern and an observation regard this code.
> 
> The corcern regards the ulaw_decode table in extract_ulaw.h: is this a
> rip from libquicktime sources? I'm wondering about (theorical?)
> copyright issues, transcode has plenty of those in past days and I
> never liked them.
> 
> The observation is technical, I think that, given the code, ulaw
> support can be merged in existing avi/raw inport module, there is no
> need for a separate one.
> 

Alright, second try, integrated into import_avi this time.
I hope those nested switch statements in MOD_decode are acceptable. It
looks a bit ugly, but I couldn't think of a better way.


stefan
diff -uNr -x CVS ../../transcode/import/extract_avi.c ./import/extract_avi.c
--- ../../transcode/import/extract_avi.c	2007-04-15 13:12:34.000000000 +0200
+++ ./import/extract_avi.c	2007-08-09 17:17:46.000000000 +0200
@@ -83,6 +83,13 @@
       ipipe->probe_info->track[j].padrate = AVI_audio_padrate(avifile);
 
       ipipe->probe_info->track[j].tid=j;
+      
+      // this should probably go somewhere else
+      // ulaw in avi seems to store the samplesize of the compressed data instead of the
+      // that of the uncompressed data
+      // ulaw is always 16 bit
+      if(ipipe->probe_info->track[j].format == CODEC_ULAW)
+	  ipipe->probe_info->track[j].bits = 16;
 
       if(ipipe->probe_info->track[j].chan>0) ++ipipe->probe_info->num_tracks;
     }
diff -uNr -x CVS ../../transcode/import/import_avi.c ./import/import_avi.c
--- ../../transcode/import/import_avi.c	2007-04-15 13:12:34.000000000 +0200
+++ ./import/import_avi.c	2007-08-10 23:08:43.000000000 +0200
@@ -35,15 +35,26 @@
 #include "import_def.h"
 
 #include "libtc/xio.h"
-
+#include "ulaw_table.h"
 
 static avi_t *avifile1=NULL;
 static avi_t *avifile2=NULL;
 
 static int audio_codec;
+static int aformat=0;
 static int aframe_count=0, vframe_count=0;
 static int width=0, height=0;
 
+static unsigned char *abuf=NULL;
+
+static int ulawtopcm(unsigned char * in, int insize, short * out) {
+  int i;
+  for (i = 0; i < insize; i++) {
+    out[i] = ulaw_decode[in[i]];
+  }
+  return i*2;
+}
+
 
 /* ------------------------------------------------------------
  *
@@ -56,7 +67,7 @@
   double fps=0;
   char *codec=NULL;
   long rate=0, bitrate=0;
-  int format=0, chan=0, bits=0;
+  int chan=0, bits=0;
   struct stat fbuf;
   char import_cmd_buf[TC_BUF_MAX];
   long sret;
@@ -113,17 +124,18 @@
     bits   =  AVI_audio_bits(avifile1);
     bits   =  (!bits)?16:bits;
 
-    format =  AVI_audio_format(avifile1);
+    aformat =  AVI_audio_format(avifile1);
     bitrate=  AVI_audio_mp3rate(avifile1);
 
     if (verbose_flag)
         tc_log_info(MOD_NAME, "format=0x%x, rate=%ld Hz, bits=%d, "
                         "channels=%d, bitrate=%ld",
-                         format, rate, bits, chan, bitrate);
+                         aformat, rate, bits, chan, bitrate);
 
-    if(vob->im_a_codec == CODEC_PCM && format != CODEC_PCM) {
+    if(vob->im_a_codec == CODEC_PCM &&
+       (aformat != CODEC_PCM && aformat != CODEC_ULAW)) {
       tc_log_info(MOD_NAME, "error: invalid AVI audio format '0x%x'"
-                      " for PCM processing", format);
+                      " for PCM processing", aformat);
       return(TC_IMPORT_ERROR);
     }
     // go to a specific byte for seeking
@@ -258,19 +270,44 @@
 
       param->size = bytes_read;
       ++aframe_count;
-
       break;
 
     default:
+      switch(aformat) {
 
-      bytes_read = AVI_read_audio(avifile1, param->buffer, param->size);
+      case CODEC_ULAW:
+	abuf = tc_realloc(abuf, param->size/2);
+	if (abuf == NULL) {
+	  tc_log_error(MOD_NAME, "allocation of audio buffer failed");
+	  return(TC_IMPORT_ERROR);
+	}
 
-      if(bytes_read<0) {
-	if(verbose & TC_DEBUG) AVI_print_error("AVI audio read frame");
-	return(TC_IMPORT_ERROR);
-      }
+	bytes_read = AVI_read_audio(avifile1, (char *)abuf, param->size/2);
 
-      if(bytes_read < param->size) param->size=bytes_read;
+      	if(bytes_read<0) {
+	  if(verbose & TC_DEBUG) AVI_print_error("AVI audio read frame");
+	  return(TC_IMPORT_ERROR);
+	}
+
+	ulawtopcm(abuf, bytes_read, (short *)param->buffer);
+
+	if(bytes_read < param->size/2) param->size=bytes_read*2;
+	break;
+
+      case CODEC_PCM:
+	bytes_read = AVI_read_audio(avifile1, param->buffer, param->size);
+
+	if(bytes_read<0) {
+	  if(verbose & TC_DEBUG) AVI_print_error("AVI audio read frame");
+	  return(TC_IMPORT_ERROR);
+	}
+	if(bytes_read < param->size) param->size=bytes_read;
+	break;
+
+      default:
+	tc_log_error(MOD_NAME, "Unsupported audio format: %i", aformat);
+  	return(TC_IMPORT_ERROR);
+      }
     }
 
     return(TC_IMPORT_OK);
@@ -292,6 +329,8 @@
 
     if(param->flag == TC_AUDIO) {
 
+	if (abuf != NULL) free(abuf);
+
 	if(avifile1!=NULL) {
 	    AVI_close(avifile1);
 	    avifile1=NULL;
diff -uNr -x CVS ../../transcode/import/ulaw_table.h ./import/ulaw_table.h
--- ../../transcode/import/ulaw_table.h	1970-01-01 01:00:00.000000000 +0100
+++ ./import/ulaw_table.h	2007-08-10 22:37:21.000000000 +0200
@@ -0,0 +1,61 @@
+/*
+ *  ulaw_table.h
+ *
+ *  Copyright (C) Stefan Scheffler - Aug 2007
+ *
+ *  This file is part of transcode, a video stream  processing tool
+ *
+ *  transcode 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, or (at your option)
+ *  any later version.
+ *
+ *  transcode 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 GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* from libquicktime */
+
+static short ulaw_decode[256] =
+{
+    -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
+    -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
+    -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
+    -11900, -11388, -10876, -10364, -9852,  -9340,  -8828,  -8316,
+    -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
+    -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
+    -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
+    -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
+    -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
+    -1372,  -1308,  -1244,  -1180,  -1116,  -1052,  -988,   -924,
+    -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
+    -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
+    -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
+    -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
+    -120,   -112,   -104,   -96,    -88,    -80,    -72,    -64,
+    -56,    -48,    -40,    -32,    -24,    -16,    -8,     0,
+
+    32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
+    23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
+    15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
+    11900,  11388,  10876,  10364,  9852,   9340,   8828,   8316,
+    7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
+    5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
+    3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
+    2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
+    1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
+    1372,   1308,   1244,   1180,   1116,   1052,   988,    924,
+    876,    844,    812,    780,    748,    716,    684,    652,
+    620,    588,    556,    524,    492,    460,    428,    396,
+    372,    356,    340,    324,    308,    292,    276,    260,
+    244,    228,    212,    196,    180,    164,    148,    132,
+    120,    112,    104,    96,     88,     80,     72,     64,
+    56,     48,     40,     32,     24,     16,     8,      0
+};
diff -uNr -x CVS ../../transcode/src/probe.c ./src/probe.c
--- ../../transcode/src/probe.c	2007-06-07 15:26:18.000000000 +0200
+++ ./src/probe.c	2007-08-10 20:24:21.000000000 +0200
@@ -314,6 +314,7 @@
         case CODEC_MP2:    return "MPEG layer-2";
         case CODEC_PCM:    return "PCM";
         case CODEC_LPCM:   return "LPCM";
+        case CODEC_ULAW:   return "uLaw";
         case CODEC_VORBIS: return "Ogg Vorbis";
         case CODEC_VAG:    return "PS-VAG";
     }
@@ -728,6 +729,8 @@
       case TC_MAGIC_AVI:
         if (vob->pass_flag & TC_VIDEO)
             vob->vmod_probed = "avi";
+        if (vob->a_codec_flag == CODEC_ULAW)
+            vob->amod_probed = "avi";
         break;
 
       case TC_MAGIC_MOV:
diff -uNr -x CVS ../../transcode/src/tc_defaults.h ./src/tc_defaults.h
--- ../../transcode/src/tc_defaults.h	2007-08-04 17:05:24.000000000 +0200
+++ ./src/tc_defaults.h	2007-08-10 20:30:05.000000000 +0200
@@ -165,6 +165,7 @@
 #define CODEC_YUV422     256
 
 #define CODEC_PCM     0x1
+#define CODEC_ULAW    0x7
 #define CODEC_AC3     0x2000
 #define CODEC_MP2     0x50
 #define CODEC_MP3     0x55

Reply via email to