]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libmp3lame.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / libmp3lame.c
index 3ac033f758c8f0caae8d13830de1d3955527b130..04498d2271572b4a2f503bcdad0862cd1befe71d 100644 (file)
@@ -2,20 +2,20 @@
  * Interface to libmp3lame for mp3 encoding
  * Copyright (c) 2002 Lennert Buytenhek <buytenh@gnu.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "mpegaudio.h"
 #include <lame/lame.h>
 
-#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4)
+#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4+1000) // FIXME: Buffer size to small? Adding 1000 to make up for it.
 typedef struct Mp3AudioContext {
     AVClass *class;
     lame_global_flags *gfp;
     int stereo;
     uint8_t buffer[BUFFER_SIZE];
     int buffer_index;
+    struct {
+        int *left;
+        int *right;
+    } s32_data;
     int reservoir;
 } Mp3AudioContext;
 
@@ -45,8 +49,11 @@ static av_cold int MP3lame_encode_init(AVCodecContext *avctx)
 {
     Mp3AudioContext *s = avctx->priv_data;
 
-    if (avctx->channels > 2)
-        return -1;
+    if (avctx->channels > 2) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Invalid number of channels %d, must be <= 2\n", avctx->channels);
+        return AVERROR(EINVAL);
+    }
 
     s->stereo = avctx->channels > 1 ? 1 : 0;
 
@@ -73,9 +80,27 @@ static av_cold int MP3lame_encode_init(AVCodecContext *avctx)
         goto err_close;
 
     avctx->frame_size             = lame_get_framesize(s->gfp);
-    avctx->coded_frame            = avcodec_alloc_frame();
+
+    if(!(avctx->coded_frame= avcodec_alloc_frame())) {
+        lame_close(s->gfp);
+
+        return AVERROR(ENOMEM);
+    }
     avctx->coded_frame->key_frame = 1;
 
+    if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt && s->stereo) {
+        int nelem = 2 * avctx->frame_size;
+
+        if(! (s->s32_data.left = av_malloc(nelem * sizeof(int)))) {
+            av_freep(&avctx->coded_frame);
+            lame_close(s->gfp);
+
+            return AVERROR(ENOMEM);
+        }
+
+        s->s32_data.right = s->s32_data.left + avctx->frame_size;
+    }
+
     return 0;
 
 err_close:
@@ -152,21 +177,63 @@ static int MP3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame,
 
     /* lame 3.91 dies on '1-channel interleaved' data */
 
-    if (data) {
+    if (!data){
+        lame_result= lame_encode_flush(
+                s->gfp,
+                s->buffer + s->buffer_index,
+                BUFFER_SIZE - s->buffer_index
+                );
+#if 2147483647 == INT_MAX
+    }else if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt){
         if (s->stereo) {
-            lame_result = lame_encode_buffer_interleaved(s->gfp, data,
-                                                         avctx->frame_size,
-                                                         s->buffer + s->buffer_index,
-                                                         BUFFER_SIZE - s->buffer_index);
+            int32_t *rp = data;
+            int32_t *mp = rp + 2*avctx->frame_size;
+            int *wpl = s->s32_data.left;
+            int *wpr = s->s32_data.right;
+
+            while (rp < mp) {
+                *wpl++ = *rp++;
+                *wpr++ = *rp++;
+            }
+
+            lame_result = lame_encode_buffer_int(
+                s->gfp,
+                s->s32_data.left,
+                s->s32_data.right,
+                avctx->frame_size,
+                s->buffer + s->buffer_index,
+                BUFFER_SIZE - s->buffer_index
+                );
         } else {
-            lame_result = lame_encode_buffer(s->gfp, data, data,
-                                             avctx->frame_size, s->buffer +
-                                             s->buffer_index, BUFFER_SIZE -
-                                             s->buffer_index);
+            lame_result = lame_encode_buffer_int(
+                s->gfp,
+                data,
+                data,
+                avctx->frame_size,
+                s->buffer + s->buffer_index,
+                BUFFER_SIZE - s->buffer_index
+                );
+        }
+#endif
+    }else{
+        if (s->stereo) {
+            lame_result = lame_encode_buffer_interleaved(
+                s->gfp,
+                data,
+                avctx->frame_size,
+                s->buffer + s->buffer_index,
+                BUFFER_SIZE - s->buffer_index
+                );
+        } else {
+            lame_result = lame_encode_buffer(
+                s->gfp,
+                data,
+                data,
+                avctx->frame_size,
+                s->buffer + s->buffer_index,
+                BUFFER_SIZE - s->buffer_index
+                );
         }
-    } else {
-        lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index,
-                                        BUFFER_SIZE - s->buffer_index);
     }
 
     if (lame_result < 0) {
@@ -205,6 +272,7 @@ static av_cold int MP3lame_encode_close(AVCodecContext *avctx)
 {
     Mp3AudioContext *s = avctx->priv_data;
 
+    av_freep(&s->s32_data.left);
     av_freep(&avctx->coded_frame);
 
     lame_close(s->gfp);
@@ -235,6 +303,9 @@ AVCodec ff_libmp3lame_encoder = {
     .close                 = MP3lame_encode_close,
     .capabilities          = CODEC_CAP_DELAY,
     .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
+#if 2147483647 == INT_MAX
+    AV_SAMPLE_FMT_S32,
+#endif
                                                              AV_SAMPLE_FMT_NONE },
     .supported_samplerates = sSampleRates,
     .long_name             = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),