blob: c246cbbfe01e5ea243085c7600182a679a2c4822 [file] [log] [blame]
agsantos5aa39652020-08-11 18:18:04 -04001/**
Sébastien Blincb783e32021-02-12 11:34:10 -05002 * Copyright (C) 2020-2021 Savoir-faire Linux Inc.
agsantosef9f8562020-06-25 16:43:25 -04003 *
4 * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
agsantos1e7736c2020-10-28 14:39:13 -040021#ifndef FRAMESCALER_H
22#define FRAMESCALER_H
23
AGS555248cd2020-05-13 11:15:19 -040024extern "C" {
25#include <libavutil/avutil.h>
26#include <libavutil/frame.h>
27#include <libavutil/pixfmt.h>
28#include <libswscale/swscale.h>
29}
30
agsantosac1940d2020-09-17 10:18:40 -040031class FrameScaler
32{
AGS555248cd2020-05-13 11:15:19 -040033public:
agsantos4bb4bc52021-03-08 14:21:45 -050034 FrameScaler() {}
AGS555248cd2020-05-13 11:15:19 -040035
36 /**
37 * @brief scaleConvert
38 * Scales an av frame accoding to the desired width height/height
39 * Converts the frame to another format if the desiredFromat is different from the input PixelFormat
40 * @param input
41 * @param desiredWidth
42 * @param desiredHeight
43 * @param desiredFormat
44 * @return
45 */
agsantos4bb4bc52021-03-08 14:21:45 -050046 static AVFrame* scaleConvert(const AVFrame* input,
47 const size_t desiredWidth,
48 const size_t desiredHeight,
49 const AVPixelFormat desiredFormat)
agsantos5aa39652020-08-11 18:18:04 -040050 {
agsantosac1940d2020-09-17 10:18:40 -040051 if (input) {
agsantos4bb4bc52021-03-08 14:21:45 -050052 SwsContext* ctx_ = nullptr;
agsantosc9181b42020-11-26 12:03:04 -050053 AVFrame* output = av_frame_alloc();
AGS555248cd2020-05-13 11:15:19 -040054 output->width = static_cast<int>(desiredWidth);
55 output->height = static_cast<int>(desiredHeight);
56 output->format = static_cast<int>(desiredFormat);
57
agsantosc9181b42020-11-26 12:03:04 -050058 if (av_frame_get_buffer(output, 0)) {
59 av_frame_unref(output);
60 av_frame_free(&output);
61 return nullptr;
62 }
AGS555248cd2020-05-13 11:15:19 -040063
64 ctx_ = sws_getCachedContext(ctx_,
65 input->width,
66 input->height,
67 static_cast<AVPixelFormat>(input->format),
agsantosc9181b42020-11-26 12:03:04 -050068 output->width,
69 output->height,
70 static_cast<AVPixelFormat>(output->format),
agsantos4bb4bc52021-03-08 14:21:45 -050071 SWS_FAST_BILINEAR,
agsantosac1940d2020-09-17 10:18:40 -040072 nullptr,
73 nullptr,
74 nullptr);
AGS555248cd2020-05-13 11:15:19 -040075 if (!ctx_) {
agsantosc9181b42020-11-26 12:03:04 -050076 av_frame_unref(output);
77 av_frame_free(&output);
78 return nullptr;
AGS555248cd2020-05-13 11:15:19 -040079 }
80
agsantosc9181b42020-11-26 12:03:04 -050081 if (sws_scale(ctx_,
agsantos4bb4bc52021-03-08 14:21:45 -050082 input->data,
83 input->linesize,
84 0,
85 input->height,
86 output->data,
87 output->linesize)
88 <= 0) {
agsantosc9181b42020-11-26 12:03:04 -050089 av_frame_unref(output);
90 av_frame_free(&output);
agsantos4bb4bc52021-03-08 14:21:45 -050091 sws_freeContext(ctx_);
agsantosc9181b42020-11-26 12:03:04 -050092 return nullptr;
93 }
agsantos4bb4bc52021-03-08 14:21:45 -050094
95 sws_freeContext(ctx_);
agsantosc9181b42020-11-26 12:03:04 -050096 return output;
AGS555248cd2020-05-13 11:15:19 -040097 }
agsantosc9181b42020-11-26 12:03:04 -050098 return nullptr;
AGS555248cd2020-05-13 11:15:19 -040099 }
100
101 /**
102 * @brief convertFormat
103 * @param input
104 * @param pix
105 * @return
106 */
agsantos4bb4bc52021-03-08 14:21:45 -0500107 static AVFrame* convertFormat(const AVFrame* input, AVPixelFormat pix)
agsantosac1940d2020-09-17 10:18:40 -0400108 {
109 return input ? scaleConvert(input,
110 static_cast<size_t>(input->width),
111 static_cast<size_t>(input->height),
112 pix)
agsantosc9181b42020-11-26 12:03:04 -0500113 : nullptr;
AGS555248cd2020-05-13 11:15:19 -0400114 }
AGS555248cd2020-05-13 11:15:19 -0400115};
agsantos1e7736c2020-10-28 14:39:13 -0400116
agsantosc9181b42020-11-26 12:03:04 -0500117#endif // FRAMESCALER_H