Skip to content
Snippets Groups Projects
Commit d7da705a authored by Denys Vidal's avatar Denys Vidal Committed by Philippe Gorley
Browse files

video_mixer: add rotation

Each video source in a conference now stores a filter for rotation and
its current rotation.

Change-Id: Ib2d2dd7bd61a481f0f1f239e376d0d655b27b94b
parent c413dc43
Branches
No related tags found
No related merge requests found
...@@ -37,31 +37,29 @@ getTransposeFilter(int rotation, std::string inputName, int width, int height, i ...@@ -37,31 +37,29 @@ getTransposeFilter(int rotation, std::string inputName, int width, int height, i
} }
std::stringstream ss; std::stringstream ss;
ss << "[" << inputName << "]"; ss << "[" << inputName << "] ";
switch (rotation) { switch (rotation) {
case 90: case 90:
case -270: case -270:
ss << "transpose=2"; ss << "transpose=2";
if (rescale) { if (rescale)
ss << ",scale=w=-1:h=" << height; ss << ", scale=w=-1:h=" << height
ss << ",pad=" << width << ":" << height << ":(ow-iw)/2"; << ", pad=" << width << ":" << height << ":(ow-iw)/2";
}
break; break;
case 180 : case 180 :
case -180 : case -180 :
ss << "transpose=1,transpose=1"; ss << "transpose=1, transpose=1";
break; break;
case 270 : case 270 :
case -90 : case -90 :
ss << "transpose=1"; ss << "transpose=1";
if (rescale) { if (rescale)
ss << ",scale=w=-1:h=" << height; ss << ", scale=w=-1:h=" << height
ss << ",pad=" << width << ":" << height << ":(ow-iw)/2"; << ", pad=" << width << ":" << height << ":(ow-iw)/2";
}
break; break;
default : default :
ss << "null"; return {};
} }
const auto one = rational<int>(1); const auto one = rational<int>(1);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Copyright (C) 2013-2019 Savoir-faire Linux Inc. * Copyright (C) 2013-2019 Savoir-faire Linux Inc.
* *
* Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com> * Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
* Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -24,8 +25,10 @@ ...@@ -24,8 +25,10 @@
#include "media_buffer.h" #include "media_buffer.h"
#include "client/videomanager.h" #include "client/videomanager.h"
#include "manager.h" #include "manager.h"
#include "media_filter.h"
#include "sinkclient.h" #include "sinkclient.h"
#include "logger.h" #include "logger.h"
#include "filter_transpose.h"
#ifdef RING_ACCEL #ifdef RING_ACCEL
#include "accel.h" #include "accel.h"
#endif #endif
...@@ -33,10 +36,16 @@ ...@@ -33,10 +36,16 @@
#include <cmath> #include <cmath>
#include <unistd.h> #include <unistd.h>
extern "C" {
#include <libavutil/display.h>
}
namespace jami { namespace video { namespace jami { namespace video {
struct VideoMixer::VideoMixerSource { struct VideoMixer::VideoMixerSource {
Observable<std::shared_ptr<MediaFrame>>* source = nullptr; Observable<std::shared_ptr<MediaFrame>>* source {nullptr};
int rotation {0};
std::unique_ptr<MediaFilter> rotationFilter {nullptr};
std::unique_ptr<VideoFrame> update_frame; std::unique_ptr<VideoFrame> update_frame;
std::unique_ptr<VideoFrame> render_frame; std::unique_ptr<VideoFrame> render_frame;
void atomic_swap_render(std::unique_ptr<VideoFrame>& other) { void atomic_swap_render(std::unique_ptr<VideoFrame>& other) {
...@@ -156,7 +165,7 @@ VideoMixer::process() ...@@ -156,7 +165,7 @@ VideoMixer::process()
x->atomic_swap_render(input); x->atomic_swap_render(input);
if (input) if (input)
render_frame(output, *input, i); render_frame(output, *input, x, i);
x->atomic_swap_render(input); x->atomic_swap_render(input);
++i; ++i;
...@@ -167,16 +176,16 @@ VideoMixer::process() ...@@ -167,16 +176,16 @@ VideoMixer::process()
} }
void void
VideoMixer::render_frame(VideoFrame& output, const VideoFrame& input, int index) VideoMixer::render_frame(VideoFrame& output, const VideoFrame& input,
const std::unique_ptr<VideoMixerSource>& source, int index)
{ {
if (!width_ or !height_ or !input.pointer()) if (!width_ or !height_ or !input.pointer())
return; return;
#ifdef RING_ACCEL #ifdef RING_ACCEL
auto framePtr = HardwareAccel::transferToMainMemory(input, AV_PIX_FMT_NV12); std::shared_ptr<VideoFrame> frame { HardwareAccel::transferToMainMemory(input, AV_PIX_FMT_NV12) };
const auto& swFrame = *framePtr;
#else #else
const auto& swFrame = input; std::shared_ptr<VideoFrame> frame = input;
#endif #endif
const int n = sources_.size(); const int n = sources_.size();
...@@ -186,7 +195,25 @@ VideoMixer::render_frame(VideoFrame& output, const VideoFrame& input, int index) ...@@ -186,7 +195,25 @@ VideoMixer::render_frame(VideoFrame& output, const VideoFrame& input, int index)
int xoff = (index % zoom) * cell_width; int xoff = (index % zoom) * cell_width;
int yoff = (index / zoom) * cell_height; int yoff = (index / zoom) * cell_height;
scaler_.scale_and_pad(swFrame, output, xoff, yoff, cell_width, cell_height, true); AVFrameSideData* sideData = av_frame_get_side_data(frame->pointer(), AV_FRAME_DATA_DISPLAYMATRIX);
int angle = 0;
if (sideData) {
auto matrixRotation = reinterpret_cast<int32_t*>(sideData->data);
angle = av_display_rotation_get(matrixRotation);
}
const constexpr char filterIn[] = "mixin";
if (angle != source->rotation) {
source->rotationFilter = video::getTransposeFilter(angle, filterIn,
frame->width(), frame->height(), frame->format(), true);
source->rotation = angle;
}
if (source->rotationFilter) {
source->rotationFilter->feedInput(frame->pointer(), filterIn);
frame = std::static_pointer_cast<VideoFrame>(std::shared_ptr<MediaFrame>(
source->rotationFilter->readOutput()));
}
scaler_.scale_and_pad(*frame, output, xoff, yoff, cell_width, cell_height, true);
} }
void void
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Copyright (C) 2013-2019 Savoir-faire Linux Inc. * Copyright (C) 2013-2019 Savoir-faire Linux Inc.
* *
* Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com> * Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
* Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -58,7 +59,8 @@ private: ...@@ -58,7 +59,8 @@ private:
struct VideoMixerSource; struct VideoMixerSource;
void render_frame(VideoFrame& output, const VideoFrame& input, int index); void render_frame(VideoFrame& output, const VideoFrame& input,
const std::unique_ptr<VideoMixerSource>& source, int index);
void start_sink(); void start_sink();
void stop_sink(); void stop_sink();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment