From e1a58f0f4e9cd05441f1e1b43fc4c83d1f862dd7 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 25 Apr 2016 21:17:25 +0200 Subject: [PATCH] Send the AVCodecContext for audio to the stream mux instead of constructing a fake one. Probably fixes missing AAC extradata. --- audio_encoder.h | 2 +- mux.cpp | 13 +++---------- mux.h | 2 +- quicksync_encoder.cpp | 2 +- video_encoder.cpp | 18 +----------------- 5 files changed, 7 insertions(+), 30 deletions(-) diff --git a/audio_encoder.h b/audio_encoder.h index 682cc47..d627a9c 100644 --- a/audio_encoder.h +++ b/audio_encoder.h @@ -25,7 +25,7 @@ public: void encode_audio(const std::vector &audio, int64_t audio_pts); void encode_last_audio(); - const AVCodec *get_codec() { return ctx->codec; } + const AVCodecContext *get_ctx() { return ctx; } private: void encode_audio_one_frame(const float *audio, size_t num_samples, int64_t audio_pts); diff --git a/mux.cpp b/mux.cpp index 161194e..ece11e1 100644 --- a/mux.cpp +++ b/mux.cpp @@ -10,7 +10,7 @@ using namespace std; -Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const AVCodec *codec_audio, int time_base, int bit_rate, KeyFrameSignalReceiver *keyframe_signal_receiver) +Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const AVCodecContext *audio_ctx, int time_base, KeyFrameSignalReceiver *keyframe_signal_receiver) : avctx(avctx), keyframe_signal_receiver(keyframe_signal_receiver) { AVCodec *codec_video = avcodec_find_encoder((video_codec == CODEC_H264) ? AV_CODEC_ID_H264 : AV_CODEC_ID_RAWVIDEO); @@ -47,20 +47,13 @@ Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const avstream_video->codec->flags = AV_CODEC_FLAG_GLOBAL_HEADER; } - avstream_audio = avformat_new_stream(avctx, codec_audio); + avstream_audio = avformat_new_stream(avctx, nullptr); if (avstream_audio == nullptr) { fprintf(stderr, "avformat_new_stream() failed\n"); exit(1); } avstream_audio->time_base = AVRational{1, time_base}; - avstream_audio->codec->bit_rate = bit_rate; - avstream_audio->codec->sample_rate = OUTPUT_FREQUENCY; - avstream_audio->codec->channels = 2; - avstream_audio->codec->channel_layout = AV_CH_LAYOUT_STEREO; - avstream_audio->codec->time_base = AVRational{1, time_base}; - if (avctx->oformat->flags & AVFMT_GLOBALHEADER) { - avstream_audio->codec->flags = AV_CODEC_FLAG_GLOBAL_HEADER; - } + avcodec_copy_context(avstream_audio->codec, audio_ctx); AVDictionary *options = NULL; vector> opts = MUX_OPTS; diff --git a/mux.h b/mux.h index d645916..1dd967c 100644 --- a/mux.h +++ b/mux.h @@ -25,7 +25,7 @@ public: }; // Takes ownership of avctx. can be nullptr. - Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const AVCodec *codec_audio, int time_base, int bit_rate, KeyFrameSignalReceiver *keyframe_signal_receiver); + Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const AVCodecContext *audio_ctx, int time_base, KeyFrameSignalReceiver *keyframe_signal_receiver); ~Mux(); void add_packet(const AVPacket &pkt, int64_t pts, int64_t dts); diff --git a/quicksync_encoder.cpp b/quicksync_encoder.cpp index 5ebd454..fbbde94 100644 --- a/quicksync_encoder.cpp +++ b/quicksync_encoder.cpp @@ -1949,7 +1949,7 @@ void QuickSyncEncoderImpl::open_output_file(const std::string &filename) exit(1); } - file_mux.reset(new Mux(avctx, frame_width, frame_height, Mux::CODEC_H264, file_audio_encoder->get_codec(), TIMEBASE, DEFAULT_AUDIO_OUTPUT_BIT_RATE, nullptr)); + file_mux.reset(new Mux(avctx, frame_width, frame_height, Mux::CODEC_H264, file_audio_encoder->get_ctx(), TIMEBASE, nullptr)); } void QuickSyncEncoderImpl::encode_thread_func() diff --git a/video_encoder.cpp b/video_encoder.cpp index 910d4b7..cae4328 100644 --- a/video_encoder.cpp +++ b/video_encoder.cpp @@ -91,17 +91,6 @@ void VideoEncoder::open_output_stream() assert(oformat != nullptr); avctx->oformat = oformat; - string codec_name; - int bit_rate; - - if (global_flags.stream_audio_codec_name.empty()) { - codec_name = AUDIO_OUTPUT_CODEC_NAME; - bit_rate = DEFAULT_AUDIO_OUTPUT_BIT_RATE; - } else { - codec_name = global_flags.stream_audio_codec_name; - bit_rate = global_flags.stream_audio_codec_bitrate; - } - uint8_t *buf = (uint8_t *)av_malloc(MUX_BUFFER_SIZE); avctx->pb = avio_alloc_context(buf, MUX_BUFFER_SIZE, 1, this, nullptr, &VideoEncoder::write_packet_thunk, nullptr); @@ -113,15 +102,10 @@ void VideoEncoder::open_output_stream() } avctx->flags = AVFMT_FLAG_CUSTOM_IO; - AVCodec *codec_audio = avcodec_find_encoder_by_name(codec_name.c_str()); - if (codec_audio == nullptr) { - fprintf(stderr, "ERROR: Could not find codec '%s'\n", codec_name.c_str()); - exit(1); - } int time_base = global_flags.stream_coarse_timebase ? COARSE_TIMEBASE : TIMEBASE; stream_mux_writing_header = true; - stream_mux.reset(new Mux(avctx, width, height, video_codec, codec_audio, time_base, bit_rate, this)); + stream_mux.reset(new Mux(avctx, width, height, video_codec, stream_audio_encoder->get_ctx(), time_base, this)); stream_mux_writing_header = false; httpd->set_header(stream_mux_header); stream_mux_header.clear(); -- 2.39.2