[MPlayer-dev-eng] [PATCH] Multi-channel reorder (aac, pcm and ac3)
Giacomo Comes
comes at naic.edu
Mon Nov 19 04:15:08 CET 2007
On Mon, Nov 19, 2007 at 03:10:16AM +0800, Ulion wrote:
> 2007/11/17, Giacomo Comes <comes at naic.edu>:
> > Here is (hopefully) the final try to include the channels reordering
> > code in MPlayer.
> > There has been several (different) attempt to fix the problem and none
> > of them fully satisfies the developers (planar formats will do, but
> > none appears to be intrested in implementing that).
> >
> > People intrested can check the following threads for a refresh:
> >
> > [PATCH] channel reordering for 6ch audio
> > http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-July/044844.html
> >
> > [RFC] 6-channel AAC and channel reordering
> > http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-October/046963.html
> >
> > [PATCH] audio channel remapping
> > http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-November/047269.html
> >
> > [PATCH] [TEST FUNC] Multi-channel reorder function
> > http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2007-November/054820.html
> >
> > The patches I'm submitting are an extension of the ones submitted by
> > Alexander Ponyatikh and it seems they are the one with higher probability to
> > be accepted.
> >
> > Please let's discuss then now and find a final agreement.
> >
>
> int n;
> + if (encoder->params.channels == 6 || encoder->params.channels == 5 &&
> + !strcmp(lavc_acodec->name,"ac3") || !strcmp(lavc_acodec->name,"libfaac") ) {
>
> should be if ( ( == || == ) && (!strcmp || !strcmp))
Of course. Thanks for noticing it.
Update attached.
Giacomo
-------------- next part --------------
diff -Nraub mplayer.ori/libmpcodecs/ad_faad.c mplayer/libmpcodecs/ad_faad.c
--- mplayer.ori/libmpcodecs/ad_faad.c 2007-08-31 12:32:31.000000000 -0400
+++ mplayer/libmpcodecs/ad_faad.c 2007-11-15 23:31:04.000000000 -0400
@@ -277,7 +277,20 @@
/* XXX: samples already multiplied by channels! */
mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Successfully decoded frame (%ld Bytes)!\n",
sh->samplesize*faac_finfo.samples);
+
+ if (sh->channels == 6 || sh->channels == 5) {
+ //Source channel order: C L R SL SR LFE
+ //We want: L R SL SR C LFE
+ int i;
+ for (i = 0; i < faac_finfo.samples; i += sh->channels) {
+ memcpy(buf+len+i*sh->samplesize,faac_sample_buffer+(i+1)*sh->samplesize, sh->samplesize*4); // L R SL SR
+ memcpy(buf+len+(i+4)*sh->samplesize,faac_sample_buffer+i*sh->samplesize, sh->samplesize); // C
+ if (sh->channels == 6)
+ memcpy(buf+len+(i+5)*sh->samplesize,faac_sample_buffer+(i+5)*sh->samplesize, sh->samplesize); // LFE
+ }
+ } else {
memcpy(buf+len,faac_sample_buffer, sh->samplesize*faac_finfo.samples);
+ }
last_dec_len = sh->samplesize*faac_finfo.samples;
len += last_dec_len;
sh->pts_bytes += last_dec_len;
-------------- next part --------------
diff -Nraub mplayer.ori/libmpcodecs/ad_pcm.c mplayer/libmpcodecs/ad_pcm.c
--- mplayer.ori/libmpcodecs/ad_pcm.c 2006-11-16 16:07:23.000000000 -0400
+++ mplayer/libmpcodecs/ad_pcm.c 2007-11-15 23:35:48.000000000 -0400
@@ -17,6 +17,8 @@
LIBAD_EXTERN(pcm)
+static void *tmp_buff = NULL;
+
static int init(sh_audio_t *sh_audio)
{
WAVEFORMATEX *h=sh_audio->wf;
@@ -90,6 +92,8 @@
}
if (!sh_audio->samplesize) // this would cause MPlayer to hang later
sh_audio->samplesize = 2;
+ if (sh_audio->channels == 6 || sh_audio->channels == 5)
+ tmp_buff = malloc(2 * sh_audio->samplesize);
return 1;
}
@@ -101,6 +105,10 @@
static void uninit(sh_audio_t *sh)
{
+ if (tmp_buff) {
+ free(tmp_buff);
+ tmp_buff = NULL;
+ }
}
static int control(sh_audio_t *sh,int cmd,void* arg, ...)
@@ -126,5 +134,15 @@
// based on channels in preinit()
return -1;
len=demux_read_data(sh_audio->ds,buf,len);
+ if (sh_audio->channels == 6 || sh_audio->channels == 5) {
+ //Source channel order: L R C LFE SL SR or L R C SL SR
+ //We want: L R SL SR C LFE or L R SL SR C
+ int i, samples = len / sh_audio->samplesize;
+ for (i = 0; i < samples; i += sh_audio->channels) {
+ memcpy(tmp_buff, buf+(i+2)*sh_audio->samplesize, ((sh_audio->channels+1)%2+1)*sh_audio->samplesize); // C (LFE) -> tmp
+ memcpy(buf+(i+2)*sh_audio->samplesize, buf+(i+(sh_audio->channels+1)%2+3)*sh_audio->samplesize, 2*sh_audio->samplesize); // SL SR -> 2,3
+ memcpy(buf+(i+4)*sh_audio->samplesize, tmp_buff, ((sh_audio->channels+1)%2+1)*sh_audio->samplesize); // C (LFE) -> 4(,5)
+ }
+ }
return len;
}
-------------- next part --------------
diff -Nraub mplayer.ori/libmpcodecs/ae_faac.c mplayer/libmpcodecs/ae_faac.c
--- mplayer.ori/libmpcodecs/ae_faac.c 2007-04-09 13:05:37.000000000 -0400
+++ mplayer/libmpcodecs/ae_faac.c 2007-11-15 23:37:36.000000000 -0400
@@ -98,6 +98,25 @@
static int encode_faac(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size)
{
+ if (encoder->params.channels == 6 || encoder->params.channels == 5) {
+ //Codec wants: C L R SL SR LFE
+ //We have: L R SL SR C LFE
+ int i;
+ uint32_t tmp32;
+ uint16_t tmp16;
+ for (i = 0; i < len; i += encoder->params.channels*divisor) {
+ if (divisor == 4) {
+ tmp32 = ((uint32_t*)(src+i))[4];
+ memmove(src+i+divisor, src+i, 4*divisor);
+ ((uint32_t*)(src+i))[0] = tmp32;
+ } else {
+ tmp16 = ((uint16_t*)(src+i))[4];
+ memmove(src+i+divisor, src+i, 4*divisor);
+ ((uint16_t*)(src+i))[0] = tmp16;
+ }
+ }
+ }
+
// len is divided by the number of bytes per sample
enc_frame_size = faacEncEncode(faac, (int32_t*) src, len / divisor, dest, max_size);
-------------- next part --------------
diff -Nraub mplayer.ori/libmpcodecs/ae_lavc.c mplayer/libmpcodecs/ae_lavc.c
--- mplayer.ori/libmpcodecs/ae_lavc.c 2007-09-10 23:04:12.000000000 -0400
+++ mplayer/libmpcodecs/ae_lavc.c 2007-11-15 23:39:35.000000000 -0400
@@ -111,6 +111,23 @@
static int encode_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size)
{
int n;
+ if ( (encoder->params.channels == 6 || encoder->params.channels == 5) &&
+ (!strcmp(lavc_acodec->name,"ac3") || !strcmp(lavc_acodec->name,"libfaac")) ) {
+ //Codec wants: L C R SL SR LFE (ac3)
+ //Codec wants: C L R SL SR LFE (aac)
+ //We have: L R SL SR C LFE
+ int i,d0,d1,d2,w;
+ uint16_t tmp;
+ if (!strcmp(lavc_acodec->name,"ac3"))
+ d1=4,d2=2,w=3*2,d0=d2/2;
+ else
+ d1=2,d2=0,w=4*2,d0=d2/2;
+ for (i = 0; i < size; i += encoder->params.channels*2) {
+ tmp = ((uint16_t*)(src+i))[4];
+ memmove(src+i+d1, src+i+d2, w);
+ ((uint16_t*)(src+i))[d0] = tmp;
+ }
+ }
n = avcodec_encode_audio(lavc_actx, dest, size, src);
compressed_frame_size = n;
return n;
-------------- next part --------------
diff -Nraub mplayer.ori/libmpcodecs/ae_pcm.c mplayer/libmpcodecs/ae_pcm.c
--- mplayer.ori/libmpcodecs/ae_pcm.c 2007-04-09 13:05:39.000000000 -0400
+++ mplayer/libmpcodecs/ae_pcm.c 2007-11-15 23:40:56.000000000 -0400
@@ -38,7 +38,27 @@
static int encode_pcm(audio_encoder_t *encoder, uint8_t *dest, void *src, int nsamples, int max_size)
{
max_size = FFMIN(nsamples, max_size);
+ if (encoder->params.channels == 6 || encoder->params.channels == 5) {
+ //Codec wants: L R C LFE SL SR L R C SL SR
+ //We have: L R SL SR C LFE L R SL SR C
+ max_size -= max_size % (2*encoder->params.channels);
+ int i;
+ for (i = 0; i < max_size; i += 2*encoder->params.channels) {
+ if (encoder->params.channels == 6) {
+ ((uint32_t*)(dest+i))[0] = ((uint32_t*)(src+i))[0]; //L R -> 0,1
+ ((uint32_t*)(dest+i))[1] = ((uint32_t*)(src+i))[2]; //C LFE -> 2,3
+ ((uint32_t*)(dest+i))[2] = ((uint32_t*)(src+i))[1]; //SL SR -> 4,5
+ } else {
+ ((uint16_t*)(dest+i))[0] = ((uint16_t*)(src+i))[0]; //L -> 0
+ ((uint16_t*)(dest+i))[1] = ((uint16_t*)(src+i))[1]; //R -> 1
+ ((uint16_t*)(dest+i))[2] = ((uint16_t*)(src+i))[4]; //C -> 2
+ ((uint16_t*)(dest+i))[3] = ((uint16_t*)(src+i))[2]; //SL -> 3
+ ((uint16_t*)(dest+i))[4] = ((uint16_t*)(src+i))[3]; //SR -> 4
+ }
+ }
+ } else {
memcpy(dest, src, max_size);
+ }
return max_size;
}
-------------- next part --------------
diff -Nraub mplayer.ori/libao2/ao_pcm.c mplayer/libao2/ao_pcm.c
--- mplayer.ori/libao2/ao_pcm.c 2006-12-11 14:35:25.000000000 -0400
+++ mplayer/libao2/ao_pcm.c 2007-11-15 23:41:59.000000000 -0400
@@ -197,8 +197,20 @@
}
#endif
+ if (ao_data.channels == 6 || ao_data.channels == 5) {
+ int i, samplesize = wavhdr.bits/8;
+ for (i = 0; i < len; i += samplesize*ao_data.channels) {
+ //L R SL SR C LFE -> L R C LFE SL SR
+ //L R SL SR C -> L R C SL SR
+ fwrite(data+i, samplesize, 2, fp);
+ fwrite(data+i+4*samplesize, samplesize, (ao_data.channels+1)%2+1, fp);
+ fwrite(data+i+2*samplesize, samplesize, 2, fp);
+ }
+ len -= len % (ao_data.channels*samplesize);
+ } else {
//printf("PCM: Writing chunk!\n");
fwrite(data,len,1,fp);
+ }
if(ao_pcm_waveheader)
wavhdr.data_length += len;
More information about the MPlayer-dev-eng
mailing list