---
 libavcodec/libmp3lame.c |  105 +++++++++++++++++-----------------------------
 1 files changed, 39 insertions(+), 66 deletions(-)

diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index d754f46..b09b61c 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -33,6 +33,7 @@
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "audio_frame_queue.h"
+#include "dsputil.h"
 #include "internal.h"
 #include "mpegaudio.h"
 #include "mpegaudiodecheader.h"
@@ -46,8 +47,9 @@ typedef struct LAMEContext {
     uint8_t buffer[BUFFER_SIZE];
     int buffer_index;
     int reservoir;
-    void *planar_samples[2];
+    float *samples_flt[2];
     AudioFrameQueue afq;
+    DSPContext dsp;
 } LAMEContext;
 
 
@@ -58,8 +60,8 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx)
 #if FF_API_OLD_ENCODE_AUDIO
     av_freep(&avctx->coded_frame);
 #endif
-    av_freep(&s->planar_samples[0]);
-    av_freep(&s->planar_samples[1]);
+    av_freep(&s->samples_flt[0]);
+    av_freep(&s->samples_flt[1]);
 
     ff_af_queue_close(&s->afq);
 
@@ -126,93 +128,64 @@ static av_cold int mp3lame_encode_init(AVCodecContext 
*avctx)
     }
 #endif
 
-    /* sample format */
-    if (avctx->sample_fmt == AV_SAMPLE_FMT_S32 ||
-        avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
+    /* allocate float sample buffers */
+    if (avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
         int ch;
         for (ch = 0; ch < avctx->channels; ch++) {
-            s->planar_samples[ch] = av_malloc(avctx->frame_size *
-                                              
av_get_bytes_per_sample(avctx->sample_fmt));
-            if (!s->planar_samples[ch]) {
+            s->samples_flt[ch] = av_malloc(avctx->frame_size *
+                                           sizeof(*s->samples_flt[ch]));
+            if (!s->samples_flt[ch]) {
                 ret = AVERROR(ENOMEM);
                 goto error;
             }
         }
     }
 
+    ff_dsputil_init(&s->dsp, avctx);
+
     return 0;
 error:
     mp3lame_encode_close(avctx);
     return ret;
 }
 
-#define DEINTERLEAVE(type, scale) do {                  \
-    int ch, i;                                          \
-    for (ch = 0; ch < s->avctx->channels; ch++) {       \
-        const type *input = samples;                    \
-        type      *output = s->planar_samples[ch];      \
-        input += ch;                                    \
-        for (i = 0; i < nb_samples; i++) {              \
-            output[i] = *input * scale;                 \
-            input += s->avctx->channels;                \
-        }                                               \
-    }                                                   \
+#define ENCODE_BUFFER(suffix, buf_name) do {                                \
+    lame_result = lame_encode_ ## suffix(s->gfp,                            \
+                                         buf_name[0],                       \
+                                         buf_name[1],                       \
+                                         frame->nb_samples,                 \
+                                         s->buffer + s->buffer_index,       \
+                                         BUFFER_SIZE - s->buffer_index);    \
 } while (0)
 
-static int encode_frame_int16(LAMEContext *s, void *samples, int nb_samples)
-{
-    if (s->avctx->channels > 1) {
-        return lame_encode_buffer_interleaved(s->gfp, samples,
-                                              nb_samples,
-                                              s->buffer + s->buffer_index,
-                                              BUFFER_SIZE - s->buffer_index);
-    } else {
-        return lame_encode_buffer(s->gfp, samples, NULL, nb_samples,
-                                  s->buffer + s->buffer_index,
-                                  BUFFER_SIZE - s->buffer_index);
-    }
-}
-
-static int encode_frame_int32(LAMEContext *s, void *samples, int nb_samples)
-{
-    DEINTERLEAVE(int32_t, 1);
-
-    return lame_encode_buffer_int(s->gfp,
-                                  s->planar_samples[0], s->planar_samples[1],
-                                  nb_samples,
-                                  s->buffer + s->buffer_index,
-                                  BUFFER_SIZE - s->buffer_index);
-}
-
-static int encode_frame_float(LAMEContext *s, void *samples, int nb_samples)
-{
-    DEINTERLEAVE(float, 32768.0f);
-
-    return lame_encode_buffer_float(s->gfp,
-                                    s->planar_samples[0], s->planar_samples[1],
-                                    nb_samples,
-                                    s->buffer + s->buffer_index,
-                                    BUFFER_SIZE - s->buffer_index);
-}
-
 static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                                 const AVFrame *frame, int *got_packet_ptr)
 {
     LAMEContext *s = avctx->priv_data;
     MPADecodeHeader hdr;
-    int len, ret;
+    int len, ret, ch;
     int lame_result;
 
     if (frame) {
         switch (avctx->sample_fmt) {
-        case AV_SAMPLE_FMT_S16:
-            lame_result = encode_frame_int16(s, frame->data[0], 
frame->nb_samples);
+        case AV_SAMPLE_FMT_S16P:
+            ENCODE_BUFFER(buffer, (const int16_t *)frame->data);
             break;
-        case AV_SAMPLE_FMT_S32:
-            lame_result = encode_frame_int32(s, frame->data[0], 
frame->nb_samples);
+        case AV_SAMPLE_FMT_S32P:
+            ENCODE_BUFFER(buffer_int, (const int32_t *)frame->data);
             break;
-        case AV_SAMPLE_FMT_FLT:
-            lame_result = encode_frame_float(s, frame->data[0], 
frame->nb_samples);
+        case AV_SAMPLE_FMT_FLTP:
+            if (frame->linesize[0] < 4 * FFALIGN(frame->nb_samples, 8)) {
+                av_log(avctx, AV_LOG_ERROR, "inadequate AVFrame plane 
padding\n");
+                return AVERROR(EINVAL);
+            }
+            for (ch = 0; ch < avctx->channels; ch++) {
+                s->dsp.vector_fmul_scalar(s->samples_flt[ch],
+                                          (const float *)frame->data[ch],
+                                          32768.0f,
+                                          FFALIGN(frame->nb_samples, 8));
+            }
+            ENCODE_BUFFER(buffer_float, s->samples_flt);
             break;
         default:
             return AVERROR_BUG;
@@ -300,9 +273,9 @@ AVCodec ff_libmp3lame_encoder = {
     .encode2               = mp3lame_encode_frame,
     .close                 = mp3lame_encode_close,
     .capabilities          = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME,
-    .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32,
-                                                             AV_SAMPLE_FMT_FLT,
-                                                             AV_SAMPLE_FMT_S16,
+    .sample_fmts           = (const enum AVSampleFormat[]) { 
AV_SAMPLE_FMT_S32P,
+                                                             
AV_SAMPLE_FMT_FLTP,
+                                                             
AV_SAMPLE_FMT_S16P,
                                                              
AV_SAMPLE_FMT_NONE },
     .supported_samplerates = libmp3lame_sample_rates,
     .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
-- 
1.7.1

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to