Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37777468
en ru br
Репозитории ALT
S:3.100-alt1
5.1: 3.98.2-alt2
4.1: 3.97-alt1.0
4.0: 3.97-alt1.0
3.0: 3.96.1-alt1.1
www.altlinux.org/Changes

Группа :: Звук
Пакет: lame

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: lame-3.98-alt-ffmpeg_fix.patch
Скачать


Cumulative patch to fix ffmpeg incomatibility in lame_encode_flush()
(for details see FFMPEG bug 803: https://roundup.ffmpeg.org/roundup/ffmpeg/issue803, 
 LAME bug 2553863: http://sourceforge.net/tracker/?func=detail&aid=2553863&group_id=290&atid=100290)
Revision 1.323.2.7 (Mon Mar 30 19:48:00 2009 UTC  by robert)
 ensure we padd at least 288 samples
Revision 1.323.2.6 (Sun Mar 29 14:43:22 2009 UTC   by robert)
 workaround for FFMPEG bug, which uses to call lame_encode_flush more than once in loop
Revision 1.323.2.5 (Sat Mar 28 22:09:45 2009 UTC   by robert)
 avoid extra frame at end
Revision 1.323.2.4 (Sun Jan 18 15:44:27 2009 UTC   by robert)
 replacing C++ style comments by C style comments
--- ./libmp3lame/lame.c	2009-07-28 19:52:17 +0400
+++ ./libmp3lame/lame.c	2009-03-30 23:48:00 +0400
@@ -1472,6 +1476,27 @@
 }
 
 
+static int
+calcNeeded(lame_global_flags* gfp)
+{
+    int mf_needed;
+    /* some sanity checks */
+#if ENCDELAY < MDCTDELAY
+# error ENCDELAY is less than MDCTDELAY, see encoder.h
+#endif
+#if FFTOFFSET > BLKSIZE
+# error FFTOFFSET is greater than BLKSIZE, see encoder.h
+#endif
+
+    mf_needed = BLKSIZE + gfp->framesize - FFTOFFSET; /* amount needed for FFT */
+    /*mf_needed = Max(mf_needed, 286 + 576 * (1 + gfc->mode_gr)); */
+    mf_needed = Max(mf_needed, 512 + gfp->framesize - 32);
+
+    assert(MFSIZE >= mf_needed);
+    
+    return mf_needed;
+}
+
 /*
  * THE MAIN LAME ENCODING INTERFACE
  * mt 3/00
@@ -1555,20 +1580,7 @@
         }
     }
 
-
-    /* some sanity checks */
-#if ENCDELAY < MDCTDELAY
-# error ENCDELAY is less than MDCTDELAY, see encoder.h
-#endif
-#if FFTOFFSET > BLKSIZE
-# error FFTOFFSET is greater than BLKSIZE, see encoder.h
-#endif
-
-    mf_needed = BLKSIZE + gfp->framesize - FFTOFFSET; /* amount needed for FFT */
-    /*mf_needed = Max(mf_needed, 286 + 576 * (1 + gfc->mode_gr)); */
-    mf_needed = Max(mf_needed, 512 + gfp->framesize - 32);
-
-    assert(MFSIZE >= mf_needed);
+    mf_needed = calcNeeded(gfp);
 
     mfbuf[0] = gfc->mfbuf[0];
     mfbuf[1] = gfc->mfbuf[1];
@@ -1602,6 +1614,13 @@
         /* update mfbuf[] counters */
         gfc->mf_size += n_out;
         assert(gfc->mf_size <= MFSIZE);
+
+        /* lame_encode_flush may have set gfc->mf_sample_to_encode to 0
+         * so we have to reinitialize it here when that happened.
+         */
+        if (gfc->mf_samples_to_encode < 1) {
+            gfc->mf_samples_to_encode = ENCDELAY + POSTDELAY;
+        }
         gfc->mf_samples_to_encode += n_out;
 
 
@@ -1926,24 +1945,36 @@
 
     /* we always add POSTDELAY=288 padding to make sure granule with real
      * data can be complety decoded (because of 50% overlap with next granule */
-    int     end_padding = POSTDELAY;
-    int     pad_out_samples;
+    int     end_padding;
     int     frames_left;
-    int     samples_to_encode = gfc->mf_samples_to_encode;
+    int     samples_to_encode = gfc->mf_samples_to_encode - POSTDELAY+288;
+    int     mf_needed = calcNeeded(gfp);
 
+    /* Was flush already called? */
+    if (gfc->mf_samples_to_encode < 1) {
+        return 0;
+    }
     memset(buffer, 0, sizeof(buffer));
     mp3count = 0;
-    
+
     if (gfp->in_samplerate != gfp->out_samplerate) {
         /* delay due to resampling; needs to be fixed, if resampling code gets changed */
         samples_to_encode += 16.*gfp->out_samplerate/gfp->in_samplerate;
     }
-    pad_out_samples = gfp->framesize - (samples_to_encode % gfp->framesize);
-    end_padding += pad_out_samples;
+    end_padding = gfp->framesize - (samples_to_encode % gfp->framesize);
+    gfp->encoder_padding = end_padding;
 
-    frames_left = (samples_to_encode + pad_out_samples) / gfp->framesize;
-    while (frames_left > 0) {
+    frames_left = (samples_to_encode + end_padding) / gfp->framesize;
+
+    /* send in a frame of 0 padding until all internal sample buffers are flushed */
+    while (frames_left > 0 && imp3 >= 0) {
+        int bunch = mf_needed-gfc->mf_size;
         int frame_num = gfp->frameNum;
+        
+        bunch *= gfp->in_samplerate;
+        bunch /= gfp->out_samplerate;
+        if (bunch > 1152) bunch = 1152;
+        if (bunch < 1) bunch = 1;
 
         mp3buffer_size_remaining = mp3buffer_size - mp3count;
 
@@ -1951,22 +1982,23 @@
         if (mp3buffer_size == 0)
             mp3buffer_size_remaining = 0;
 
-        /* send in a frame of 0 padding until all internal sample buffers
-         * are flushed
-         */
-        imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], 32,
+        imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], bunch,
                                   mp3buffer, mp3buffer_size_remaining);
         
-        if (frame_num != gfp->frameNum) {
-            --frames_left;
-        }
-        if (imp3 < 0) {
-            /* some type of fatal error */
-            return imp3;
-        }
         mp3buffer += imp3;
         mp3count += imp3;
+        frames_left -= (frame_num != gfp->frameNum) ? 1 : 0;
     }
+    /* Set gfc->mf_samples_to_encode to 0, so we may detect
+     * and break loops calling it more than once in a row.
+     */
+    gfc->mf_samples_to_encode = 0;
+
+    if (imp3 < 0) {
+        /* some type of fatal error */
+        return imp3;
+    }
+
     mp3buffer_size_remaining = mp3buffer_size - mp3count;
     /* if user specifed buffer size = 0, dont check size */
     if (mp3buffer_size == 0)
@@ -1997,7 +2029,6 @@
         }
         mp3count += imp3;
     }
-    gfp->encoder_padding = end_padding;
 #if 0
     {
         int const ed = gfp->encoder_delay;
@@ -2011,6 +2042,8 @@
         MSGF(gfc, "encoder padding=%d\n", ep);
         MSGF(gfc, "sample count=%d (%g)\n", ns, gfp->in_samplerate*duration);
         MSGF(gfc, "duration=%g sec\n", duration);
+        MSGF(gfc, "mf_size=%d\n",gfc->mf_size);
+        MSGF(gfc, "mf_samples_to_encode=%d\n",gfc->mf_samples_to_encode);
     }
 #endif
     return mp3count;
@@ -2052,7 +2085,12 @@
 /* flush internal mp3 buffers, and free internal buffers         */
 /*****************************************************************/
 #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+/* OBSOLETE */
+int CDECL
+lame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size);
 #else
+#endif
+
 int
 lame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)
 {
@@ -2062,7 +2100,6 @@
 
     return ret;
 }
-#endif
 
 /*****************************************************************/
 /* write VBR Xing header, and ID3 version 1 tag, if asked for    */
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin