[MPlayer-users] Problems with mplayer on PPC

Rogério Brito linuxconsult at yahoo.com.br
Fri Apr 26 09:33:01 CEST 2002


On Apr 25 2002, Arpi wrote:
> yes. ok, i've fixed in CVS, please test both avi and dvd pcm.

	Yes, it's working correctly now, for both inputs, thanks.

> the keypoint: _both_ AFMT and byte order has to be swapped...

	Humm, curious. I'll read more about that, as I learn more
	about mplayer.

	In the mean time, I apparently solved the problem with the WAV
	files being with incorrect headers (with -ao pcm). In fact,
	they were with byte-swapped headers *and* content. I made a
	patch which I tested on both ppc and x86. It seems to work
	well on both my machines and I believe that it is not *that*
	bad. I also tried to make it reasonably clean.

	I tested my patch with some files on x86 and it generates the
	same output as the old ao_pcm.c generated (as one would
	expect).

	BTW, it seems that (both the original and my patched) ao_pcm.c
	has a problem with 8-bit files and generates an incorrect
	header. If I have some spare time, I'll look into that and see
	what is happening (if I can).

	My patch is attached to this message. Could you apply it if you
	think that it is correct, please? If not, please let me know
	and I'll try to make it appropriate to inclusion, when I have
	some free time.


	Thanks, Roger...

P.S.: I also made some cosmetic changest to avoid lines being much
longer than 80 chars.
-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  Rogério Brito - rbrito at iname.com - http://www.ime.usp.br/~rbrito/
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-------------- next part --------------
--- MPlayer-20020425/libao2/ao_pcm.c	Sat Mar  2 15:54:58 2002
+++ mplayer-0.90/libao2/ao_pcm.c	Fri Apr 26 03:37:01 2002
@@ -1,6 +1,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "config.h"         /* Needed for WORDS_BIGENDIAN definition -- rbrito */
+#include "afmt.h"
 #include "audio_out.h"
 #include "audio_out_internal.h"
 
@@ -19,6 +21,20 @@
 char *ao_outputfilename = NULL;
 int ao_pcm_waveheader = 1;
 
+/* Are there other conversion routines to be used instead of these? */
+#ifdef WORDS_BIGENDIAN
+#   define u32_le(x)  (((x) & 0xff000000) >> 24 | \
+                      ((x) & 0x00ff0000) >>  8 | \
+                      ((x) & 0x0000ff00) <<  8 | \
+                      ((x) & 0x000000ff) << 24)
+#   define u16_le(x)  (((x) & 0xff00) >> 8 | ((x) & 0x00ff) << 8)
+
+#else
+
+#   define u32_le(x)  (x)
+#   define u16_le(x)  (x)
+#endif
+
 #define WAV_ID_RIFF 0x46464952 /* "RIFF" */
 #define WAV_ID_WAVE 0x45564157 /* "WAVE" */
 #define WAV_ID_FMT  0x20746d66 /* "fmt " */
@@ -44,19 +60,19 @@
 
 
 static struct WaveHeader wavhdr = {
-	WAV_ID_RIFF,
-	0x00000000,
-	WAV_ID_WAVE,
-	WAV_ID_FMT,
-	16,
-	WAV_ID_PCM,
-	2,
-	44100,
-	192000,
-	4,
-	16,
-	WAV_ID_DATA,
-	0x00000000
+	u32_le(WAV_ID_RIFF),
+	u32_le(0x00000000),
+	u32_le(WAV_ID_WAVE),
+	u32_le(WAV_ID_FMT),
+	u32_le(16),
+	u16_le(WAV_ID_PCM),
+	u16_le(2),
+	u32_le(44100),
+	u32_le(192000),
+	u16_le(4),
+	u16_le(16),
+	u32_le(WAV_ID_DATA),
+	u32_le(0x00000000)
 };
 
 static FILE *fp = NULL;
@@ -69,19 +85,34 @@
 // open & setup audio device
 // return: 1=success 0=fail
 static int init(int rate,int channels,int format,int flags){
+	int bits;
 	if(!ao_outputfilename) {
 		ao_outputfilename = (char *) malloc(sizeof(char) * 14);
-		strcpy(ao_outputfilename,(ao_pcm_waveheader ? "audiodump.wav" : "audiodump.pcm"));
+		strcpy(ao_outputfilename,
+		       (ao_pcm_waveheader ? "audiodump.wav" : "audiodump.pcm"));
 	}
 	
-	wavhdr.channels = channels;
-	wavhdr.sample_rate = rate;
-	wavhdr.bytes_per_second = rate * (format / 8) * channels;
-	wavhdr.bits = format;
+	/* bits is only equal to format if (format == 8) or (format == 16);
+	   this means that the following "if" is a kludge and should
+	   really be a switch to be correct in all cases */
+	if (format == AFMT_S16_BE) { bits = 16;	}
+	else { bits = format; }
+
+	wavhdr.channels = u16_le(channels);
+	wavhdr.sample_rate = u32_le(rate);
+	wavhdr.bytes_per_second = rate * (bits / 8) * channels;
+	wavhdr.bytes_per_second = u32_le(wavhdr.bytes_per_second);
+	wavhdr.bits = u16_le(bits);
+
+	printf("PCM: File: %s (%s)\n"
+	       "PCM: Samplerate: %iHz Channels: %s Format %s\n",
+	       ao_outputfilename, (ao_pcm_waveheader?"WAVE":"RAW PCM"), rate,
+	       (channels > 1) ? "Stereo" : "Mono", audio_out_format_name(format));
+	printf("PCM: Info: fastest dumping is achieved with -vo null "
+	       "-hardframedrop.\n"
+	       "PCM: Info: to write WAVE files use -waveheader (default); "
+	       "for RAW PCM -nowaveheader.\n");
 
-	printf("PCM: File: %s (%s) Samplerate: %iHz Channels: %s Format %s\n", ao_outputfilename, (ao_pcm_waveheader?"WAVE":"RAW PCM"), rate, (channels > 1) ? "Stereo" : "Mono", audio_out_format_name(format));
-	printf("PCM: Info - fastest dumping is achieved with -vo null -hardframedrop.\n");
-	printf("PCM: Info - to write WAVE files use -waveheader (default), for RAW PCM -nowaveheader.\n");
 	fp = fopen(ao_outputfilename, "wb");
 
 	ao_data.outburst = 65536;
@@ -101,6 +132,7 @@
 	
 	if(ao_pcm_waveheader){ /* Write wave header */
 		wavhdr.file_length = wavhdr.data_length + sizeof(wavhdr) - 8;
+		wavhdr.file_length = u32_le(wavhdr.file_length);
 		fseek(fp, 0, SEEK_SET);
 		fwrite(&wavhdr,sizeof(wavhdr),1,fp);
 	}
@@ -136,9 +168,21 @@
 // return: number of bytes played
 static int play(void* data,int len,int flags){
 
+#ifdef WORDS_BIGENDIAN
+	register int i;
+	unsigned short *buffer = (unsigned short *) data;
+
+	if (wavhdr.bits == u16_le(16)) {
+	  for(i = 0; i < len/2; ++i) {
+	    buffer[i] = u16_le(buffer[i]);
+	  }
+	}
+	/* FIXME: take care of cases with more than 8 bits here? */
+#endif 
+	
 	//printf("PCM: Writing chunk!\n");
 	fwrite(data,len,1,fp);
-	
+
 	if(ao_pcm_waveheader)
 		wavhdr.data_length += len;
 	


More information about the MPlayer-users mailing list