X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=audio_encoder.cpp;h=e33d2181b46a5465a648bceead3636ba9872b535;hb=327534a3031a332423411c9599c741f2f81657df;hp=ac1c8f509f9aae5057335e3234dd2c2b123e6aa4;hpb=3be00c8dd8b841cecc44f57234b9fc2d3a94cb45;p=nageru diff --git a/audio_encoder.cpp b/audio_encoder.cpp index ac1c8f5..e33d218 100644 --- a/audio_encoder.cpp +++ b/audio_encoder.cpp @@ -5,18 +5,24 @@ extern "C" { #include #include #include +#include #include +#include +#include #include #include -#include } #include - +#include +#include +#include +#include #include #include #include "defs.h" +#include "mux.h" #include "timebase.h" using namespace std; @@ -37,7 +43,7 @@ AudioEncoder::AudioEncoder(const string &codec_name, int bit_rate, const AVOutpu ctx->channel_layout = AV_CH_LAYOUT_STEREO; ctx->time_base = AVRational{1, TIMEBASE}; if (oformat->flags & AVFMT_GLOBALHEADER) { - ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; + ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; } if (avcodec_open2(ctx, codec, NULL) < 0) { fprintf(stderr, "Could not open codec '%s'\n", codec_name.c_str()); @@ -118,24 +124,35 @@ void AudioEncoder::encode_audio_one_frame(const float *audio, size_t num_samples exit(1); } - AVPacket pkt; - av_init_packet(&pkt); - pkt.data = nullptr; - pkt.size = 0; - int got_output = 0; - avcodec_encode_audio2(ctx, &pkt, audio_frame, &got_output); - if (got_output) { - pkt.stream_index = 1; - pkt.flags = 0; - for (Mux *mux : muxes) { - mux->add_packet(pkt, pkt.pts, pkt.dts); + int err = avcodec_send_frame(ctx, audio_frame); + if (err < 0) { + fprintf(stderr, "avcodec_send_frame() failed with error %d\n", err); + exit(1); + } + + for ( ;; ) { // Termination condition within loop. + AVPacket pkt; + av_init_packet(&pkt); + pkt.data = nullptr; + pkt.size = 0; + int err = avcodec_receive_packet(ctx, &pkt); + if (err == 0) { + pkt.stream_index = 1; + pkt.flags = 0; + for (Mux *mux : muxes) { + mux->add_packet(pkt, pkt.pts, pkt.dts); + } + av_packet_unref(&pkt); + } else if (err == AVERROR(EAGAIN)) { + break; + } else { + fprintf(stderr, "avcodec_receive_frame() failed with error %d\n", err); + exit(1); } } av_freep(&audio_frame->data[0]); - av_frame_unref(audio_frame); - av_free_packet(&pkt); } void AudioEncoder::encode_last_audio() @@ -150,20 +167,31 @@ void AudioEncoder::encode_last_audio() if (ctx->codec->capabilities & AV_CODEC_CAP_DELAY) { // Collect any delayed frames. for ( ;; ) { - int got_output = 0; AVPacket pkt; av_init_packet(&pkt); pkt.data = nullptr; pkt.size = 0; - avcodec_encode_audio2(ctx, &pkt, nullptr, &got_output); - if (!got_output) break; - - pkt.stream_index = 1; - pkt.flags = 0; - for (Mux *mux : muxes) { - mux->add_packet(pkt, pkt.pts, pkt.dts); + int err = avcodec_receive_packet(ctx, &pkt); + if (err == 0) { + pkt.stream_index = 1; + pkt.flags = 0; + for (Mux *mux : muxes) { + mux->add_packet(pkt, pkt.pts, pkt.dts); + } + av_packet_unref(&pkt); + } else if (err == AVERROR_EOF) { + break; + } else { + fprintf(stderr, "avcodec_receive_frame() failed with error %d\n", err); + exit(1); } - av_free_packet(&pkt); } } } + +AVCodecParametersWithDeleter AudioEncoder::get_codec_parameters() +{ + AVCodecParameters *codecpar = avcodec_parameters_alloc(); + avcodec_parameters_from_context(codecpar, ctx); + return AVCodecParametersWithDeleter(codecpar); +}