[MPlayer-dev-eng] Re: [PATCH] encoding audio with libavcodec

Tobias Diedrich ranma at gmx.at
Sun Nov 2 06:30:48 CET 2003


Nico wrote:

> Daniele Forghieri and I have developed this patch to use Lavc audio 
> codecs during encoding.

Nice :-)
I looked over it and made a few modifications.
It now initializes lavc first and uses alavc_ctx->frame_size and
alavc_ctx->block_align to set mux_a->wf->nBlockAlign.
cbSize has to be 12 (sizeof(waveformat-mpeglayer3waveformat)), or the
extension is ignored (which it is anyway if the codec is not mp3).
I changed the default bitrate to 224 because IMHO 128 is quite low for
mp2.  adpcm_ima_wav almost works.

-- 
Tobias						PGP: http://9ac7e0bc.2ya.com
This mail is made of 100% recycled bits
-------------- next part --------------
Index: mencoder.c
===================================================================
RCS file: /cvsroot/mplayer/main/mencoder.c,v
retrieving revision 1.219
diff -u -r1.219 mencoder.c
--- mencoder.c	22 Oct 2003 17:04:15 -0000	1.219
+++ mencoder.c	2 Nov 2003 05:22:58 -0000
@@ -14,6 +14,7 @@
 #define ACODEC_PCM 1
 #define ACODEC_VBRMP3 2
 #define ACODEC_NULL 3
+#define ACODEC_LAVC 4
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -71,6 +72,21 @@
 
 #include "osdep/timer.h"
 
+#ifdef USE_LIBAVCODEC
+// for lavc audio encoding
+#include "libavcodec/avcodec.h"
+AVCodec        *alavc_codec;
+AVCodecContext *alavc_ctx = NULL;
+static char    *alavc_param_codec = "mp2";
+static int      alavc_param_bitrate = 224;
+static int      alavc_ok = 0;
+static uint16_t alavc_codec_tag = 0x0;
+// tmp buffer for lavc audio encoding (to free!!!!!)
+void *alavc_buf = NULL;
+
+uint32_t alavc_find_tag(char *codec);
+#endif
+
 int vo_doublebuffering=0;
 int vo_directrendering=0;
 int vo_config_count=0;
@@ -792,6 +808,101 @@
     }
     break;
 #endif
+#ifdef USE_LIBAVCODEC
+case ACODEC_LAVC:
+    if(! alavc_param_codec)
+    {
+       mp_msg(MSGT_MENCODER, MSGL_FATAL, "Audio LAVC, Missing codec name!\n");
+       exit(1);
+    }
+    avcodec_init();
+    avcodec_register_all();
+
+    alavc_codec = avcodec_find_encoder_by_name(alavc_param_codec);
+    if (!alavc_codec)
+    {
+       mp_msg(MSGT_MENCODER, MSGL_FATAL, "Audio LAVC, couldn't find encoder for codec %s\n", alavc_param_codec);
+       break;
+    }
+
+    alavc_ctx = avcodec_alloc_context();
+    if(alavc_ctx == NULL)
+    {
+       mp_msg(MSGT_MENCODER, MSGL_FATAL, "Audio LAVC, couldn't allocate context!\n");
+       break;
+    }
+
+    // put sample parameters
+    alavc_ctx->bit_rate = alavc_param_bitrate * 1000;
+    alavc_ctx->channels = audio_output_channels ? audio_output_channels : sh_audio->channels;
+    alavc_ctx->sample_rate = force_srate ? force_srate : sh_audio->samplerate;
+
+    if(avcodec_open(alavc_ctx, alavc_codec) < 0)
+    {
+       mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't open codec %s, br=%d\n", alavc_param_codec, alavc_param_bitrate);
+       break;
+    }
+
+    alavc_buf = malloc(alavc_ctx->frame_size * 2 * alavc_ctx->channels);
+    if(alavc_buf == NULL)
+    {
+       fprintf(stderr, "Couldn't allocate %d bytes\n", alavc_ctx->frame_size * 2 * alavc_ctx->channels);
+       break;
+    }
+
+    alavc_ok = 1;
+
+    mux_a->h.dwSampleSize = 1;
+    mux_a->h.dwRate = (1000 * alavc_param_bitrate / 8);
+    mux_a->h.dwScale = 1;
+
+    if (sizeof(MPEGLAYER3WAVEFORMAT) != 30)
+       mp_msg(MSGT_MENCODER, MSGL_WARN,
+              "sizeof(MPEGLAYER3WAVEFORMAT)==%d!=30, maybe broken C compiler?\n",
+              sizeof(MPEGLAYER3WAVEFORMAT));
+
+    mux_a->wf = malloc(sizeof(MPEGLAYER3WAVEFORMAT));  // should be 30
+
+    mux_a->wf->nChannels = alavc_ctx->channels;
+    mux_a->wf->nSamplesPerSec = alavc_ctx->sample_rate;
+    mux_a->wf->nAvgBytesPerSec = (1000 * alavc_param_bitrate / 8);
+    if (alavc_ctx->block_align)
+        mux_a->wf->nBlockAlign = alavc_ctx->block_align;
+    else
+        mux_a->wf->nBlockAlign = alavc_ctx->frame_size;
+    mux_a->wf->wBitsPerSample = 0;
+    mux_a->wf->cbSize = 12;
+
+    ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1;
+    ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2;
+    ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nAvgBytesPerSec * mux_a->wf->nBlockAlign / mux_a->wf->nSamplesPerSec;
+    ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1;
+    ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0;
+
+    if(alavc_codec_tag != 0)
+        mux_a->wf->wFormatTag = alavc_codec_tag;
+    else
+        mux_a->wf->wFormatTag = alavc_find_tag(alavc_param_codec);
+
+    // setup filter:
+    if (!init_audio_filters(
+       sh_audio,
+       sh_audio->samplerate, sh_audio->channels,
+       sh_audio->sample_format, sh_audio->samplesize,
+       mux_a->wf->nSamplesPerSec, mux_a->wf->nChannels,
+#ifdef WORDS_BIGENDIAN
+       AFMT_S16_BE, 2,
+#else
+       AFMT_S16_LE, 2,
+#endif
+       alavc_ctx->frame_size, mux_a->h.dwRate * mux_a->wf->nChannels * 2)) {
+        mp_msg(MSGT_CPLAYER, MSGL_ERR, "Couldn't find matching filter / ao format!\n");
+    }
+
+    mp_msg(MSGT_MENCODER, MSGL_V, "FRAME_SIZE: %d, BUFFER_SIZE: %d, TAG: 0x%x\n", alavc_ctx->frame_size, alavc_ctx->frame_size * 2 * alavc_ctx->channels, mux_a->wf->wFormatTag);
+
+    break;
+#endif
 }
 
 if (verbose>1) print_wave_header(mux_a->wf);
@@ -932,6 +1043,25 @@
 		len=mux_a->h.dwSampleSize*(mux_a->h.dwRate/audio_density);
 		len=dec_audio(sh_audio,mux_a->buffer,len);
 		break;
+#ifdef USE_LIBAVCODEC
+            case ACODEC_LAVC:
+               {
+                       if(alavc_ok)
+                       {
+                               int  size, rd_len;
+
+                               size = alavc_ctx->frame_size * 2 * mux_a->wf->nChannels;
+
+                               rd_len = dec_audio(sh_audio, alavc_buf, size);
+                               if(rd_len != size)
+                                       break;
+
+                               // Encode one frame
+                               len = avcodec_encode_audio(alavc_ctx, &(mux_a->buffer[0]), size, alavc_buf);
+                       }
+               }
+               break;
+#endif
 	    }
 	} else {
 	    // VBR - encode/copy an audio frame
@@ -1294,6 +1424,11 @@
 if(demuxer) free_demuxer(demuxer);
 if(stream) free_stream(stream); // kill cache thread
 
+#ifdef USE_LIBAVCODEC
+if(alavc_buf != NULL)
+    free(alavc_buf);
+#endif
+
 return interrupted;
 }
 
@@ -1600,3 +1735,20 @@
 	mencoder_exit(0, NULL);
 }
 #endif
+
+#ifdef USE_LIBAVCODEC
+uint32_t alavc_find_tag(char *codec)
+{
+    if(codec == NULL)
+       return 0;
+
+    if(! strcasecmp(codec, "mp2"))
+       return 0x50;
+
+    if(! strcasecmp(codec, "ac3"))
+       return 0x2000;
+
+    return 0;
+}
+#endif
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20031102/c333f1f6/attachment.pgp>


More information about the MPlayer-dev-eng mailing list