From f8bd331d66ad263b23c0cb9fe12bdf27ffbf095f Mon Sep 17 00:00:00 2001 From: philippegorley <philippe.gorley@savoirfairelinux.com> Date: Tue, 10 Jul 2018 14:20:36 -0400 Subject: [PATCH] recorder: use video input as source MediaRecorder no longer uses VideoSender (encoder) as a source for its local video and will directly use VideoInput (decoder), as it is earlier in the pipeline. This is the first step to support switching inputs while recording. Change-Id: Ia163efa3b20a349a93fc7b05213ec5e00de1704e Reviewed-by: Sebastien Blin <sebastien.blin@savoirfairelinux.com> --- src/media/media_decoder.cpp | 5 +++-- src/media/media_encoder.cpp | 25 ++++++++++++------------- src/media/video/video_input.cpp | 7 +++++++ src/media/video/video_input.h | 3 +++ src/media/video/video_rtp_session.cpp | 10 ++++------ src/media/video/video_sender.cpp | 7 ------- src/media/video/video_sender.h | 3 --- 7 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp index 9c3dfa2d89..b450b6def3 100644 --- a/src/media/media_decoder.cpp +++ b/src/media/media_decoder.cpp @@ -295,16 +295,17 @@ MediaDecoder::decode(VideoFrame& result) static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); if (auto rec = recorder_.lock()) { + bool fromPeer = (inputCtx_->iformat->name == std::string("sdp")); if (!recordingStarted_) { auto ms = MediaStream("", decoderCtx_, frame->pts); ms.format = frame->format; // might not match avStream_ if accel is used - if (rec->addStream(true, true, ms) >= 0) + if (rec->addStream(true, fromPeer, ms) >= 0) recordingStarted_ = true; else recorder_ = std::weak_ptr<MediaRecorder>(); } if (recordingStarted_) - rec->recordData(frame, true, true); + rec->recordData(frame, true, fromPeer); } if (emulateRate_ and packetTimestamp != AV_NOPTS_VALUE) { diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp index 029d566af8..44034e5b89 100644 --- a/src/media/media_encoder.cpp +++ b/src/media/media_encoder.cpp @@ -443,6 +443,18 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer) nb_frames -= frame->nb_samples; offset_ptr += frame->nb_samples * buffer.channels(); + if (auto rec = recorder_.lock()) { + if (!recordingStarted_) { + auto ms = MediaStream("", encoders_[currentStreamIdx_], frame->pts); + if (rec->addStream(false, false, ms) >= 0) + recordingStarted_ = true; + else + recorder_ = std::weak_ptr<MediaRecorder>(); + } + if (recordingStarted_) + rec->recordData(frame, false, false); + } + encode(frame, currentStreamIdx_); av_frame_free(&frame); } @@ -460,19 +472,6 @@ MediaEncoder::encode(AVFrame* frame, int streamIdx) pkt.data = nullptr; // packet data will be allocated by the encoder pkt.size = 0; - if (auto rec = recorder_.lock()) { - bool isVideo = encoderCtx->codec_type == AVMEDIA_TYPE_VIDEO; - if (!recordingStarted_) { - auto ms = MediaStream("", encoderCtx, frame->pts); - if (rec->addStream(isVideo, false, ms) >= 0) - recordingStarted_ = true; - else - recorder_ = std::weak_ptr<MediaRecorder>(); - } - if (recordingStarted_) - rec->recordData(frame, isVideo, false); - } - ret = avcodec_send_frame(encoderCtx, frame); if (ret < 0) return -1; diff --git a/src/media/video/video_input.cpp b/src/media/video/video_input.cpp index 5853697e5d..367c1c6984 100644 --- a/src/media/video/video_input.cpp +++ b/src/media/video/video_input.cpp @@ -587,4 +587,11 @@ VideoInput::foundDecOpts(const DeviceParams& params) } } +void +VideoInput::startRecorder(std::shared_ptr<MediaRecorder>& rec) +{ + if (decoder_) + decoder_->startRecorder(rec); +} + }} // namespace ring::video diff --git a/src/media/video/video_input.h b/src/media/video/video_input.h index f6a4c0b44f..4ddcc81ade 100644 --- a/src/media/video/video_input.h +++ b/src/media/video/video_input.h @@ -42,6 +42,7 @@ namespace ring { class MediaDecoder; +class MediaRecorder; } namespace ring { namespace video { @@ -88,6 +89,8 @@ public: void releaseFrame(void *frame); #endif + void startRecorder(std::shared_ptr<MediaRecorder>& rec); + private: NON_COPYABLE(VideoInput); diff --git a/src/media/video/video_rtp_session.cpp b/src/media/video/video_rtp_session.cpp index 6818967188..50d7f8a245 100644 --- a/src/media/video/video_rtp_session.cpp +++ b/src/media/video/video_rtp_session.cpp @@ -571,14 +571,12 @@ VideoRtpSession::startRecorder(std::shared_ptr<MediaRecorder>& rec) const constexpr int keyframes = 3; if (receiveThread_) receiveThread_->startRecorder(rec); - if (sender_) - sender_->startRecorder(rec); - for (int i = 0; i < keyframes; ++i) { + if (auto vidInput = std::static_pointer_cast<VideoInput>(videoLocal_)) + vidInput->startRecorder(rec); + for (int i = 0; i < keyframes; ++i) if (receiveThread_) receiveThread_->triggerKeyFrameRequest(); - if (sender_) - sender_->forceKeyFrame(); - } + // TODO trigger keyframes for local video } }} // namespace ring::video diff --git a/src/media/video/video_sender.cpp b/src/media/video/video_sender.cpp index ca58aae129..8fb9916e0e 100644 --- a/src/media/video/video_sender.cpp +++ b/src/media/video/video_sender.cpp @@ -106,11 +106,4 @@ VideoSender::useCodec(const ring::AccountVideoCodecInfo* codec) const return videoEncoder_->useCodec(codec); } -void -VideoSender::startRecorder(std::shared_ptr<MediaRecorder>& rec) -{ - if (videoEncoder_) - videoEncoder_->startRecorder(rec); -} - }} // namespace ring::video diff --git a/src/media/video/video_sender.h b/src/media/video/video_sender.h index 875b17fa2f..322aa61892 100644 --- a/src/media/video/video_sender.h +++ b/src/media/video/video_sender.h @@ -35,7 +35,6 @@ namespace ring { class SocketPair; struct AccountVideoCodecInfo; -class MediaRecorder; } namespace ring { namespace video { @@ -63,8 +62,6 @@ public: bool useCodec(const AccountVideoCodecInfo* codec) const; - void startRecorder(std::shared_ptr<MediaRecorder>& rec); - private: static constexpr int KEYFRAMES_AT_START {4}; // Number of keyframes to enforce at stream startup static constexpr unsigned KEY_FRAME_PERIOD {0}; // seconds before forcing a keyframe -- GitLab