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

Nico nsabbi at libero.it
Sun Nov 2 08:40:53 CET 2003


Good :)
but there are 2 problems with your patch:
-  A/V sync is immediately lost in the case of ac3; I can see that it's 
due to this code:

    if (alavc_ctx->block_align)
        mux_a->wf->nBlockAlign = alavc_ctx->block_align;
    else
        mux_a->wf->nBlockAlign = alavc_ctx->frame_size;

in both cases (ac3 and mp2) alavc_ctx->block_align is 0, so 
mux_a->wf->nBlockAlign ens up being 1152 for mp2 and
1536 for ac3; mp2 is in sync and ac3 not.

How can we solve it?

2) there's this assignment that I don't understand:

mux_a->wf->wBitsPerSample = 0;

shouldn't it be 16?

Thanks,
    Nico

Tobias Diedrich wrote:

>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.
>
>  
>
>------------------------------------------------------------------------
>
>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
>+
>  
>
>------------------------------------------------------------------------
>
>_______________________________________________
>MPlayer-dev-eng mailing list
>MPlayer-dev-eng at mplayerhq.hu
>http://mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
>  
>




More information about the MPlayer-dev-eng mailing list