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