LINUX.ORG.RU

libavcodec vorbis encoding


0

1

Здравствуйте!!! пытаюсь разобраться с кодированием аудио с помощью FFmpeg сделал тестовое приложение на основе http://ffmpeg.org/doxygen/trunk/decoding__encoding_8c_source.html Cигнал 440 Гц кодируется и пишется в контейнер. AAC, MP2, AC3 работает без проблем. НО категорически не хочет работать Vorbis т.е при стандартных параметрах AVCodecContext функция avcodec_encode_audio2() работает без ошибок и даже чего то возвращает, но эти данные оказываются поврежденными Никто не знает как правильно настроить кодекконтекст для Vorbis ??? может есть какие то специфичные параметры этого кодека

#include <conio.h>
extern "C" 
{
#include <libavcodec/avcodec.h>
}

static int select_sample_rate(AVCodec *codec)
{
    const int *p;
    int best_samplerate = 0;

    if (!codec->supported_samplerates)
        return 44100;

    p = codec->supported_samplerates;
    while (*p) {
        best_samplerate = FFMAX(*p, best_samplerate);
        p++;
    }
    return best_samplerate;
}

static int select_channel_layout(AVCodec *codec)
{
    const uint64_t *p;
    uint64_t best_ch_layout = 0;
    int best_nb_channells   = 0;

    if (!codec->channel_layouts)
        return AV_CH_LAYOUT_STEREO;

    p = codec->channel_layouts;
    while (*p) {
        int nb_channels = av_get_channel_layout_nb_channels(*p);

        if (nb_channels > best_nb_channells) {
            best_ch_layout    = *p;
            best_nb_channells = nb_channels;
        }
        p++;
    }
    return best_ch_layout;
}


static void audio_encode_example(const char *filename)
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    AVFrame *frame;
    AVPacket pkt;
    int i, j, k, ret, got_output;
    int buffer_size;
    FILE *f;
    uint16_t *samples;
    float t, tincr;

    printf("Encode audio file %s\n", filename);

    //codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
	codec = avcodec_find_encoder(AV_CODEC_ID_VORBIS);
	//codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
	//codec = avcodec_find_encoder(AV_CODEC_ID_AC3);
    if (!codec) {
        fprintf(stderr, "Codec not found\n");
        exit(1);
    }

    c = avcodec_alloc_context3(codec);

    c->bit_rate = 64000;
    c->sample_fmt = AV_SAMPLE_FMT_FLTP; 
    c->sample_rate    = 44100; //select_sample_rate(codec);
    c->channel_layout = select_channel_layout(codec);
    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);

    /* open it */
    if (avcodec_open2(c, codec, NULL) < 0) {
        fprintf(stderr, "Could not open codec\n");
        exit(1);
    }

    f = fopen(filename, "wb");
    if (!f) {
        fprintf(stderr, "Could not open %s\n", filename);
        exit(1);
    }

    frame = avcodec_alloc_frame();
    if (!frame) {
        fprintf(stderr, "Could not allocate audio frame\n");
        exit(1);
    }

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

    buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
                                             c->sample_fmt, 0);
    samples = (uint16_t*)av_malloc(buffer_size);
    if (!samples) {
        fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
                buffer_size);
        exit(1);
    }

    ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
                                   (const uint8_t*)samples, buffer_size, 0);
    if (ret < 0) {
        fprintf(stderr, "Could not setup audio frame\n");
        exit(1);
    }

    t = 0;
    tincr = 2 * M_PI * 440.0 / c->sample_rate;
    for(i=0;i<200;i++) {
        av_init_packet(&pkt);
        pkt.data = NULL; 
        pkt.size = 0;

        for (j = 0; j < c->frame_size; j++) {
            samples[2*j] = (int)(sin(t) * 10000);

            for (k = 1; k < c->channels; k++)
                samples[2*j + k] = samples[2*j];
            t += tincr;
        }

        ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
        if (ret < 0) {
            fprintf(stderr, "Error encoding audio frame\n");
            exit(1);
        }
        if (got_output) {
            fwrite(pkt.data, 1, pkt.size, f);
            av_free_packet(&pkt);
        }
    }

    for (got_output = 1; got_output; i++) {
        ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
        if (ret < 0) {
            fprintf(stderr, "Error encoding frame\n");
            exit(1);
        }

        if (got_output) {
            fwrite(pkt.data, 1, pkt.size, f);
            av_free_packet(&pkt);
        }
    }
    fclose(f);

    av_freep(&samples);
    av_freep(&frame);
    avcodec_close(c);
    av_free(c);
}

int main(int argc, char **argv)
{
    avcodec_register_all();

	audio_encode_example("test.ogg");

	printf("Encoding is completed...\n");
	getch();
    return 0;
}



Последнее исправление: alexanderR (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.