[Libav-user] Encoding an AVFrame with MP3 Encoder over libav

Dr. Sven Alisch svenali at t-online.de
Mon Oct 3 02:07:24 EEST 2022


Dear developers,

My original material is a PCM stream (WAV) which I want to encode to MP3. I reformat it with swr_convert from AV_SAMPLE_FMT_S16 to AV_SAMPLE_FMT_FLTP and copy it to a AVFifo, because the frame sizes are different. In my encoding Function I read out my samples from that Fifo and want to send it to the encoder. I use a similar code like the code from tanscode_aac.c. It seems to work fine, but I can not read from Fifo and store the data in to output_frame->data. My program crashes. If I use a self created structure (a buffer I prepared of my own), than it works.
Also strange for me is, that the linesize-parameter after the av_frame_get_buffer(output_frame, 0); is always for linesize[0] set. Why? I thought, that the FLTP (Planar) mode creates a line size for each channel?

Here my code:

    AVFrame *output_frame = av_frame_alloc();
    if (!output_frame)
    {
        cerr << "Could not allocate output frame" << endl;
        return;
    }
    const int frame_size = FFMIN(av_audio_fifo_size(_AVFifo), _CodecContext->frame_size);
    output_frame->nb_samples = frame_size;
    output_frame->format = _CodecContext->sample_fmt;
    output_frame->sample_rate = _CodecContext->sample_rate;
    output_frame->channel_layout = _CodecContext->channel_layout;

    error = av_frame_get_buffer(output_frame, 0);
    if (error < 0)
    {
        cerr << "Could not allocate output frame samples: " << av_err2str(error) << endl;
        av_frame_free(&output_frame);
        return;
    }

    AVPacket *output_packet = av_packet_alloc();
    if (!output_packet)
    {
        cerr << "could not allocate the packet!" << endl;
        return;
    }

    int ret = av_audio_fifo_read(_AVFifo, (void **)output_frame->data, frame_size);  <- Here it crashes
    if (ret < frame_size)
    {
        cerr << "Could not read data from FIFO" << endl;
        av_frame_free(&output_frame);
        return;
    }
    cout << ret * sizeof(float) << " readed Bytes from AV Fifo." << endl;

    output_frame->pts = _pts;
    _pts += output_frame->nb_samples;

    ret = avcodec_send_frame(_CodecContext, output_frame);
    if (ret < 0)
    {
        cerr << "Error sending the frame to the encoder! Answer: " << ret << endl;
    }

    while (ret >= 0)
    {
        ret = avcodec_receive_packet(_CodecContext, output_packet);

        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
        {
            cerr << "Error encoding audio frame ... need more DATA ..." << endl;
            return;
        }
        else if (ret < 0)
        {
            cerr << "Error encoding audio frame!" << endl;
            return;
        }

        fwrite(output_packet->data, 1, output_packet->size, f);

        av_packet_unref(output_packet);

Thank you for help!

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/20221003/a8d87522/attachment.sig>


More information about the Libav-user mailing list