[Libav-user] Problem encoding audio to ogg/vorbis

hipersayan x hipersayan.x at gmail.com
Thu Jun 9 03:21:27 CEST 2011


2011/6/6, hipersayan x <hipersayan.x at gmail.com>:
> information of the Environment:
>
> Operating system: Arch Linux
> ffmpeg version: 20110330
>
> I'm trying to encode audio to ogg/vorbis format, in the
> output-example.c file, if I set the output name to video.ogv, the
> audio is encoded in flac by default.
> Then I tried putting the line:
>
> fmt->audio_codec = CODEC_ID_VORBIS;
>
> After the line:
>
> fmt = av_guess_format(NULL, filename, NULL);
>
> When I compile and run the example, it return the error:
>
> output-example: libavutil/mathematics.c:79: av_rescale_rnd: Assertion
> `c > 0' failed.
>
> Also, if I set the output name to video.webm, it uses libvorbis by
> default, returns the same error.
> My question is, do I need to set another parameter to encode the audio
> stream as vorbis?
> Thanks in advance.
>

Hi again, this is the first time Im use libav, and need some help,
here is the sample code that Im testing:

/*
 * Compile this example with:
 *
 * gcc -lavformat -o oggvorbisenc oggvorbisenc.c
 */

#include <libavformat/avformat.h>

/* The test only fails when I try to use vorbis encoding, Why? */
#define VORBIS_TEST

/* Another tests will not fail */
/*#define FLAC_TEST*/
/*#define MP3_TEST*/

#define CHANNEL_COUNT 2
#define SAMPLE_SIZE 16   /* 2 bytes for each sample */
#define SAMPLE_RATE 8000
#define N_SAMPLES 100    /* Number of samples to output */

#ifdef MP3_TEST
    #define OUTPUT_FILENAME "output.mp3"
#else
    #define OUTPUT_FILENAME "output.ogg"
#endif

int main()
{
    AVFormatContext *oc;
    AVStream *audio_st;
    AVOutputFormat *fmt;
    int audio_outbuf_size;
    int audio_sample_size;
    uint8_t *audio_outbuf;
    short int *samples;
    unsigned int i;
    AVPacket pkt;
    int frame;
    int channel;
    int sample;
    short int A;

    av_register_all();

    fmt = av_guess_format(NULL, OUTPUT_FILENAME, NULL);

#ifdef VORBIS_TEST
    /* Set the audio codec as vorbis, Is this correct? */
    fmt->audio_codec = CODEC_ID_VORBIS;
#endif

    oc = avformat_alloc_context();
    oc->oformat = fmt;

    snprintf(oc->filename, sizeof(oc->filename), "%s", OUTPUT_FILENAME);

    audio_st = av_new_stream(oc, 1);

    /* Set the output parameters, Are these parameters correct? */
    audio_st->codec->codec_id = fmt->audio_codec;
    audio_st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    audio_st->codec->sample_fmt = AV_SAMPLE_FMT_S16;
    audio_st->codec->bit_rate = CHANNEL_COUNT * SAMPLE_SIZE * SAMPLE_RATE;
    audio_st->codec->sample_rate = SAMPLE_RATE;
    audio_st->codec->channels = CHANNEL_COUNT;

    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
        audio_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;

    av_set_parameters(oc, NULL);
    av_dump_format(oc, 0, OUTPUT_FILENAME, 1);

    /* In avcodec_open returns -1 and show this error:
     *
     * [libvorbis @ 0xcd6940] oggvorbis_encode_init: init_encoder failed
     *
     * Why? What's wrong?
     */
    avcodec_open(audio_st->codec,
avcodec_find_encoder(audio_st->codec->codec_id));

    audio_outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    audio_outbuf = (uint8_t *)av_malloc(audio_outbuf_size);

    audio_sample_size = 2 * audio_st->codec->frame_size *
audio_st->codec->channels;
    samples = (short int *)av_malloc(audio_sample_size);

    if (!(fmt->flags & AVFMT_NOFILE))
        avio_open(&oc->pb, OUTPUT_FILENAME, URL_WRONLY);

    av_write_header(oc);

    for (sample = 0; sample < N_SAMPLES; sample++)
    {
        /* Create some test noise */
        for (frame = 0; frame < audio_st->codec->frame_size; frame++)
        {
            A = 0x7FFF * sin(5 * 2 * M_PI * (float)frame / (float)N_SAMPLES);

            for (channel = 0; channel < audio_st->codec->channels; channel++)
                samples[2 * frame + channel] = A;
        }

        av_init_packet(&pkt);

        pkt.size = avcodec_encode_audio(audio_st->codec, audio_outbuf,
audio_outbuf_size, samples);

        if (audio_st->codec->coded_frame &&
audio_st->codec->coded_frame->pts != (unsigned int)AV_NOPTS_VALUE)
            pkt.pts = av_rescale_q(audio_st->codec->coded_frame->pts,
audio_st->codec->time_base, audio_st->time_base);

        pkt.flags |= AV_PKT_FLAG_KEY;
        pkt.stream_index = audio_st->index;
        pkt.data = audio_outbuf;

        av_interleaved_write_frame(oc, &pkt);
    }

    av_write_trailer(oc);

    if (audio_st)
    {
        avcodec_close(audio_st->codec);
        av_free(audio_outbuf);
        av_free(samples);
    }

    for (i = 0; i < oc->nb_streams; i++)
    {
        av_freep(&oc->streams[i]->codec);
        av_freep(&oc->streams[i]);
    }

    if (!(fmt->flags & AVFMT_NOFILE))
        avio_close(oc->pb);

    av_free(oc);

    return 0;
}


More information about the Libav-user mailing list