static int setup_mp3_audio_codec(AVFormatContext* out_fmt_ctx) { AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_MP3); if (!codec) { fprintf(stderr, "Codec not found\n"); exit(1); } AVStream *out_stream = avformat_new_stream(out_fmt_ctx, codec); AVCodecContext *codecCtx = out_stream->codec; /* put sample parameters */ codecCtx->bit_rate = 64000; /* check that the encoder supports s16 pcm input */ codecCtx->sample_fmt = AV_SAMPLE_FMT_S16P; if (!check_sample_fmt(codec, codecCtx->sample_fmt)) { fprintf(stderr, "Encoder does not support sample format %s", av_get_sample_fmt_name(codecCtx->sample_fmt)); exit(1); } /* select other audio parameters supported by the encoder */ codecCtx->sample_rate = 44100; codecCtx->channel_layout = AV_CH_LAYOUT_STEREO; codecCtx->channels = av_get_channel_layout_nb_channels(codecCtx->channel_layout); /* open it */ if (avcodec_open2(codecCtx, codec, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); exit(1); } out_stream->codec->codec_tag = 0; if (out_fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; }
/* * Audio encoding example */ 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); /* find the MP2 encoder */ codec = avcodec_find_encoder(AV_CODEC_ID_MP2); if (!codec) { fprintf(stderr, "Codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate audio codec context\n"); exit(1); } /* put sample parameters */ c->bit_rate = 64000; /* check that the encoder supports s16 pcm input */ c->sample_fmt = AV_SAMPLE_FMT_S16; if (!check_sample_fmt(codec, c->sample_fmt)) { fprintf(stderr, "Encoder does not support sample format %s", av_get_sample_fmt_name(c->sample_fmt)); exit(1); } /* select other audio parameters supported by the encoder */ c->sample_rate = 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 containing input raw audio */ 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; /* the codec gives us the frame size, in samples, * we calculate the size of the samples buffer in bytes */ buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, c->sample_fmt, 0); samples = av_malloc(buffer_size); if (!samples) { fprintf(stderr, "Could not allocate %d bytes for samples buffer\n", buffer_size); exit(1); } /* setup the data pointers in the AVFrame */ 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); } /* encode a single tone sound */ t = 0; tincr = 2 * M_PI * 440.0 / c->sample_rate; for(i=0;i<200;i++) { av_init_packet(&pkt); pkt.data = NULL; // packet data will be allocated by the encoder 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; } /* encode the samples */ 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); } } /* get the delayed frames */ 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); avcodec_free_frame(&frame); avcodec_close(c); av_free(c); }
static bool reinitialize_coder(struct libavcodec_codec_state *s, struct audio_desc desc) { av_freep(&s->samples); pthread_mutex_lock(s->libav_global_lock); avcodec_close(s->codec_ctx); pthread_mutex_unlock(s->libav_global_lock); /* put sample parameters */ s->codec_ctx->bit_rate = 64000; s->codec_ctx->sample_rate = desc.sample_rate; s->change_bps_to = 0; switch(desc.bps) { case 1: s->codec_ctx->sample_fmt = AV_SAMPLE_FMT_U8; break; case 2: s->codec_ctx->sample_fmt = AV_SAMPLE_FMT_S16; break; case 3: s->change_bps_to = 4; case 4: s->codec_ctx->sample_fmt = AV_SAMPLE_FMT_S32; break; } if(!check_sample_fmt(s->codec, s->codec_ctx->sample_fmt)) { s->codec_ctx->sample_fmt = s->codec->sample_fmts[0]; s->change_bps_to = av_get_bytes_per_sample(s->codec_ctx->sample_fmt); } s->codec_ctx->channels = 1; s->codec_ctx->channel_layout = AV_CH_LAYOUT_MONO; pthread_mutex_lock(s->libav_global_lock); /* open it */ if (avcodec_open2(s->codec_ctx, s->codec, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); pthread_mutex_unlock(s->libav_global_lock); return false; } pthread_mutex_unlock(s->libav_global_lock); if(s->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) { s->codec_ctx->frame_size = 1; } s->av_frame->nb_samples = s->codec_ctx->frame_size; s->av_frame->format = s->codec_ctx->sample_fmt; s->av_frame->channel_layout = AV_CH_LAYOUT_MONO; int channels = 1; /* the codec gives us the frame size, in samples, * we calculate the size of the samples buffer in bytes */ int buffer_size = av_samples_get_buffer_size(NULL, channels, s->codec_ctx->frame_size, s->codec_ctx->sample_fmt, 0); s->samples = av_malloc(buffer_size); if (!s->samples) { fprintf(stderr, "could not allocate %d bytes for samples buffer\n", buffer_size); return false; } /* setup the data pointers in the AVFrame */ int ret = avcodec_fill_audio_frame(s->av_frame, channels, s->codec_ctx->sample_fmt, (const uint8_t*)s->samples, buffer_size, 0); if (ret < 0) { fprintf(stderr, "could not setup audio frame\n"); return false; } s->output_channel.sample_rate = desc.sample_rate; s->output_channel.bps = desc.bps; s->saved_desc = desc; return true; }
/** * encodes raw audio to various encodings like mp3 * @param args it holds various parameters like desired output encoding * @see libav_encode_args */ void audio_encode(libav_encode_args* a) { libav_encode_args& args = *a; avcodec_register_all(); AVCodec *codec; AVCodecContext *c = NULL; AVFrame *frame; AVPacket pkt; int i, j, k, ret, got_output; int max_input_buffer_size = args.input_buffer.periodbuffer->size(); int input_buffer_size = args.initptr < args.termptr ? (args.termptr - args. initptr + 1) : (args.termptr + args.input_buffer.periodbuffer-> size() - args.initptr + 1); FILE *f; uint16_t *samples; float t, tincr; // printf("Encode audio file %s\n", filename); /* find the MP2 encoder */ codec = avcodec_find_encoder(args.codecID); if (!codec) { // fprintf(stderr, "Codec not found\n"); // exit(1); ErrnoExit("Codec not found"); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate audio codec context\n"); exit(1); } /* put sample parameters */ c->bit_rate = args.bitrate; /* check that the encoder supports s16 pcm input */ c->sample_fmt = args.av_smpl_fmt; //AV_SAMPLE_FMT_S16; if (!check_sample_fmt(codec, c->sample_fmt)) { fprintf(stderr, "Encoder does not support sample format %s", av_get_sample_fmt_name(c->sample_fmt)); exit(1); } /* select other audio parameters supported by the encoder */ c->sample_rate = 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 containing input raw audio */ frame = av_frame_alloc(); 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; /* the codec gives us the frame size, in samples, * we calculate the size of the samples buffer in bytes */ int computed_buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, c->sample_fmt, 0); samples = (uint16_t*) av_malloc(computed_buffer_size); if (!samples) { fprintf(stderr, "Could not allocate %d bytes for samples buffer\n", computed_buffer_size); exit(1); } /* setup the data pointers in the AVFrame */ if (computed_buffer_size != (*args.input_buffer.periodbuffer)[(args.initptr) % max_input_buffer_size].length) { fp_err(FPOL_LAV, "buffer statement mismatch. Encoder exited"); return; } ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, (const uint8_t*) samples, computed_buffer_size, 0); if (ret < 0) { fprintf(stderr, "Could not setup audio frame\n"); exit(1); } /* encode a single tone sound */ // t = 0; //tincr = 2 * M_PI * 440.0 / c->sample_rate; args.output_buffer = (char*) malloc(input_buffer_size * (*args.input_buffer.periodbuffer)[(args.initptr) % max_input_buffer_size].length); args.output_buffer_size = 0; int non_cycled_termptr = args.initptr + input_buffer_size; for (i = args.initptr; i < non_cycled_termptr; i++) { av_init_packet(&pkt); pkt.data = NULL; // packet data will be allocated by the encoder 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; // } /* setup the data pointers in the AVFrame */ int k = 0; int l = computed_buffer_size / 4; uint16_t* obuffer = (uint16_t*) ((*args.input_buffer.periodbuffer)[i % max_input_buffer_size].period); for (j = 0; j < computed_buffer_size / 2; j++) { samples[k++] = obuffer[j]; j++; samples[l++] = obuffer[j]; } /* encode the samples */ 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); //pkt.data[pkt.size] = 0; memcpy(args.output_buffer + args.output_buffer_size, pkt.data, pkt.size); args.output_buffer_size += pkt.size; av_packet_unref(&pkt); } } /* get the delayed frames */ 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); memcpy(args.output_buffer + args.output_buffer_size, pkt.data, pkt.size); args.output_buffer_size += pkt.size; av_packet_unref(&pkt); } } // fclose(f); av_freep(&samples); av_frame_free(&frame); avcodec_close(c); av_free(c); }
int main(int argc, char **argv) { const char *filename; const AVCodec *codec; AVCodecContext *c = NULL; AVFrame *frame; AVPacket *pkt; int i, j, k, ret; FILE *f; uint16_t *samples; float t, tincr; if (argc <= 1) { fprintf(stderr, "Usage: %s <output file>\n", argv[0]); return 0; } filename = argv[1]; /* find the MP2 encoder */ codec = avcodec_find_encoder(AV_CODEC_ID_MP2); if (!codec) { fprintf(stderr, "Codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate audio codec context\n"); exit(1); } /* put sample parameters */ c->bit_rate = 64000; /* check that the encoder supports s16 pcm input */ c->sample_fmt = AV_SAMPLE_FMT_S16; if (!check_sample_fmt(codec, c->sample_fmt)) { fprintf(stderr, "Encoder does not support sample format %s", av_get_sample_fmt_name(c->sample_fmt)); exit(1); } /* select other audio parameters supported by the encoder */ c->sample_rate = 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); } /* packet for holding encoded output */ pkt = av_packet_alloc(); if (!pkt) { fprintf(stderr, "could not allocate the packet\n"); exit(1); } /* frame containing input raw audio */ frame = av_frame_alloc(); 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; /* allocate the data buffers */ ret = av_frame_get_buffer(frame, 0); if (ret < 0) { fprintf(stderr, "Could not allocate audio data buffers\n"); exit(1); } /* encode a single tone sound */ t = 0; tincr = 2 * M_PI * 440.0 / c->sample_rate; for (i = 0; i < 200; i++) { /* make sure the frame is writable -- makes a copy if the encoder * kept a reference internally */ ret = av_frame_make_writable(frame); if (ret < 0) exit(1); samples = (uint16_t*)frame->data[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; } encode(c, frame, pkt, f); } /* flush the encoder */ encode(c, NULL, pkt, f); fclose(f); av_frame_free(&frame); av_packet_free(&pkt); avcodec_free_context(&c); return 0; }