Commit f8bd331d authored by Philippe Gorley's avatar Philippe Gorley Committed by Sébastien Blin

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: Sébastien Blin's avatarSebastien Blin <sebastien.blin@savoirfairelinux.com>
parent 33293017
......@@ -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) {
......
......@@ -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;
......
......@@ -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
......@@ -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);
......
......@@ -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
......@@ -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
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment