WaterMark: add gif support
GitLab: #23
Change-Id: I8dc9708315097a46e1f3b5359a86d399da680b13
diff --git a/WaterMark/WatermarkVideoSubscriber.cpp b/WaterMark/WatermarkVideoSubscriber.cpp
index c53d0de..dbf79b5 100644
--- a/WaterMark/WatermarkVideoSubscriber.cpp
+++ b/WaterMark/WatermarkVideoSubscriber.cpp
@@ -71,12 +71,14 @@
if (avformat_open_input(&ctx, logoPath_.c_str(), NULL, NULL) != 0) {
avformat_free_context(ctx);
Plog::log(Plog::LogPriority::INFO, TAG, "Couldn't open input stream.");
+ validLogo_ = false;
return {};
}
pFormatCtx_.reset(ctx);
// Retrieve stream information
if (avformat_find_stream_info(pFormatCtx_.get(), NULL) < 0) {
Plog::log(Plog::LogPriority::INFO, TAG, "Couldn't find stream information.");
+ validLogo_ = false;
return {};
}
@@ -92,6 +94,7 @@
if (videoStream_ == -1) {
Plog::log(Plog::LogPriority::INFO, TAG, "Didn't find a video stream.");
+ validLogo_ = false;
return {};
}
@@ -124,7 +127,6 @@
logoFilter_.initialize(logoDescription_, {logoStream_});
AVCodecContext* pCodecCtx;
- AVPacket* packet;
const AVCodec* pCodec = avcodec_find_decoder(
pFormatCtx_->streams[videoStream_]->codecpar->codec_id);
@@ -144,7 +146,8 @@
return;
}
- packet = av_packet_alloc();
+ AVPacket* packet = av_packet_alloc();
+
if (av_read_frame(pFormatCtx_.get(), packet) < 0) {
avcodec_close(pCodecCtx);
avcodec_free_context(&pCodecCtx);
@@ -292,13 +295,18 @@
if (std::abs(angle_) == 90)
rotateSides = ":out_w=ih:out_h=iw";
+ auto gifDescription = "movie='" + logoPath_ + "':loop=0,setpts=N/(FR*TB)[logo]," + logoDescription_ + "[loop],";
+
if (angle_ != 0)
- pluginFilterDescription_ = "[input]rotate=" + rotation[angle_] + rotateSides
- + "[rot],[rot][mark]overlay=" + std::to_string(points_[0].first)
+ pluginFilterDescription_ = gifDescription
+ + "[input]rotate=" + rotation[angle_] + rotateSides
+ + "[rot],[rot][loop]overlay=" + std::to_string(points_[0].first)
+ ":" + std::to_string(points_[0].second)
+ ",rotate=" + rotation[-angle_] + rotateSides;
else
- pluginFilterDescription_ = "[input][mark]overlay=" + std::to_string(points_[0].first) + ":"
+ pluginFilterDescription_ = gifDescription
+ + "[input][loop]overlay="
+ + std::to_string(points_[0].first) + ":"
+ std::to_string(points_[0].second);
std::string baseInfosDescription = "[input]rotate=" + rotation[angle_] + rotateSides
@@ -329,6 +337,8 @@
void
WatermarkVideoSubscriber::setMarkPosition()
{
+ if (!validLogo_)
+ return;
// 1, 2, 3, and 4 are cartesian positions
int margin = 10;
int markWidth = showLogo_ ? mark_->width : 0;
@@ -370,7 +380,7 @@
void
WatermarkVideoSubscriber::update(jami::Observable<AVFrame*>*, AVFrame* const& pluginFrame)
{
- if (!observable_ || !pluginFrame || (!validLogo_ && showLogo_))
+ if (!observable_ || !pluginFrame || (showLogo_ && !validLogo_))
return;
AVFrameSideData* side_data = av_frame_get_side_data(pluginFrame, AV_FRAME_DATA_DISPLAYMATRIX);
@@ -390,7 +400,13 @@
rgbFrame.reset(FrameScaler::convertFormat(rgbFrame.get(), AV_PIX_FMT_YUV420P));
if (!rgbFrame.get())
return;
- rgbFrame->pts = 1;
+
+ if (sourceTimeBase_.num != pluginFrame->time_base.num || sourceTimeBase_.den != pluginFrame->time_base.den)
+ firstRun = true;
+
+ rgbFrame->pts = pluginFrame->pts;
+ rgbFrame->time_base = pluginFrame->time_base;
+ sourceTimeBase_ = pluginFrame->time_base;
if (firstRun) {
pluginFilter_.clean();
@@ -401,7 +417,7 @@
setFilterDescription();
- rational<int> fr(rgbFrame->pts, 1);
+ rational<int> fr(sourceTimeBase_.den, sourceTimeBase_.num);
pluginstream_ = MediaStream("input",
rgbFrame->format,
1 / fr,
@@ -410,17 +426,8 @@
0,
fr);
- if (showLogo_) {
- MediaStream markstream_ = MediaStream("mark",
- mark_->format,
- logoStream_.timeBase,
- mark_->width,
- mark_->height,
- 0,
- logoStream_.frameRate);
- pluginFilter_.initialize(pluginFilterDescription_, {markstream_, pluginstream_});
- pluginFilter_.feedInput(mark_.get(), "mark");
- pluginFilter_.feedEOF("mark");
+ if (showLogo_ && validLogo_) {
+ pluginFilter_.initialize(pluginFilterDescription_, {pluginstream_});
}
infosFilter_.initialize(infosDescription_, {pluginstream_});
@@ -430,7 +437,7 @@
if (!infosFilter_.initialized_ && !pluginFilter_.initialized_)
return;
- if (showLogo_) {
+ if (showLogo_ && validLogo_) {
if (pluginFilter_.feedInput(rgbFrame.get(), "input") == 0) {
uniqueFramePtr filteredFrame = {pluginFilter_.readOutput(), frameFree};
if (filteredFrame.get())