[FFmpeg-user] Rescaling audio samples

JULIAN GARDNER joolzg at btinternet.com
Fri Mar 27 23:46:24 CET 2015


Im hoping someone can help me here as I am stuck when trying to resample audio from rate to another rate, this is my own code and not withing ffmpeg's code, using ffmpeg libs

LONG MESSAGE WITH CODE

output Stream Information:
Output #0, mpegts, to 'a0.ts':
    Stream #0:0: Video: h264 (libx264), yuv420p, 720x576, q=-1--1, 1300 kb/s, 25 tbn, 25 tbc
    Stream #0:1: Audio: aac (libfaac), 48000 Hz, stereo, s16, 64 kb/s

Input Stream Information
Input #0, mpegts, from 'udp://225.176.5.178:50206?reuse&fifo_size=50000':
  Duration: N/A, start: 62947.782956, bitrate: N/A
  Program 1 
    Metadata:
      service_name    : 1458
    Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p, 720x288 [SAR 32:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 32000 Hz, stereo, fltp, 73 kb/s

My Conversion Code
static int write_audio_frame(AVFormatContext *out_context, OutputStream *out_stream)
{
    inputStream *inputSource = inputs[0];
    AVCodecContext *c;
    AVPacket pkt = { 0 }; // data and size must be 0;
    AVFrame *frame = NULL;
    avPackets *here;
    int ret;
    int l;
    int got_packet = 0;

        av_init_packet(&pkt);
        c = out_stream->st->codec;

        // Get next available packet
        here = inputSource->packets_list[AUDIO_INDEX];
        if( here) {
        int dst_nb_samples;

            frame = here->frame;
            frame->pts = out_stream->next_pts;
            out_stream->next_pts += frame->nb_samples;

            /* convert samples from native format to destination codec format, using the resampler */
                /* compute destination number of samples */
            dst_nb_samples = av_rescale_rnd(swr_get_delay(inputSource->audio_swr_ctx, inputSource->audio_dec_ctx->sample_rate) + frame->nb_samples,
                                            c->sample_rate, inputSource->audio_dec_ctx->sample_rate, AV_ROUND_UP);


            // If i have this assert in it triggers all the time, but as my input is 32000 and my output is 48000 i would expect them to be different
            //av_assert0(dst_nb_samples == frame->nb_samples);

            // This gives "rescale_rnd 1024 to 1560"
            printf( "rescale_rnd %d to %d\r\n", frame->nb_samples, dst_nb_samples);

                // Reallocate the buffer if the size is biggert
                if( dst_nb_samples>out_stream->audio_frame_size) {
                    av_frame_free(&ost->audio_frame);
                    out_stream->audio_frame = alloc_audio_frame(c->sample_fmt, c->channel_layout, c->sample_rate, dst_nb_samples);
                    out_stream->audio_frame_size = dst_nb_samples;
                }

            /* when we pass a frame to the encoder, it may keep a reference to it
             * internally;
             * make sure we do not overwrite it here
             */
            ret = av_frame_make_writable(out_stream->audio_frame);
            if (ret < 0)
                exit(1);

            /* convert to destination format */
            ret = swr_convert(inputSource->audio_swr_ctx,
                              out_stream->audio_frame->data, dst_nb_samples,
                              (const uint8_t **)frame->data, frame->nb_samples);
            if (ret < 0) {
                fprintf(stderr, "Error while converting\n");
                exit(1);
            }
            out_stream->audio_frame->pts = av_rescale_q(out_stream->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
            out_stream->samples_count   += dst_nb_samples;

        // HERE IS THE FAILING CALL
            ret = avcodec_encode_audio2(c, &pkt, out_stream->audio_frame, &got_packet);
            if (ret < 0) {
                fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
                exit(1);
            }

            if (got_packet) {
                ret = write_frame(out_context, &c->time_base, out_stream->st, &pkt);
                if (ret < 0) {
                    fprintf(stderr, "Error while writing audio frame: %s\n",
                            av_err2str(ret));
                    exit(1);
                }
            }
            inputSource->packets_list[AUDIO_INDEX] = here->next;
            av_frame_free(&here->frame);
            free( here);
        }
    }

    return 0; //(frame || got_packet) ? 0 : 1;
}

//
Allocating the output audio buffer
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
                                  uint64_t channel_layout,
                                  int sample_rate, int nb_samples)
{
    AVFrame *frame = av_frame_alloc();
    int ret;

    if (!frame) {
        fprintf(stderr, "Error allocating an audio frame\n");
        exit(1);
    }

    // This code give "Allocating 1 3 48000 1024"
    printf( "Allocating %d %d %d %d\n", sample_fmt, channel_layout, sample_rate, nb_samples);

    frame->format = sample_fmt;
    frame->channel_layout = channel_layout;
    frame->sample_rate = sample_rate;
    frame->nb_samples = nb_samples;

    if (nb_samples) {
        ret = av_frame_get_buffer(frame, 16);
        if (ret < 0) {
            fprintf(stderr, "Error allocating an audio buffer\n");
            exit(1);
        }
    }

    return frame;
}


After running my code i get this crash

rescale_rnd 1024 to 1536
[libfaac @ 0x7fb5500021a0] more samples than frame size (avcodec_encode_audio2)

Can anyone shed some light on why after converting from 1024 to 1536 samples the system crashes ithe the above error.

joolz


More information about the ffmpeg-user mailing list