MythTV  master
vaapi2context.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 MythTV Developers <mythtv-dev@mythtv.org>
3 //
4 // This is part of MythTV (https://www.mythtv.org)
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 2 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 // You should have received a copy of the GNU General Public License
21 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 //
24 
25 #include "mythcorecontext.h"
26 #include "mythlogging.h"
27 #include "vaapi2context.h"
28 #include "videooutbase.h"
29 #include "mythplayer.h"
30 
31 extern "C" {
32  #include "libavutil/pixfmt.h"
33  #include "libavutil/hwcontext.h"
34  #include "libavcodec/avcodec.h"
35 }
36 
37 #define LOC QString("VAAPI2: ")
38 
41 {
42 
43 }
44 
46  AVCodec **ppCodec,
47  const QString &decoder,
48  uint stream_type,
49  AVPixelFormat &pix_fmt)
50 {
51  enum AVHWDeviceType type = AV_HWDEVICE_TYPE_VAAPI;
52 
53  AVPixelFormat fmt = AV_PIX_FMT_NONE;
54  if (decoder == "vaapi2")
55  {
56  for (int i = 0;; i++) {
57  const AVCodecHWConfig *config = avcodec_get_hw_config(*ppCodec, i);
58  if (!config) {
59  LOG(VB_PLAYBACK, LOG_INFO, LOC +
60  QString("Decoder %1 does not support device type %2.")
61  .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type)));
62  break;
63  }
64  if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
65  config->device_type == type) {
66  fmt = config->pix_fmt;
67  break;
68  }
69  }
70  }
71  if (fmt == AV_PIX_FMT_NONE)
72  return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1));
73  else
74  {
75  LOG(VB_PLAYBACK, LOG_INFO, LOC +
76  QString("Decoder %1 supports device type %2.")
77  .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type)));
78  pix_fmt = fmt;
79  return (MythCodecID)(kCodec_MPEG1_VAAPI2 + (stream_type - 1));
80  }
81 }
82 
83 // const char *filter_descr = "scale=78:24,transpose=cclock";
84 /* other way:
85  scale=78:24 [scl]; [scl] transpose=cclock // assumes "[in]" and "[out]" to be input output pads respectively
86  */
87 
88 int Vaapi2Context::HwDecoderInit(AVCodecContext *ctx)
89 {
90  int ret = 0;
91  AVBufferRef *hw_device_ctx = nullptr;
92 
93  const char *device = nullptr;
94  QString vaapiDevice = gCoreContext->GetSetting("VAAPIDevice");
95  if (!vaapiDevice.isEmpty())
96  {
97  device = vaapiDevice.toLocal8Bit().constData();
98  }
99 
100  ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
101  device, nullptr, 0);
102  if (ret < 0)
103  {
104  char error[AV_ERROR_MAX_STRING_SIZE];
105  LOG(VB_GENERAL, LOG_ERR, LOC +
106  QString("av_hwdevice_ctx_create Device = <%3> error: %1 (%2)")
107  .arg(av_make_error_string(error, sizeof(error), ret))
108  .arg(ret).arg(vaapiDevice));
109  }
110  else
111  {
112  ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
113  av_buffer_unref(&hw_device_ctx);
114  }
115 
116  return ret;
117 }
118 
120 {
121  // example filter - deinterlace_vaapi=mode=default:rate=frame:auto=1
122  // example deinterlacername - vaapi2doubleratemotion_compensated
123  QString ret;
124  QString rate="frame";
126  return ret;
127  QString filtername = deinterlacername;
128  filtername.remove(0,6); //remove "vaapi2"
129  if (filtername.startsWith("doublerate"))
130  {
131  rate="field";
132  filtername.remove(0,10); // remove "doublerate"
133  }
134  ret=QString("deinterlace_vaapi=mode=%1:rate=%2:auto=1")
135  .arg(filtername).arg(rate);
136 
137  return ret;
138 }
139 
140 bool Vaapi2Context::isValidDeinterlacer(QString filtername)
141 {
142  return filtername.startsWith("vaapi2");
143 }
144 
146 {
147  return MythCodecContext::GetDeinterlacers("vaapi2");
148 }
static MythCodecID GetBestSupportedCodec(AVCodec **ppCodec, const QString &decoder, uint stream_type, AVPixelFormat &pix_fmt)
#define LOC
MythCodecID
Definition: mythcodecid.h:10
static void error(const char *str,...)
Definition: vbi.c:41
unsigned int uint
Definition: compat.h:140
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetSetting(const QString &key, const QString &defaultval="")
int HwDecoderInit(AVCodecContext *ctx) override
bool isValidDeinterlacer(QString) override
QString GetDeinterlaceFilter(void) override
virtual QStringList GetDeinterlacers(void)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
QStringList GetDeinterlacers(void) override