[MPlayer-dev-eng] Re: [PATCH] QuickTime in24 and in32 PCM audio support

Dominik 'Rathann' Mierzejewski dominik at rangers.eu.org
Mon Mar 13 01:50:20 CET 2006


On Sunday, 12 March 2006 at 02:41, Baptiste COUDURIER wrote:
> Hi,
> 
> Dominik 'Rathann' Mierzejewski wrote:
> > [...]
> > 
> > Indeed. So with my patch, BE samples play fine, but LE (obviously) don't.
> > Any idea how to tell one from another? The FourCC is the same.
> 
> Endianness is specified through 'enda' atom in MOV container. The change
> needs to be done in the MOV demuxer.

Here's a preliminary, non-working patch (crashes). I couldn't make heads or tails
of the fact that gdb tells me that trak is unset (NULL) here:

+                         if ((len >= 22) &&
+                             (char2int(trak->stdata,52+16)==MOV_FOURCC('e','n','d','a')) &&
+                             (char2short(trak->stdata,52+20))) {
+                               sh->format=BE_32(char2int(trak->stdata,52+8));
+                               mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found little endian PCM data, reversed fourcc:%04x\n",
sh->format);
+                         }
+                         break;

Attached. Basically the idea is to byteswap the fourcc if enda atom says
the PCM data is little-endian (enda->littleEndian==true) in demux_mov.c and
then detect the swapped fourcc in ad_pcm.c.

Regards,
R.

-- 
MPlayer developer and RPMs maintainer: http://rpm.greysector.net/mplayer/
There should be a science of discontent. People need hard times and oppression
to develop psychic muscles.
	-- from "Collected Sayings of Muad'Dib" by the Princess Irulan
-------------- next part --------------
--- MPlayer-20060312/libmpcodecs/ad_pcm.c.orig	2006-03-12 01:36:33.000000000 +0100
+++ MPlayer-20060312/libmpcodecs/ad_pcm.c	2006-03-13 01:44:02.000000000 +0100
@@ -6,6 +6,18 @@
 #include "ad_internal.h"
 #include "libaf/af_format.h"
 
+#define BE_16(x) (((unsigned char *)(x))[0] <<  8 | \
+                  ((unsigned char *)(x))[1])
+#define BE_32(x) (((unsigned char *)(x))[0] << 24 | \
+                  ((unsigned char *)(x))[1] << 16 | \
+                  ((unsigned char *)(x))[2] <<  8 | \
+                  ((unsigned char *)(x))[3])
+
+#define char2short(x,y) BE_16(&(x)[(y)])
+#define char2int(x,y)   BE_32(&(x)[(y)])
+
+#define MOV_FOURCC(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|(d))
+
 static ad_info_t info = 
 {
 	"Uncompressed PCM audio decoder",
@@ -65,14 +77,36 @@
        sh_audio->sample_format=AF_FORMAT_FLOAT_BE;
        sh_audio->samplesize=4;
        break;
+    case 0x666c3332: // '23lf', little endian float32, MPlayer internal fourCC
+       sh_audio->sample_format=AF_FORMAT_FLOAT_LE;
+       sh_audio->samplesize=4;
+       break;
+    case 0x34366c66: // 'fl64', bigendian float64
+       sh_audio->sample_format=AF_FORMAT_FLOAT_BE;
+       sh_audio->samplesize=8;
+       break;
+    case 0x666c3634: // '46lf', little endian float64, MPlayer internal fourCC
+       sh_audio->sample_format=AF_FORMAT_FLOAT_LE;
+       sh_audio->samplesize=8;
+       break;
     case 0x34326e69: // 'in24', bigendian int24
        sh_audio->sample_format=AF_FORMAT_S24_BE;
        sh_audio->samplesize=3;
+//       printf("frma: size=%ld, atomType=%04x, format=%04x\n",char2int(sh_audio->codecdata,0),char2int(sh_audio->codecdata,4),char2int(sh_audio->codecdata,8));
+//       printf("enda: size=%ld, atomType=%04x, littleEndian=%d\n",char2int(sh_audio->codecdata,12),char2int(sh_audio->codecdata,16),char2short(sh_audio->codecdata,20));
+       break;
+    case 0x696e3234: // '42ni', little endian int24, MPlayer internal fourCC
+       sh_audio->sample_format=AF_FORMAT_S24_LE;
+       sh_audio->samplesize=3;
        break;
     case 0x32336e69: // 'in32', bigendian int32
        sh_audio->sample_format=AF_FORMAT_S32_BE;
        sh_audio->samplesize=4;
        break;
+    case 0x696e3332: // '23ni', little endian int32, MPlayer internal fourCC
+       sh_audio->sample_format=AF_FORMAT_S32_LE;
+       sh_audio->samplesize=4;
+       break;
     default: if(sh_audio->samplesize!=2) sh_audio->sample_format=AF_FORMAT_U8;
   }
   if (!sh_audio->samplesize) // this would cause MPlayer to hang later
--- MPlayer-20060312/libmpdemux/demux_mov.c.orig	2006-03-06 18:40:28.000000000 +0100
+++ MPlayer-20060312/libmpdemux/demux_mov.c	2006-03-13 00:00:44.000000000 +0100
@@ -724,13 +724,29 @@
 		    mp_msg(MSGT_DEMUX,MSGL_V,"Audio extra header: len=%d  fcc=0x%X\n",len,fcc);
 		    if((len >= 4) && 
 		       (char2int(trak->stdata,52) >= 12) &&
-		       (char2int(trak->stdata,52+4) == MOV_FOURCC('f','r','m','a')) &&
-		       (char2int(trak->stdata,52+8) == MOV_FOURCC('a','l','a','c')) &&
-		       (len >= 36 + char2int(trak->stdata,52))) {
+		       (char2int(trak->stdata,52+4) == MOV_FOURCC('f','r','m','a'))) {
+			switch(char2int(trak->stdata,52+8)) {
+			 case MOV_FOURCC('a','l','a','c'):
+			  if (len >= 36 + char2int(trak->stdata,52)) {
 			    sh->codecdata_len = char2int(trak->stdata,52+char2int(trak->stdata,52));
 			    mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found alac atom (%d)!\n", sh->codecdata_len);
 			    sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
 			    memcpy(sh->codecdata, &trak->stdata[52+char2int(trak->stdata,52)], sh->codecdata_len);
+			  }
+			  break;
+			 case MOV_FOURCC('i','n','2','4'):
+			 case MOV_FOURCC('i','n','3','2'):
+			 case MOV_FOURCC('f','l','3','2'):
+			 case MOV_FOURCC('f','l','6','4'):
+			  if ((len >= 22) &&
+			      (char2int(trak->stdata,52+16)==MOV_FOURCC('e','n','d','a')) &&
+			      (char2short(trak->stdata,52+20))) {
+				sh->format=BE_32(char2int(trak->stdata,52+8));
+				mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found little endian PCM data, reversed fourcc:%04x\n", sh->format);
+			  }
+		          break;
+		         default: break;
+		        }
 		    } else {
 		      if (len > 8 && len + 44 <= trak->stdata_len) {
 		    sh->codecdata_len = len-8;


More information about the MPlayer-dev-eng mailing list