the following code (adapted from resampling_audio.c written by Stefano Sabatini and included in ffmpeg doc/examples) is able do resample fltp to AV_SAMPLE_FMT_S16 but fails to downmix 5.1 to stereo. I've tried several solutions without hope. The routine takes a buffer decoded with av_decode_audio4 and after resampling sends it to an output buffer. Can someone have a look at this code and spot where the mistake is?
Luigi

int32_t LG_ffmpeg_Audio_decoder::ResampleAudio( AVFrame *dec_fr )
{
int64_t src_ch_layout = dec_fr->channel_layout, dst_ch_layout = AV_CH_LAYOUT_STEREO;

    int32_t src_rate = dec_fr->sample_rate, dst_rate = 48000;

    uint8_t **src_data = dec_fr->data;

    int32_t dst_nb_channels = 0;

    int32_t dst_linesize;

int32_t src_nb_samples = dec_fr->nb_samples, dst_nb_samples, max_dst_nb_samples;

    enum AVSampleFormat src_sample_fmt = (AVSampleFormat)dec_fr->format;

    enum AVSampleFormat dst_sample_fmt = AV_SAMPLE_FMT_S16;

    int32_t dst_bufsize;

    const char *fmt;

    struct SwrContext *swr_ctx;

    int32_t ret;

    /* create resampler context */
    swr_ctx = swr_alloc();
    if (!swr_ctx)
    {
        fprintf(stderr, "Could not allocate resampler context\n");
        ret = AVERROR(ENOMEM);
        goto end;
    }

    /* set options */
    av_opt_set_int(swr_ctx, "in_channel_layout",    src_ch_layout, 0);
    av_opt_set_int(swr_ctx, "in_sample_rate",       src_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);

    av_opt_set_int(swr_ctx, "out_channel_layout",    dst_ch_layout, 0);
    av_opt_set_int(swr_ctx, "out_sample_rate",       dst_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);

    /* initialize the resampling context */
    if ((ret = swr_init(swr_ctx)) < 0)
    {
        fprintf(stderr, "Failed to initialize the resampling context\n");
        goto end;
    }

    /* compute the number of converted samples: buffering is avoided
    * ensuring that the output buffer will contain at least all the
    * converted input samples */
max_dst_nb_samples = dst_nb_samples = av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);

/* buffer is going to be directly written to a rawaudio file, no alignment */
    dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);

ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels, dst_nb_samples, dst_sample_fmt, 0);

    if (ret < 0)
    {
        fprintf(stderr, "Could not allocate destination samples\n");
        goto end;
    }

    /* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) + src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);

    if (dst_nb_samples > max_dst_nb_samples)
    {
        av_free(dst_data[0]);
ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels, dst_nb_samples, dst_sample_fmt, 1);
        if (ret < 0)
              exit(0);// break;

        max_dst_nb_samples = dst_nb_samples;
     }

     /* convert to destination format */
ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)src_data, src_nb_samples);

     if (ret < 0)
     {
        fprintf(stderr, "Error while converting\n");
        goto end;
     }

dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels, ret, dst_sample_fmt, 1);
    //    printf("t:%f in:%d out:%d\n", t, src_nb_samples, ret);

InsertBufferInOutBuf((unsigned char *)dst_data[0], dst_bufsize ) ;

     if ((ret = GetFormatFromSampleFmt(&fmt, dst_sample_fmt)) < 0)
        goto end;
// fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n"
//        "ffplay -f %s -channel_layout % -channels %d -ar %d %s\n",
//        fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);

      goto end;

    end:

    if (dst_data)
        av_freep(&dst_data[0]);
    av_freep(&dst_data);

    swr_free(&swr_ctx);

    return ret < 0;
}

_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to