Здравствуйте!!! пытаюсь разобраться с кодированием аудио с помощью 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;
}