[Libav-user] Problems with encoding raw PCM in mp3

Dr. Sven Alisch svenali at t-online.de
Mon Sep 26 14:29:42 EEST 2022


Hello everybody,

I am a little confused with from the encoding result in my app. I hear the sound only in the left speaker with a low quality if I play the file with a MP3 player (VLC). I do not find my mistake. Please help me.

I have a PCM stream with a SampleRate of 44100 Hz and a sample size of 4096 Bytes. The samples are stored in a Buffer. Sample Format is AV_SAMPLE_FMT_S16. Here is my code:

<snip>
    _Codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
    if (!_Codec)
    { ...    }

    _CodecContext = avcodec_alloc_context3(_Codec);
    _CodecContext->bit_rate = 192000;
    _CodecContext->sample_fmt = AV_SAMPLE_FMT_FLTP;
    _CodecContext->sample_rate    = audioSampleRate;
    _CodecContext->channel_layout = AV_CH_LAYOUT_STEREO;
    _CodecContext->channels       = 2;  // Stereo

    /* open it */
    if (avcodec_open2(_CodecContext, _Codec, NULL) < 0)
    { …  }

   /* AVFrames for the encoder */
    AVFrame *frame = av_frame_alloc();
    if (!frame)
    { … }

    frame->nb_samples     = _CodecContext->frame_size;
    frame->format         = _CodecContext->sample_fmt;
    frame->channel_layout = _CodecContext->channel_layout;

    /* allocate the data buffers */
    int ret = av_frame_get_buffer(frame, 0);
    if (ret < 0)
    {… }

   /* AVFrames for the original input */
    AVFrame *input_frame = av_frame_alloc();
    if (!input_frame)
    { ...    }

    input_frame->nb_samples     = 4096;
    input_frame->format         = AV_SAMPLE_FMT_S16;
    input_frame->channel_layout = 2;

    /* allocate the data buffers */
    ret = av_frame_get_buffer(input_frame, 0);
    if (ret < 0)
    { …}

    /* packet for holding encoded output */
    AVPacket *pkt = av_packet_alloc();
    if (!pkt)
    {...}

    int data_size = 0;
    uint8_t *data_uint8 = (uint8_t*) av_malloc (AUDIO_INBUF_SIZE * 20 + AV_INPUT_BUFFER_PADDING_SIZE);
    uint8_t *conv_data = (uint8_t*) av_malloc (AUDIO_INBUF_SIZE * 20 + AV_INPUT_BUFFER_PADDING_SIZE);

   FILE *f = fopen("ali-test.mp3", "wb");
    if (!f) {... }

    SwrContext *swr = NULL;
    if (!swr)
    {
        swr = swr_alloc_set_opts(NULL,
            AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT,   // output
            AV_SAMPLE_FMT_FLTP,                     // output
            audioSampleRate,                        // output
            AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT,   // input
            AV_SAMPLE_FMT_S16,                      // input
            audioSampleRate,                        // input
            0,
            NULL);
        int swrInit = swr_init(swr);
        if (swrInit < 0)
        {
            cerr << "swr init error swrInit " << swrInit << endl;
            return;
        }
    }

    while (_running)
    {
        int32_t size = _streamBuffer.GetRingBufferReadAvailable();

        if (size > 0)
        {
            data_size = _streamBuffer.getDataFromBuffer(data_uint8, size);
            int samples = data_size / 4096;

            for (int i = 0; i < samples; i++)
            {
                input_frame->data[0] = &data_uint8[i * input_frame->nb_samples];

                ret = swr_convert(swr, &conv_data, input_frame->nb_samples, (const uint8_t**) &input_frame->data[0], input_frame->nb_samples);

                if (ret > 0)
                {
                    frame->data[0] = conv_data;

                    encodeFrame(_CodecContext, frame, pkt, f);
                }
            }
        }
        else
        {
            cerr << "Wait for INPUT to encode ..." << endl;
            this_thread::sleep_for(chrono::seconds(3));
        }

Regards,
Sven
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: Message signed with OpenPGP
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20220926/5fa151ee/attachment.sig>


More information about the Libav-user mailing list