[MPlayer-dev-eng] [PATCH] add support for big-endian PCM output
Grant Edwards
grante at visi.com
Wed Mar 21 18:11:29 CET 2007
[I posted this to the mencoder-user list a while back. Judging
by the lack of any sort of rsopnse that was the wrong forum.]
I needed to be able to encode to 16-bit uncompressed big-endian
PCM. I couldn't get either "-format sb16be" or "-af format=s16be"
to encode to big-endian format, so I gave up and added a "pcms"
audio encoder that swaps the byte-order of the data stream. In
order to get lavf containers to label the stream correctly, I
had to invent a new "wav" audio tag for big-endian PCM.
Although it works I have a feeling that this wasn't really the
"right" way to do it. If anybody would care to comment or
suggest a better way to get big-endian PCM output please feel
free to do so.
Anyway, the patch is available at
http://www.visi.com/~grante/sansa/mplayer-1.0rc1-encode-bigendian-pcm.patch
and is also included below.
--------------------------------8<--------------------------------------
diff -r -U9 MPlayer-1.0rc1/cfg-mencoder.h MPlayer-1.0rc1gbe/cfg-mencoder.h
--- MPlayer-1.0rc1/cfg-mencoder.h 2006-10-22 17:32:31.000000000 -0500
+++ MPlayer-1.0rc1gbe/cfg-mencoder.h 2007-01-08 11:20:59.000000000 -0600
@@ -86,18 +86,19 @@
" x264 - H.264 encoding\n"
#endif
"\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
m_option_t oac_conf[]={
{"copy", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_COPY, NULL},
{"pcm", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_PCM, NULL},
+ {"pcms", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_PCMS, NULL},
#ifdef HAVE_MP3LAME
{"mp3lame", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_VBRMP3, NULL},
#else
{"mp3lame", "MPlayer was compiled without libmp3lame support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
#endif
#ifdef USE_LIBAVCODEC
{"lavc", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_LAVC, NULL},
#else
{"lavc", "MPlayer was compiled without libavcodec. See README or DOCS.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
@@ -114,18 +115,19 @@
#endif
#ifdef HAVE_FAAC
{"faac", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_FAAC, NULL},
#else
{"faac", "MPlayer was compiled without libfaac. See README or DOCS.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
#endif
{"help", "\nAvailable codecs:\n"
" copy - frame copy, without re-encoding (useful for AC3)\n"
" pcm - uncompressed PCM audio\n"
+ " pcms - uncompressed PCM audio (byteswapped)\n"
#ifdef HAVE_MP3LAME
" mp3lame - cbr/abr/vbr MP3 using libmp3lame\n"
#endif
#ifdef USE_LIBAVCODEC
" lavc - FFmpeg audio encoder (MP2, AC3, ...)\n"
#endif
#ifdef HAVE_TOOLAME
" toolame - Toolame MP2 audio encoder\n"
#endif
Only in MPlayer-1.0rc1gbe: cfg-mencoder.h-orig
diff -r -U9 MPlayer-1.0rc1/libavformat/riff.c MPlayer-1.0rc1gbe/libavformat/riff.c
--- MPlayer-1.0rc1/libavformat/riff.c 2006-10-22 17:32:34.000000000 -0500
+++ MPlayer-1.0rc1gbe/libavformat/riff.c 2007-01-09 13:41:45.000000000 -0600
@@ -166,18 +166,19 @@
{ CODEC_ID_NONE, 0 },
};
const CodecTag codec_wav_tags[] = {
{ CODEC_ID_MP2, 0x50 },
{ CODEC_ID_MP3, 0x55 },
{ CODEC_ID_AC3, 0x2000 },
{ CODEC_ID_DTS, 0x2001 },
{ CODEC_ID_PCM_S16LE, 0x01 },
+ { CODEC_ID_PCM_S16BE, 0x9999 },
{ CODEC_ID_PCM_U8, 0x01 }, /* must come after s16le in this list */
{ CODEC_ID_PCM_S24LE, 0x01 },
{ CODEC_ID_PCM_S32LE, 0x01 },
{ CODEC_ID_PCM_ALAW, 0x06 },
{ CODEC_ID_PCM_MULAW, 0x07 },
{ CODEC_ID_ADPCM_MS, 0x02 },
{ CODEC_ID_ADPCM_IMA_WAV, 0x11 },
{ CODEC_ID_ADPCM_YAMAHA, 0x20 },
{ CODEC_ID_ADPCM_G726, 0x45 },
diff -r -U9 MPlayer-1.0rc1/libmpcodecs/ae.c MPlayer-1.0rc1gbe/libmpcodecs/ae.c
--- MPlayer-1.0rc1/libmpcodecs/ae.c 2006-10-22 17:32:24.000000000 -0500
+++ MPlayer-1.0rc1gbe/libmpcodecs/ae.c 2007-01-08 11:23:15.000000000 -0600
@@ -43,18 +43,22 @@
encoder = (audio_encoder_t *) calloc(1, sizeof(audio_encoder_t));
memcpy(&encoder->params, params, sizeof(audio_encoding_params_t));
encoder->stream = stream;
switch(stream->codec)
{
case ACODEC_PCM:
ris = mpae_init_pcm(encoder);
break;
+
+ case ACODEC_PCMS:
+ ris = mpae_init_pcms(encoder);
+ break;
#ifdef HAVE_TOOLAME
case ACODEC_TOOLAME:
ris = mpae_init_toolame(encoder);
break;
#endif
#ifdef USE_LIBAVCODEC
case ACODEC_LAVC:
ris = mpae_init_lavc(encoder);
break;
diff -r -U9 MPlayer-1.0rc1/libmpcodecs/ae.h MPlayer-1.0rc1gbe/libmpcodecs/ae.h
--- MPlayer-1.0rc1/libmpcodecs/ae.h 2006-10-22 17:32:24.000000000 -0500
+++ MPlayer-1.0rc1gbe/libmpcodecs/ae.h 2007-01-08 11:26:21.000000000 -0600
@@ -4,18 +4,19 @@
#define ACODEC_COPY 0
#define ACODEC_PCM 1
#define ACODEC_VBRMP3 2
#define ACODEC_NULL 3
#define ACODEC_LAVC 4
#define ACODEC_TOOLAME 5
#define ACODEC_FAAC 6
#define ACODEC_TWOLAME 7
+#define ACODEC_PCMS 99
#define AE_NEEDS_COMPRESSED_INPUT 1
typedef struct {
int channels;
int sample_rate;
int bitrate;
int samples_per_frame;
int audio_preload;
diff -r -U9 MPlayer-1.0rc1/libmpcodecs/ae_pcm.c MPlayer-1.0rc1gbe/libmpcodecs/ae_pcm.c
--- MPlayer-1.0rc1/libmpcodecs/ae_pcm.c 2006-10-22 17:32:24.000000000 -0500
+++ MPlayer-1.0rc1gbe/libmpcodecs/ae_pcm.c 2007-01-08 13:18:37.000000000 -0600
@@ -65,9 +65,63 @@
encoder->bind = bind_pcm;
encoder->get_frame_size = get_frame_size;
encoder->set_decoded_len = set_decoded_len;
encoder->encode = encode_pcm;
encoder->close = close_pcm;
return 1;
}
+
+
+//==================================================
+//Byteswapped version
+static int bind_pcms(audio_encoder_t *encoder, muxer_stream_t *mux_a)
+{
+ mux_a->h.dwScale=1;
+ mux_a->h.dwRate=encoder->params.sample_rate;
+ mux_a->wf=malloc(sizeof(WAVEFORMATEX));
+ mux_a->wf->wFormatTag= 0x9999;
+ mux_a->wf->nChannels=encoder->params.channels;
+ mux_a->h.dwSampleSize=2*mux_a->wf->nChannels;
+ mux_a->wf->nBlockAlign=mux_a->h.dwSampleSize;
+ mux_a->wf->nSamplesPerSec=mux_a->h.dwRate;
+ mux_a->wf->nAvgBytesPerSec=mux_a->h.dwSampleSize*mux_a->wf->nSamplesPerSec;
+ mux_a->wf->wBitsPerSample=16;
+ mux_a->wf->cbSize=0; // FIXME for l3codeca.acm
+
+ encoder->input_format = (mux_a->wf->wBitsPerSample==8) ? AF_FORMAT_U8 : AF_FORMAT_S16_LE;
+ encoder->min_buffer_size = 16384;
+ encoder->max_buffer_size = mux_a->wf->nAvgBytesPerSec;
+
+ return 1;
+}
+
+
+static int encode_pcms(audio_encoder_t *encoder, uint8_t *dest, void *src, int nsamples, int max_size)
+{
+ int i;
+ max_size = min(nsamples, max_size);
+ memcpy(dest, src, max_size);
+ for (i=0; i<(max_size-1); i+=2)
+ {
+ uint8_t t = dest[i];
+ dest[i] = dest[i+1];
+ dest[i+1] = t;
+ }
+ return max_size;
+}
+
+int mpae_init_pcms(audio_encoder_t *encoder)
+{
+ encoder->params.samples_per_frame = encoder->params.sample_rate;
+ encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8;
+
+ encoder->decode_buffer_size = encoder->params.bitrate / 8;
+ encoder->bind = bind_pcms;
+ encoder->get_frame_size = get_frame_size;
+ encoder->set_decoded_len = set_decoded_len;
+ encoder->encode = encode_pcms;
+ encoder->close = close_pcm;
+
+ return 1;
+}
Only in MPlayer-1.0rc1gbe/libmpcodecs: ae_pcm.c-orig
diff -r -U9 MPlayer-1.0rc1/libmpcodecs/ae_pcm.h MPlayer-1.0rc1gbe/libmpcodecs/ae_pcm.h
--- MPlayer-1.0rc1/libmpcodecs/ae_pcm.h 2006-10-22 17:32:24.000000000 -0500
+++ MPlayer-1.0rc1gbe/libmpcodecs/ae_pcm.h 2007-01-08 11:53:00.000000000 -0600
@@ -1,8 +1,9 @@
#ifndef __AE_PCM_H_
#define __AE_PCM_H_
#include "ae.h"
int mpae_init_pcm(audio_encoder_t *encoder);
+int mpae_init_pcms(audio_encoder_t *encoder);
#endif
diff -r -U9 MPlayer-1.0rc1/mencoder.c MPlayer-1.0rc1gbe/mencoder.c
--- MPlayer-1.0rc1/mencoder.c 2006-10-22 17:32:31.000000000 -0500
+++ MPlayer-1.0rc1gbe/mencoder.c 2007-01-08 11:22:35.000000000 -0600
@@ -12,18 +12,19 @@
#define ACODEC_COPY 0
#define ACODEC_PCM 1
#define ACODEC_VBRMP3 2
#define ACODEC_NULL 3
#define ACODEC_LAVC 4
#define ACODEC_TOOLAME 5
#define ACODEC_FAAC 6
#define ACODEC_TWOLAME 7
+#define ACODEC_PCMS 99
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "config.h"
#ifdef __MINGW32__
#define SIGHUP 1
--------------------------------8<--------------------------------------
--
Grant Edwards grante Yow! Yow! Those people
at look exactly like Donnie
visi.com and Marie Osmond!!
More information about the MPlayer-dev-eng
mailing list