From 39a0adba3c62fd03e18e2e34a20ff9b14276c2f2 Mon Sep 17 00:00:00 2001 From: ffiirree Date: Thu, 16 Jun 2022 22:33:56 +0800 Subject: [PATCH] fix a bug in Encoder class --- src/capturer.h | 6 +++--- src/media/decoder.cpp | 21 ++++----------------- src/media/dispatcher.cpp | 16 ++++++++-------- src/media/encoder.h | 6 +++--- src/record/screenrecorder.cpp | 2 +- 5 files changed, 19 insertions(+), 32 deletions(-) diff --git a/src/capturer.h b/src/capturer.h index 8389c94..8550076 100644 --- a/src/capturer.h +++ b/src/capturer.h @@ -14,10 +14,10 @@ class LimitSizeVector : public std::vector { public: void append(const T& value) { - push_back(value); + this->push_back(value); - if(size() > MAX_SIZE) { - erase(begin()); + if(this->size() > MAX_SIZE) { + this->erase(this->begin()); } } }; diff --git a/src/media/decoder.cpp b/src/media/decoder.cpp index b5a0196..60f46c9 100644 --- a/src/media/decoder.cpp +++ b/src/media/decoder.cpp @@ -53,24 +53,17 @@ int Decoder::open(const std::string& name, const std::string& format, const std: return -1; } - av_dump_format(fmt_ctx_, 0, name.c_str(), 0); + // av_dump_format(fmt_ctx_, 0, name.c_str(), 0); // find video & audio streams - video_stream_idx_ = av_find_best_stream(fmt_ctx_, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0); - audio_stream_idx_ = av_find_best_stream(fmt_ctx_, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0); + video_stream_idx_ = av_find_best_stream(fmt_ctx_, AVMEDIA_TYPE_VIDEO, -1, -1, &video_decoder_, 0); + audio_stream_idx_ = av_find_best_stream(fmt_ctx_, AVMEDIA_TYPE_AUDIO, -1, -1, &audio_decoder_, 0); if (video_stream_idx_ < 0 && audio_stream_idx_ < 0) { LOG(ERROR) << "not found any stream"; return -1; } if (video_stream_idx_ >= 0) { - // decoder - video_decoder_ = avcodec_find_decoder(fmt_ctx_->streams[video_stream_idx_]->codecpar->codec_id); - if (!video_decoder_) { - LOG(ERROR) << "avcodec_find_decoder"; - return -1; - } - // decoder context video_decoder_ctx_ = avcodec_alloc_context3(video_decoder_); if (!video_decoder_ctx_) { @@ -101,12 +94,6 @@ int Decoder::open(const std::string& name, const std::string& format, const std: } if (audio_stream_idx_ >= 0) { - audio_decoder_ = avcodec_find_decoder(fmt_ctx_->streams[audio_stream_idx_]->codecpar->codec_id); - if (!audio_decoder_) { - LOG(ERROR) << "avcodec_find_decoder() for audio"; - return false; - } - audio_decoder_ctx_ = avcodec_alloc_context3(audio_decoder_); if (!audio_decoder_ctx_) { LOG(ERROR) << "avcodec_alloc_context3 failed for audio"; @@ -127,7 +114,7 @@ int Decoder::open(const std::string& name, const std::string& format, const std: audio_decoder_ctx_->sample_rate, audio_decoder_ctx_->channels, av_get_default_channel_layout(audio_decoder_ctx_->channels), av_get_sample_fmt_name(audio_decoder_ctx_->sample_fmt), - fmt_ctx_->streams[audio_stream_idx_]->nb_frames, + audio_decoder_ctx_->frame_size, fmt_ctx_->streams[audio_stream_idx_]->start_time ); } diff --git a/src/media/dispatcher.cpp b/src/media/dispatcher.cpp index 32d2c4f..f4ecace 100644 --- a/src/media/dispatcher.cpp +++ b/src/media/dispatcher.cpp @@ -37,7 +37,7 @@ int Dispatcher::create_filter_for_video_input(const Producer* decoder, LOG(ERROR) << "[DISPATCHER] decoder is not ready"; return -1; } - LOG(INFO) << "[DISPATCHER] " << "create filter for video buffersrc: " << decoder->format_str(AVMEDIA_TYPE_VIDEO); + LOG(INFO) << "[DISPATCHER] " << "create buffersrc: " << decoder->format_str(AVMEDIA_TYPE_VIDEO); const AVFilter* buffersrc = avfilter_get_by_name("buffer"); if (!buffersrc) { @@ -73,7 +73,7 @@ int Dispatcher::create_filter_for_video_output(const Consumer* encoder, return -1; } - LOG(INFO) << "[DISPATCHER] " << "create filter for video buffersink"; + LOG(INFO) << "[DISPATCHER] " << "create buffersink"; return 0; } @@ -84,7 +84,7 @@ int Dispatcher::create_filter_for_audio_input(const Producer* decoder, LOG(ERROR) << "[DISPATCHER] decoder is not ready"; return -1; } - LOG(INFO) << "[DISPATCHER] " << "create filter for audio buffersrc: " << decoder->format_str(AVMEDIA_TYPE_AUDIO); + LOG(INFO) << "[DISPATCHER] " << "create abuffersrc: " << decoder->format_str(AVMEDIA_TYPE_AUDIO); const AVFilter* buffersrc = avfilter_get_by_name("abuffer"); if (!buffersrc) { @@ -122,7 +122,7 @@ int Dispatcher::create_filter_for_audio_output(const Consumer* encoder, return -1; } - LOG(INFO) << "[DISPATCHER] " << "create filter for audio buffersink"; + LOG(INFO) << "[DISPATCHER] " << "create abuffersink"; return 0; } @@ -275,9 +275,8 @@ int Dispatcher::create_filter_graph(const std::string_view& graph_desc) } ready_ = true; - LOG(INFO) << "[ENCODER] " << "filter graph @{"; - LOG(INFO) << "\n" << avfilter_graph_dump(filter_graph_, nullptr); - LOG(INFO) << "[ENCODER] " << "@}"; + LOG(INFO) << "[DISPATCHER] " << "filter graph @{\n" << avfilter_graph_dump(filter_graph_, nullptr); + LOG(INFO) << "[DISPATCHER] " << "@}"; return 0; } @@ -387,7 +386,7 @@ int Dispatcher::dispatch_thread_f() for (auto& [sink_ctx, consumer, stream_eof] : o_streams_) { enum AVMediaType media_type = av_buffersink_get_type(sink_ctx); ret = 0; - while (ret >= 0 && !stream_eof) { + while (ret >= 0 && !stream_eof && !consumer->full(media_type)) { av_frame_unref(filtered_frame); ret = av_buffersink_get_frame_flags(sink_ctx, filtered_frame, AV_BUFFERSINK_FLAG_NO_REQUEST); @@ -407,6 +406,7 @@ int Dispatcher::dispatch_thread_f() } while (consumer->full(media_type) && running_) { + LOG(WARNING) << "[DISPATCHER] better not be here"; std::this_thread::sleep_for(20ms); } ret = consumer->consume(filtered_frame, media_type); diff --git a/src/media/encoder.h b/src/media/encoder.h index 9f3d14c..7bda933 100644 --- a/src/media/encoder.h +++ b/src/media/encoder.h @@ -35,7 +35,7 @@ class Encoder : public Consumer { case AVMEDIA_TYPE_VIDEO: return video_buffer_.full(); case AVMEDIA_TYPE_AUDIO: - return video_buffer_.full(); + return audio_buffer_.full(); default: return true; } } @@ -128,12 +128,12 @@ class Encoder : public Consumer { AVAudioFifo* audio_fifo_buffer_{ nullptr }; - RingVector video_buffer_{ + RingVector video_buffer_{ []() { return av_frame_alloc(); }, [](AVFrame** frame) { av_frame_free(frame); } }; - RingVector audio_buffer_{ + RingVector audio_buffer_{ []() { return av_frame_alloc(); }, [](AVFrame** frame) { av_frame_free(frame); } }; diff --git a/src/record/screenrecorder.cpp b/src/record/screenrecorder.cpp index 82dbf0c..b52209d 100644 --- a/src/record/screenrecorder.cpp +++ b/src/record/screenrecorder.cpp @@ -112,7 +112,7 @@ void ScreenRecorder::setup() filename_ = fmt::format("{}/Capturer_video_{}.{}", root_dir, date_time, (recording_type_ == VIDEO ? "mp4" : "gif")); #ifdef __linux__ if (recording_type_ != GIF && Devices::microphones().size() > 0 && Devices::microphones().contains("default")) { - if (microphone_decoder_ && microphone_decoder_->open("default", "pulse") < 0) { + if (microphone_decoder_ && microphone_decoder_->open("default", "alsa") < 0) { microphone_decoder_->reset(); } }