From e0e7f6afb9d29aa1c1fa6f4a3681adc27209cd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Wed, 9 Sep 2020 16:30:40 -0400 Subject: [PATCH] video: factor getting video orientation Change-Id: I332fb4f341f3cb433f54b71651a02d6eb417282b --- src/client/videomanager.cpp | 22 ++++++++++++++++++++ src/dring/videomanager_interface.h | 3 +++ src/media/media_recorder.cpp | 10 +--------- src/media/video/sinkclient.cpp | 14 ++----------- src/media/video/video_mixer.cpp | 12 +---------- src/media/video/video_sender.cpp | 32 +++++++----------------------- 6 files changed, 36 insertions(+), 57 deletions(-) diff --git a/src/client/videomanager.cpp b/src/client/videomanager.cpp index 56ed87ea17..5241073595 100644 --- a/src/client/videomanager.cpp +++ b/src/client/videomanager.cpp @@ -49,6 +49,10 @@ #include <cstring> // std::memset #include <ciso646> // fix windows compiler bug +extern "C" { +#include <libavutil/display.h> +} + namespace DRing { MediaFrame::MediaFrame() @@ -341,6 +345,24 @@ VideoFrame::noise() } } +int +VideoFrame::getOrientation() const +{ + int32_t* matrix {nullptr}; + if (auto p = packet()) { + matrix = reinterpret_cast<int32_t*>(av_packet_get_side_data(p, AV_PKT_DATA_DISPLAYMATRIX, nullptr)); + } else if (auto p = pointer()) { + if (AVFrameSideData* side_data = av_frame_get_side_data(p, AV_FRAME_DATA_DISPLAYMATRIX)) { + matrix = reinterpret_cast<int32_t*>(side_data->data); + } + } + if (matrix) { + double angle = av_display_rotation_get(matrix); + return std::isnan(angle) ? 0 : -(int)angle; + } + return 0; +} + VideoFrame* getNewFrame() { diff --git a/src/dring/videomanager_interface.h b/src/dring/videomanager_interface.h index 04173a3a6c..7dbcea0e75 100644 --- a/src/dring/videomanager_interface.h +++ b/src/dring/videomanager_interface.h @@ -149,6 +149,9 @@ public: // Allocate internal pixel buffers following given specifications void reserve(int format, int width, int height); + // Return orientation (in degrees) stored in the frame metadata, or 0 by default. + int getOrientation() const; + // Set internal pixel buffers on given memory buffer // This buffer must follow given specifications. void setFromMemory(uint8_t* data, int format, int width, int height) noexcept; diff --git a/src/media/media_recorder.cpp b/src/media/media_recorder.cpp index f2ee43918a..61b195c303 100644 --- a/src/media/media_recorder.cpp +++ b/src/media/media_recorder.cpp @@ -39,10 +39,6 @@ #include <sys/types.h> #include <ctime> -extern "C" { -#include <libavutil/display.h> -} - namespace jami { const constexpr char ROTATION_FILTER_INPUT_NAME[] = "in"; @@ -87,11 +83,7 @@ struct MediaRecorder::StreamObserver : public Observer<std::shared_ptr<MediaFram else #endif framePtr = std::static_pointer_cast<VideoFrame>(m); - AVFrameSideData* sideData = av_frame_get_side_data(framePtr->pointer(), - AV_FRAME_DATA_DISPLAYMATRIX); - int angle = sideData - ? -av_display_rotation_get(reinterpret_cast<int32_t*>(sideData->data)) - : 0; + int angle = framePtr->getOrientation(); if (angle != rotation_) { videoRotationFilter_ = jami::video::getTransposeFilter(angle, ROTATION_FILTER_INPUT_NAME, diff --git a/src/media/video/sinkclient.cpp b/src/media/video/sinkclient.cpp index 02f36f7dd9..e52b0ddd54 100644 --- a/src/media/video/sinkclient.cpp +++ b/src/media/video/sinkclient.cpp @@ -58,10 +58,6 @@ #include <stdexcept> #include <cmath> -extern "C" { -#include <libavutil/display.h> -} - namespace jami { namespace video { @@ -367,14 +363,8 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/, AV_PIX_FMT_NV12); else #endif - frame = std::static_pointer_cast<VideoFrame>(frame_p); - AVFrameSideData* side_data = av_frame_get_side_data(frame->pointer(), - AV_FRAME_DATA_DISPLAYMATRIX); - int angle = 0; - if (side_data) { - auto matrix_rotation = reinterpret_cast<int32_t*>(side_data->data); - angle = -av_display_rotation_get(matrix_rotation); - } + frame = std::static_pointer_cast<VideoFrame>(frame_p); + int angle = frame->getOrientation(); if (angle != rotation_) { filter_ = getTransposeFilter(angle, FILTER_INPUT_NAME, diff --git a/src/media/video/video_mixer.cpp b/src/media/video/video_mixer.cpp index 172d1f5045..279a15ee87 100644 --- a/src/media/video/video_mixer.cpp +++ b/src/media/video/video_mixer.cpp @@ -38,10 +38,6 @@ #include <opendht/thread_pool.h> -extern "C" { -#include <libavutil/display.h> -} - static constexpr auto MIN_LINE_ZOOM = 6; // Used by the ONE_BIG_WITH_SMALL layout for the small previews @@ -307,13 +303,7 @@ VideoMixer::render_frame(VideoFrame& output, int xoff = source->x; int yoff = source->y; - 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); - } + int angle = frame->getOrientation(); const constexpr char filterIn[] = "mixin"; if (angle != source->rotation) { source->rotationFilter = video::getTransposeFilter(angle, diff --git a/src/media/video/video_sender.cpp b/src/media/video/video_sender.cpp index 7a80811623..f643046bbd 100644 --- a/src/media/video/video_sender.cpp +++ b/src/media/video/video_sender.cpp @@ -36,9 +36,6 @@ #include <map> #include <unistd.h> -extern "C" { -#include <libavutil/display.h> -} namespace jami { namespace video { @@ -84,6 +81,13 @@ VideoSender::~VideoSender() void VideoSender::encodeAndSendVideo(VideoFrame& input_frame) { + int angle = input_frame.getOrientation(); + if (rotation_ != angle) { + rotation_ = angle; + if (changeOrientationCallback_) + changeOrientationCallback_(rotation_); + } + if (auto packet = input_frame.packet()) { #if __ANDROID__ if (forceKeyFrame_) { @@ -91,17 +95,6 @@ VideoSender::encodeAndSendVideo(VideoFrame& input_frame) --forceKeyFrame_; } #endif - int size {0}; - uint8_t* side_data = av_packet_get_side_data(packet, AV_PKT_DATA_DISPLAYMATRIX, &size); - auto angle = (side_data == nullptr || size == 0) - ? 0 - : -av_display_rotation_get(reinterpret_cast<int32_t*>(side_data)); - if (rotation_ != angle) { - rotation_ = angle; - if (changeOrientationCallback_) - changeOrientationCallback_(rotation_); - } - videoEncoder_->send(*packet); } else { bool is_keyframe = forceKeyFrame_ > 0 @@ -110,17 +103,6 @@ VideoSender::encodeAndSendVideo(VideoFrame& input_frame) if (is_keyframe) --forceKeyFrame_; - AVFrameSideData* side_data = av_frame_get_side_data(input_frame.pointer(), - AV_FRAME_DATA_DISPLAYMATRIX); - auto angle = side_data == nullptr - ? 0 - : -av_display_rotation_get(reinterpret_cast<int32_t*>(side_data->data)); - if (rotation_ != angle) { - rotation_ = angle; - if (changeOrientationCallback_) - changeOrientationCallback_(rotation_); - } - if (videoEncoder_->encode(input_frame, is_keyframe, frameNumber_++) < 0) JAMI_ERR("encoding failed"); } -- GitLab