Re: lavcac3enc broken?

Reimar Döffinger <[email protected]> Wed, 29 Mar 2023 19:38:38 +0200
Newsgroups gmane.comp.video.mplayer.devel
Message-ID <[email protected]>

> On 29 Mar 2023, at 12:51, Reimar Döffinger <[email protected]> wrote:
> 
>> 
>> On 27 Mar 2023, at 17:37, eatdirt <[email protected]> wrote:
>> 
>> Hi there,
>> I am a long term user of mplayer, and my "custom" usage is to reencode audio streams to ac3 to feed my "old" amplifier.
>> 
>> Since version 1.5, it seems that the audio chain having:
>> 
>> -af lavcac3enc 1:x:y
>> 
>> is broken as soon as the stream is not ac3 (it used to work with any stream pre-version 1.5).
>> 
>> Here the errors popping out, for instance from an eac3 audio channel:
>> 
>> [ac3_fixed @ 0x7f72fd553760]Specified sample format s16p is invalid or not supported
> 
> Seems there was a FFmpeg change making the ac3 encoder only support 32-bit input.
> So the lavcac3enc code would need to be changed to take that instead of 16-bit inputs.
> It should not be hard, but might take a bit of time to do.

Unfortunately I can't test it, but I have a patch attached...

_______________________________________________
MPlayer-dev-eng mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
ac3enc.diff (application/octet-stream, 3.6 KB)
Index: libaf/af_lavcac3enc.c
===================================================================
--- libaf/af_lavcac3enc.c	(revision 38410)
+++ libaf/af_lavcac3enc.c	(working copy)
@@ -48,7 +48,7 @@

 // Data for specific instances of this filter
 typedef struct af_ac3enc_s {
-    struct AVCodec        *lavc_acodec;
+    const struct AVCodec  *lavc_acodec;
     struct AVCodecContext *lavc_actx;
     int add_iec61937_header;
     int bit_rate;
@@ -66,6 +66,15 @@
     int i, bit_rate, test_output_res;
     static const int default_bit_rate[AC3_MAX_CHANNELS+1] = \
         {0, 96000, 192000, 256000, 384000, 448000, 448000};
+    static const AVChannelLayout layouts[AC3_MAX_CHANNELS+1] = {
+        AV_CHANNEL_LAYOUT_MONO,
+        AV_CHANNEL_LAYOUT_MONO,
+        AV_CHANNEL_LAYOUT_STEREO,
+        AV_CHANNEL_LAYOUT_SURROUND,
+        AV_CHANNEL_LAYOUT_QUAD,
+        AV_CHANNEL_LAYOUT_5POINT0,
+        AV_CHANNEL_LAYOUT_5POINT1
+    };

     switch (cmd){
     case AF_CONTROL_REINIT:
@@ -72,8 +81,19 @@
         if (AF_FORMAT_IS_AC3(data->format) || data->nch < s->min_channel_num)
             return AF_DETACH;

+        // set up input format
+        af->data->format = AF_FORMAT_S32_NE;
+        if (data->rate == 48000 || data->rate == 44100 || data->rate == 32000)
+            af->data->rate = data->rate;
+        else
+            af->data->rate = 48000;
+        if (data->nch > AC3_MAX_CHANNELS)
+            af->data->nch = AC3_MAX_CHANNELS;
+        else
+            af->data->nch = data->nch;
+        af->data->bps = 4;
         s->pending_len = 0;
-        s->expect_len = AC3_FRAME_SIZE * data->nch * data->bps;
+        s->expect_len = AC3_FRAME_SIZE * af->data->nch * af->data->bps;
         if (s->add_iec61937_header)
             af->mul = (double)AC3_FRAME_SIZE * 2 * 2 / s->expect_len;
         else
@@ -82,21 +102,11 @@
         mp_msg(MSGT_AFILTER, MSGL_DBG2, "af_lavcac3enc reinit: %d, %d, %f, %d.\n",
                data->nch, data->rate, af->mul, s->expect_len);

-        af->data->format = AF_FORMAT_S16_NE;
-        if (data->rate == 48000 || data->rate == 44100 || data->rate == 32000)
-            af->data->rate = data->rate;
-        else
-            af->data->rate = 48000;
-        if (data->nch > AC3_MAX_CHANNELS)
-            af->data->nch = AC3_MAX_CHANNELS;
-        else
-            af->data->nch = data->nch;
-        af->data->bps = 2;
         test_output_res = af_test_output(af, data);

         bit_rate = s->bit_rate ? s->bit_rate : default_bit_rate[af->data->nch];

-        if (s->lavc_actx->channels != af->data->nch ||
+        if (s->lavc_actx->ch_layout.nb_channels != af->data->nch ||
                 s->lavc_actx->sample_rate != af->data->rate ||
                 s->lavc_actx->bit_rate != bit_rate) {

@@ -104,9 +114,9 @@
                 avcodec_close(s->lavc_actx);

             // Put sample parameters
-            s->lavc_actx->channels = af->data->nch;
+            s->lavc_actx->ch_layout = layouts[af->data->nch];
             s->lavc_actx->sample_rate = af->data->rate;
-            s->lavc_actx->sample_fmt  = AV_SAMPLE_FMT_S16P;
+            s->lavc_actx->sample_fmt  = AV_SAMPLE_FMT_S32P;
             s->lavc_actx->bit_rate = bit_rate;

             if(avcodec_open2(s->lavc_actx, s->lavc_acodec, NULL) < 0) {
@@ -114,8 +124,10 @@
                 return AF_ERROR;
             }
         }
+        // set output format
         af->data->format = AF_FORMAT_AC3_BE;
         af->data->nch = 2;
+        af->data->bps = 2;
         return test_output_res;
     case AF_CONTROL_COMMAND_LINE:
         mp_msg(MSGT_AFILTER, MSGL_DBG2, "af_lavcac3enc cmdline: %s.\n", (char*)arg);