changeset 30241:02b9c1a452e1

Add support for distinguishing between little- and big-endian SPDIF AC3 and converting between both.
author reimar
date Mon, 11 Jan 2010 20:27:52 +0000
parents 1c55c7f6874b
children 03c1ad03f29d
files libaf/af_format.c libaf/af_format.h libaf/af_lavcac3enc.c libaf/format.c libao2/ao_alsa.c libao2/ao_alsa5.c libao2/ao_dsound.c libao2/ao_mpegpes.c libao2/ao_oss.c libao2/ao_pcm.c libao2/ao_win32.c libmpcodecs/ad_hwac3.c m_option.c stream/tv.c
diffstat 14 files changed, 42 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/libaf/af_format.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libaf/af_format.c	Mon Jan 11 20:27:52 2010 +0000
@@ -98,6 +98,8 @@
        af->data->bps == data->bps)
       return AF_DETACH;
 
+    // Allow trivial AC3-endianness conversion
+    if (!AF_FORMAT_IS_AC3(af->data->format) || !AF_FORMAT_IS_AC3(data->format))
     // Check for errors in configuration
     if((AF_OK != check_bps(data->bps)) ||
        (AF_OK != check_format(data->format)) ||
@@ -152,7 +154,7 @@
   }
   case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET:{
     // Check for errors in configuration
-    if(AF_OK != check_format(*(int*)arg))
+    if(!AF_FORMAT_IS_AC3(*(int*)arg) && AF_OK != check_format(*(int*)arg))
       return AF_ERROR;
 
     af->data->format = *(int*)arg;
--- a/libaf/af_format.h	Mon Jan 11 20:02:46 2010 +0000
+++ b/libaf/af_format.h	Mon Jan 11 20:27:52 2010 +0000
@@ -83,6 +83,9 @@
 #define AF_FORMAT_FLOAT_LE	(AF_FORMAT_F|AF_FORMAT_32BIT|AF_FORMAT_LE)
 #define AF_FORMAT_FLOAT_BE	(AF_FORMAT_F|AF_FORMAT_32BIT|AF_FORMAT_BE)
 
+#define AF_FORMAT_AC3_LE	(AF_FORMAT_AC3|AF_FORMAT_16BIT|AF_FORMAT_LE)
+#define AF_FORMAT_AC3_BE	(AF_FORMAT_AC3|AF_FORMAT_16BIT|AF_FORMAT_BE)
+
 #if HAVE_BIGENDIAN
 #define AF_FORMAT_U16_NE AF_FORMAT_U16_BE
 #define AF_FORMAT_S16_NE AF_FORMAT_S16_BE
@@ -91,6 +94,7 @@
 #define AF_FORMAT_U32_NE AF_FORMAT_U32_BE
 #define AF_FORMAT_S32_NE AF_FORMAT_S32_BE
 #define AF_FORMAT_FLOAT_NE AF_FORMAT_FLOAT_BE
+#define AF_FORMAT_AC3_NE AF_FORMAT_AC3_BE
 #else
 #define AF_FORMAT_U16_NE AF_FORMAT_U16_LE
 #define AF_FORMAT_S16_NE AF_FORMAT_S16_LE
@@ -99,6 +103,7 @@
 #define AF_FORMAT_U32_NE AF_FORMAT_U32_LE
 #define AF_FORMAT_S32_NE AF_FORMAT_S32_LE
 #define AF_FORMAT_FLOAT_NE AF_FORMAT_FLOAT_LE
+#define AF_FORMAT_AC3_NE AF_FORMAT_AC3_LE
 #endif
 
 #define AF_FORMAT_UNKNOWN (-1)
--- a/libaf/af_lavcac3enc.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libaf/af_lavcac3enc.c	Mon Jan 11 20:27:52 2010 +0000
@@ -58,7 +58,7 @@
 
     switch (cmd){
     case AF_CONTROL_REINIT:
-        if (data->format == AF_FORMAT_AC3 || data->nch < s->min_channel_num)
+        if (AF_FORMAT_IS_AC3(data->format) || data->nch < s->min_channel_num)
             return AF_DETACH;
 
         s->pending_len = 0;
@@ -102,7 +102,7 @@
                 return AF_ERROR;
             }
         }
-        af->data->format = AF_FORMAT_AC3;
+        af->data->format = AF_FORMAT_AC3_NE;
         af->data->nch = 2;
         return test_output_res;
     case AF_CONTROL_COMMAND_LINE:
--- a/libaf/format.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libaf/format.c	Mon Jan 11 20:27:52 2010 +0000
@@ -47,7 +47,7 @@
     format |= AF_FORMAT_A_LAW; return format;
   }
   if(strstr(str,"ac3") || strstr(str,"AC3")){
-    format |= AF_FORMAT_AC3; return format;
+    format |= AF_FORMAT_AC3 | AF_FORMAT_16BIT; return format;
   }
   if(strstr(str,"mpeg2") || strstr(str,"MPEG2")){
     format |= AF_FORMAT_MPEG2; return format;
@@ -158,7 +158,9 @@
     { "mulaw", AF_FORMAT_MU_LAW },
     { "alaw", AF_FORMAT_A_LAW },
     { "mpeg2", AF_FORMAT_MPEG2 },
-    { "ac3", AF_FORMAT_AC3 },
+    { "ac3le", AF_FORMAT_AC3_LE },
+    { "ac3be", AF_FORMAT_AC3_BE },
+    { "ac3ne", AF_FORMAT_AC3_NE },
     { "imaadpcm", AF_FORMAT_IMA_ADPCM },
 
     { "u8", AF_FORMAT_U8 },
--- a/libao2/ao_alsa.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libao2/ao_alsa.c	Mon Jan 11 20:27:52 2010 +0000
@@ -364,15 +364,11 @@
       case AF_FORMAT_U16_BE:
 	alsa_format = SND_PCM_FORMAT_U16_BE;
 	break;
-#if !HAVE_BIGENDIAN
-      case AF_FORMAT_AC3:
-#endif
+      case AF_FORMAT_AC3_LE:
       case AF_FORMAT_S16_LE:
 	alsa_format = SND_PCM_FORMAT_S16_LE;
 	break;
-#if HAVE_BIGENDIAN
-      case AF_FORMAT_AC3:
-#endif
+      case AF_FORMAT_AC3_BE:
       case AF_FORMAT_S16_BE:
 	alsa_format = SND_PCM_FORMAT_S16_BE;
 	break;
@@ -535,6 +531,9 @@
          mp_msg(MSGT_AO,MSGL_INFO,
 		MSGTR_AO_ALSA_FormatNotSupportedByHardware, af_fmt2str_short(format));
          alsa_format = SND_PCM_FORMAT_S16_LE;
+         if (AF_FORMAT_IS_AC3(ao_data.format))
+           ao_data.format = AF_FORMAT_AC3_LE;
+         else
          ao_data.format = AF_FORMAT_S16_LE;
       }
 
--- a/libao2/ao_alsa5.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libao2/ao_alsa5.c	Mon Jan 11 20:27:52 2010 +0000
@@ -101,15 +101,11 @@
 	case AF_FORMAT_U16_BE:
 	    alsa_format.format = SND_PCM_SFMT_U16_BE;
 	    break;
-#if !HAVE_BIGENDIAN
-	case AF_FORMAT_AC3:
-#endif
+	case AF_FORMAT_AC3_LE:
 	case AF_FORMAT_S16_LE:
 	    alsa_format.format = SND_PCM_SFMT_S16_LE;
 	    break;
-#if HAVE_BIGENDIAN
-	case AF_FORMAT_AC3:
-#endif
+	case AF_FORMAT_AC3_BE:
 	case AF_FORMAT_S16_BE:
 	    alsa_format.format = SND_PCM_SFMT_S16_BE;
 	    break;
--- a/libao2/ao_dsound.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libao2/ao_dsound.c	Mon Jan 11 20:27:52 2010 +0000
@@ -432,8 +432,11 @@
 		mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: 8 channel audio not yet supported\n");
 		return 0;
 	}
+
+	if (AF_FORMAT_IS_AC3(format))
+		format = AF_FORMAT_AC3_NE;
 	switch(format){
-		case AF_FORMAT_AC3:
+		case AF_FORMAT_AC3_NE:
 		case AF_FORMAT_S24_LE:
 		case AF_FORMAT_S16_LE:
 		case AF_FORMAT_U8:
--- a/libao2/ao_mpegpes.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libao2/ao_mpegpes.c	Mon Jan 11 20:27:52 2010 +0000
@@ -250,9 +250,12 @@
     switch(format){
 	case AF_FORMAT_S16_BE:
 	case AF_FORMAT_MPEG2:
-	case AF_FORMAT_AC3:
+	case AF_FORMAT_AC3_BE:
 	    ao_data.format=format;
 	    break;
+	case AF_FORMAT_AC3_LE:
+	    ao_data.format=AF_FORMAT_AC3_BE;
+	    break;
 	default:
 	    ao_data.format=AF_FORMAT_S16_BE;
     }
@@ -333,8 +336,6 @@
 	unsigned short *s=data;
 //	if(len>2000) len=2000;
 //	printf("ao_mpegpes: len=%d  \n",len);
-	if(ao_data.format==AF_FORMAT_AC3)
-	    for(i=0;i<len/2;i++) s[i]=(s[i]>>8)|(s[i]<<8); // le<->be
 	send_mpeg_lpcm_packet(data, len, 0xA0, ao_data.pts, freq_id, my_ao_write);
     }
     return len;
--- a/libao2/ao_oss.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libao2/ao_oss.c	Mon Jan 11 20:27:52 2010 +0000
@@ -96,7 +96,7 @@
     case AF_FORMAT_MPEG2: return AFMT_MPEG;
 #endif
 #ifdef AFMT_AC3
-    case AF_FORMAT_AC3: return AFMT_AC3;
+    case AF_FORMAT_AC3_NE: return AFMT_AC3;
 #endif
     }
     mp_msg(MSGT_AO, MSGL_V, "OSS: Unknown/not supported internal format: %s\n", af_fmt2str_short(format));
@@ -139,7 +139,7 @@
     case AFMT_MPEG: return AF_FORMAT_MPEG2;
 #endif
 #ifdef AFMT_AC3
-    case AFMT_AC3: return AF_FORMAT_AC3;
+    case AFMT_AC3: return AF_FORMAT_AC3_NE;
 #endif
     }
     mp_msg(MSGT_GLOBAL,MSGL_ERR,MSGTR_AO_OSS_UnknownUnsupportedFormat, format);
@@ -303,6 +303,8 @@
   }
 
 ac3_retry:
+  if (AF_FORMAT_IS_AC3(format))
+    format = AF_FORMAT_AC3_NE;
   ao_data.format=format;
   oss_format=format2oss(format);
   if (oss_format == -1) {
--- a/libao2/ao_pcm.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libao2/ao_pcm.c	Mon Jan 11 20:27:52 2010 +0000
@@ -127,7 +127,8 @@
         format=AF_FORMAT_U8;
     case AF_FORMAT_U8:
         break;
-    case AF_FORMAT_AC3:
+    case AF_FORMAT_AC3_BE:
+    case AF_FORMAT_AC3_LE:
         bits=16;
         break;
     default:
--- a/libao2/ao_win32.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libao2/ao_win32.c	Mon Jan 11 20:27:52 2010 +0000
@@ -143,8 +143,10 @@
 	unsigned char* buffer;
 	int i;
 
+	if (AF_FORMAT_IS_AC3(format))
+		format = AF_FORMAT_AC3_NE;
 	switch(format){
-		case AF_FORMAT_AC3:
+		case AF_FORMAT_AC3_NE:
 		case AF_FORMAT_S24_LE:
 		case AF_FORMAT_S16_LE:
 		case AF_FORMAT_U8:
--- a/libmpcodecs/ad_hwac3.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/libmpcodecs/ad_hwac3.c	Mon Jan 11 20:27:52 2010 +0000
@@ -151,7 +151,7 @@
   sh->audio_in_minsize = 8192;
   sh->channels = 2;
   sh->samplesize = 2;
-  sh->sample_format = AF_FORMAT_AC3;
+  sh->sample_format = AF_FORMAT_AC3_NE;
   return 1;
 }
 
--- a/m_option.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/m_option.c	Mon Jan 11 20:27:52 2010 +0000
@@ -1146,7 +1146,9 @@
   {"mulaw", AF_FORMAT_MU_LAW},
   {"alaw", AF_FORMAT_A_LAW},
   {"mpeg2", AF_FORMAT_MPEG2},
-  {"ac3", AF_FORMAT_AC3},
+  {"ac3le", AF_FORMAT_AC3_LE},
+  {"ac3be", AF_FORMAT_AC3_BE},
+  {"ac3ne", AF_FORMAT_AC3_NE},
   {"imaadpcm", AF_FORMAT_IMA_ADPCM},
   // ORIDNARY
   {"u8", AF_FORMAT_U8},
--- a/stream/tv.c	Mon Jan 11 20:02:46 2010 +0000
+++ b/stream/tv.c	Mon Jan 11 20:27:52 2010 +0000
@@ -760,7 +760,6 @@
 	    case AF_FORMAT_MU_LAW:
 	    case AF_FORMAT_A_LAW:
 	    case AF_FORMAT_MPEG2:
-	    case AF_FORMAT_AC3:
 	    default:
 		mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_UnsupportedAudioType,
 		    af_fmt2str(audio_format, buf, 128), audio_format);