Ticket #13357: 20181227_nvdec_decode_deint.patch
File 20181227_nvdec_decode_deint.patch, 48.4 KB (added by , 5 years ago) |
---|
-
mythtv/configure
diff --git a/mythtv/configure b/mythtv/configure index f6d86a7272e..8471c9bde57 100755
a b Advanced options (experts only): 135 135 --disable-crystalhd disable Broadcom CrystalHD hardware decoder support 136 136 --disable-vaapi disable VAAPI hardware accelerated video decoding 137 137 --disable-vaapi2 disable VAAPI2 hardware accelerated video decoding 138 --disable-nvdec disable NVDEC (CUVID) hardware accelerated video decoding 138 139 --disable-openmax disable OpenMAX hardware accelerated video decoding 139 140 --disable-dxva2 disable hardware accelerated decoding on windows 140 141 --disable-mediacodec disable hardware accelerated decoding on android … … EXTERNAL_LIBRARY_LIST=" 1397 1398 sdl2 1398 1399 vaapi 1399 1400 vaapi2 1401 nvdec 1400 1402 " 1401 1403 1402 1404 HWACCEL_AUTODETECT_LIBRARY_LIST=" … … USING_LIST=' 2041 2043 opengles 2042 2044 vaapi 2043 2045 vaapi2 2046 nvdec 2044 2047 vdpau 2045 2048 openmax 2046 2049 mediacodec … … enable lirc 2772 2775 enable mediacodec 2773 2776 enable vaapi 2774 2777 enable vaapi2 2778 enable nvdec 2775 2779 enable mheg 2776 2780 enable mythtranscode 2777 2781 enable opengl … … ffmpeg_optenable cross_compile libmp3lame libx264 libx265 libvpx libxvid 7159 7163 ffmpeg_optenable vdpau libxml2 libass dxva2 7160 7164 ffmpeg_optenable libbluray libfontconfig libfreetype libiec61883 7161 7165 ffmpeg_optenable crystalhd sdl2 ffplay 7166 ffmpeg_optenable nvdec 7167 7162 7168 if test $target_os = "android"; then 7163 7169 enabled mediacodec && enable jni 7164 7170 ffmpeg_optenable mediacodec jni … … if enabled x11 ; then 7376 7382 echo "VDPAU support ${vdpau-no}" 7377 7383 echo "VAAPI support ${vaapi-no}" 7378 7384 echo "VAAPI2 support ${vaapi2-no}" 7385 echo "NVDEC support ${nvdec-no}" 7379 7386 echo "CrystalHD support ${crystalhd-no}" 7380 7387 echo "OpenMAX support ${openmax-no}" 7381 7388 if enabled openmax ; then -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp index 4c37addfe6c..cfc57917529 100644
a b extern "C" { 73 73 #include "vaapi2context.h" 74 74 #endif 75 75 76 #ifdef USING_NVDEC 77 #include "nvdeccontext.h" 78 #endif 79 76 80 extern "C" { 77 81 #include "libavutil/avutil.h" 78 82 #include "libavutil/error.h" … … int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic, int flags); 189 193 #ifdef USING_VAAPI2 190 194 int get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic, int flags); 191 195 #endif 196 #ifdef USING_NVDEC 197 int get_avf_buffer_nvdec(struct AVCodecContext *c, AVFrame *pic, int flags); 198 #endif 192 199 193 200 static int determinable_frame_size(struct AVCodecContext *avctx) 194 201 { … … void AvFormatDecoder::GetDecoders(render_opts &opts) 396 403 opts.decoders->append("vaapi2"); 397 404 (*opts.equiv_decoders)["vaapi2"].append("dummy"); 398 405 #endif 406 #ifdef USING_NVDEC 407 opts.decoders->append("nvdec"); 408 (*opts.equiv_decoders)["nvdec"].append("dummy"); 409 #endif 399 410 #ifdef USING_MEDIACODEC 400 411 opts.decoders->append("mediacodec"); 401 412 (*opts.equiv_decoders)["mediacodec"].append("dummy"); … … static enum AVPixelFormat get_format_vaapi2(struct AVCodecContext */*avctx*/, 1581 1592 } 1582 1593 #endif 1583 1594 1595 #ifdef USING_NVDEC 1596 static enum AVPixelFormat get_format_nvdec(struct AVCodecContext */*avctx*/, 1597 const enum AVPixelFormat *valid_fmts) 1598 { 1599 enum AVPixelFormat ret = AV_PIX_FMT_NONE; 1600 while (*valid_fmts != AV_PIX_FMT_NONE) { 1601 if (AV_PIX_FMT_CUDA == *valid_fmts) 1602 { 1603 ret = *valid_fmts; 1604 break; 1605 } 1606 valid_fmts++; 1607 } 1608 return ret; 1609 } 1610 #endif 1611 1584 1612 #ifdef USING_MEDIACODEC 1585 1613 static enum AVPixelFormat get_format_mediacodec(struct AVCodecContext */*avctx*/, 1586 1614 const enum AVPixelFormat *valid_fmts) … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1687 1715 enc->get_format = get_format_vaapi2; 1688 1716 } 1689 1717 else 1718 #endif 1719 #ifdef USING_NVDEC 1720 if (codec_is_nvdec(video_codec_id)) 1721 { 1722 enc->get_buffer2 = get_avf_buffer_nvdec; 1723 enc->get_format = get_format_nvdec; 1724 directrendering = false; 1725 } 1726 else 1690 1727 #endif 1691 1728 if (codec1 && codec1->capabilities & AV_CODEC_CAP_DR1) 1692 1729 { … … int AvFormatDecoder::ScanStreams(bool novideo) 2500 2537 fps = 0; 2501 2538 if (!is_db_ignored) 2502 2539 { 2503 VideoDisplayProfile vdp;2504 v dp.SetInput(QSize(width, height),fps,codecName);2505 dec = v dp.GetDecoder();2506 thread_count = v dp.GetMaxCPUs();2507 bool skip_loop_filter = v dp.IsSkipLoopEnabled();2540 // VideoDisplayProfile vdp; 2541 videoDisplayProfile.SetInput(QSize(width, height),fps,codecName); 2542 dec = videoDisplayProfile.GetDecoder(); 2543 thread_count = videoDisplayProfile.GetMaxCPUs(); 2544 bool skip_loop_filter = videoDisplayProfile.IsSkipLoopEnabled(); 2508 2545 if (!skip_loop_filter) 2509 2546 { 2510 2547 enc->skip_loop_filter = AVDISCARD_NONKEY; … … int AvFormatDecoder::ScanStreams(bool novideo) 2622 2659 } 2623 2660 } 2624 2661 #endif // USING_VAAPI2 2662 #ifdef USING_NVDEC 2663 if (!foundgpudecoder) 2664 { 2665 MythCodecID nvdec_mcid; 2666 AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P; 2667 nvdec_mcid = NvdecContext::GetBestSupportedCodec( 2668 &codec, dec, mpeg_version(enc->codec_id), 2669 pix_fmt); 2670 2671 if (codec_is_nvdec(nvdec_mcid)) 2672 { 2673 gCodecMap->freeCodecContext(ic->streams[selTrack]); 2674 enc = gCodecMap->getCodecContext(ic->streams[selTrack], codec); 2675 video_codec_id = nvdec_mcid; 2676 foundgpudecoder = true; 2677 } 2678 } 2679 #endif // USING_NVDEC 2625 2680 } 2626 2681 // default to mpeg2 2627 2682 if (video_codec_id == kCodec_NONE) … … int AvFormatDecoder::ScanStreams(bool novideo) 2642 2697 && (codec_is_std(video_codec_id) 2643 2698 || codec_is_mediacodec(video_codec_id) 2644 2699 || codec_is_vaapi2(video_codec_id) 2700 || codec_is_nvdec(video_codec_id) 2645 2701 || GetCodecDecoderName() == "openmax")) 2646 2702 use_frame_timing = true; 2647 2703 … … void release_avf_buffer(void *opaque, uint8_t *data) 3015 3071 nd->GetPlayer()->DeLimboFrame(frame); 3016 3072 } 3017 3073 3018 #ifdef USING_VAAPI23019 3074 static void dummy_release_avf_buffer(void * /*opaque*/, uint8_t * /*data*/) 3020 3075 { 3021 3076 } 3022 #endif3023 3077 3024 3078 #ifdef USING_VDPAU 3025 3079 int get_avf_buffer_vdpau(struct AVCodecContext *c, AVFrame *pic, int /*flags*/) … … int get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic, int flags) 3156 3210 return avcodec_default_get_buffer2(c, pic, flags); 3157 3211 } 3158 3212 #endif 3213 #ifdef USING_NVDEC 3214 int get_avf_buffer_nvdec(struct AVCodecContext *c, AVFrame *pic, int flags) 3215 { 3216 AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque); 3217 nd->directrendering = false; 3218 return avcodec_default_get_buffer2(c, pic, flags); 3219 } 3220 #endif 3159 3221 3160 3222 void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len, bool scte) 3161 3223 { … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3951 4013 picframe = m_parent->GetNextVideoFrame(); 3952 4014 unsigned char *buf = picframe->buf; 3953 4015 bool used_picframe=false; 3954 #ifdef USING_VAAPI2 3955 if (IS_VAAPI_PIX_FMT((AVPixelFormat)mpa_pic->format)) 4016 #if defined(USING_VAAPI2) || defined(USING_NVDEC) 4017 if (AV_PIX_FMT_CUDA == (AVPixelFormat)mpa_pic->format 4018 || IS_VAAPI_PIX_FMT((AVPixelFormat)mpa_pic->format)) 3956 4019 { 3957 4020 int ret = 0; 3958 4021 tmp_frame = av_frame_alloc(); … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3997 4060 av_freep(&pixelformats); 3998 4061 } 3999 4062 else 4000 #endif // USING_VAAPI2 4063 #endif // USING_VAAPI2 || USING_NVDEC 4001 4064 use_frame = mpa_pic; 4002 4065 4003 4066 if (!used_picframe) -
mythtv/libs/libmythtv/avformatdecoder.h
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h index 9d8406d5ea6..8abe6b9510e 100644
a b class AvFormatDecoder : public DecoderBase 209 209 int flags); 210 210 friend int get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic, 211 211 int flags); 212 friend int get_avf_buffer_nvdec(struct AVCodecContext *c, AVFrame *pic, 213 int flags); 212 214 friend void release_avf_buffer(void *opaque, uint8_t *data); 213 215 214 216 friend int open_avf(URLContext *h, const char *filename, int flags); -
mythtv/libs/libmythtv/decoderbase.h
diff --git a/mythtv/libs/libmythtv/decoderbase.h b/mythtv/libs/libmythtv/decoderbase.h index 22bbd9fbae5..2ffaced66a8 100644
a b using namespace std; 12 12 #include "programinfo.h" 13 13 #include "mythcodecid.h" 14 14 #include "mythavutil.h" 15 #include "videodisplayprofile.h" 15 16 16 17 class RingBuffer; 17 18 class TeletextViewer; … … class DecoderBase 271 272 void TrackTotalDuration(bool track) { trackTotalDuration = track; } 272 273 int GetfpsMultiplier(void) { return fpsMultiplier; } 273 274 MythCodecContext *GetMythCodecContext(void) { return m_mythcodecctx; } 275 VideoDisplayProfile * GetVideoDisplayProfile(void) { return &videoDisplayProfile; } 274 276 275 277 protected: 276 278 virtual int AutoSelectTrack(uint type); … … class DecoderBase 361 363 /// language preferences for auto-selection of streams 362 364 vector<int> languagePreference; 363 365 MythCodecContext *m_mythcodecctx; 366 VideoDisplayProfile videoDisplayProfile; 364 367 }; 365 368 366 369 inline int DecoderBase::IncrementTrack(uint type) -
mythtv/libs/libmythtv/libmythtv.pro
diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro index b109a8be5fa..2fa383a1d17 100644
a b using_frontend { 513 513 SOURCES += vaapi2context.cpp 514 514 } 515 515 516 using_nvdec { 517 DEFINES += USING_NVDEC 518 HEADERS += nvdeccontext.h 519 SOURCES += nvdeccontext.cpp 520 } 521 516 522 using_mediacodec { 517 523 DEFINES += USING_MEDIACODEC 518 524 HEADERS += mediacodeccontext.h -
mythtv/libs/libmythtv/mythcodeccontext.cpp
diff --git a/mythtv/libs/libmythtv/mythcodeccontext.cpp b/mythtv/libs/libmythtv/mythcodeccontext.cpp index 7f007462033..32fc920afb3 100644
a b 30 30 #ifdef USING_VAAPI2 31 31 #include "vaapi2context.h" 32 32 #endif 33 #ifdef USING_NVDEC 34 #include "nvdeccontext.h" 35 #endif 33 36 34 37 extern "C" { 35 38 #include "libavutil/pixfmt.h" 36 39 #include "libavutil/hwcontext.h" 37 40 #include "libavcodec/avcodec.h" 38 #include "libavfilter/avfilter.h"41 // #include "libavfilter/avfilter.h" 39 42 #include "libavfilter/buffersink.h" 40 43 #include "libavfilter/buffersrc.h" 41 #include "libavformat/avformat.h"44 // #include "libavformat/avformat.h" 42 45 #include "libavutil/opt.h" 43 46 #include "libavutil/buffer.h" 44 47 } … … MythCodecContext::MythCodecContext() : 62 65 63 66 MythCodecContext::~MythCodecContext() 64 67 { 65 CloseFilters(); 68 66 69 } 67 70 68 71 // static … … MythCodecContext *MythCodecContext::createMythCodecContext(MythCodecID codec) 72 75 #ifdef USING_VAAPI2 73 76 if (codec_is_vaapi2(codec)) 74 77 mctx = new Vaapi2Context(); 75 #else76 Q_UNUSED(codec);77 78 #endif 79 #ifdef USING_NVDEC 80 if (codec_is_nvdec(codec)) 81 mctx = new NvdecContext(); 82 #endif 83 // In case neither was defined 84 Q_UNUSED(codec); 85 78 86 if (!mctx) 79 87 mctx = new MythCodecContext(); 80 88 return mctx; … … QStringList MythCodecContext::GetDeinterlacers(QString decodername) 115 123 1 = enabled 116 124 0 = disabled 117 125 */ 126 } 127 #endif 128 #ifdef USING_NVDEC 129 if (decodername == "nvdec") 130 { 131 ret.append("nvdecweave"); 132 ret.append("nvdecbob"); 133 ret.append("nvdecadaptive"); 134 ret.append("nvdecdoublerateweave"); 135 ret.append("nvdecdoubleratebob"); 136 ret.append("nvdecdoublerateadaptive"); 137 138 /* 139 Explanation of nvdec deinterlacing modes. 140 "weave", "Weave deinterlacing (do nothing)" 141 "bob", "Bob deinterlacing" 142 "adaptive", "Adaptive deinterlacing" 143 "drop_second_field", "Drop second field when deinterlacing" 144 */ 118 145 119 146 } 120 #else121 Q_UNUSED(decodername);122 147 #endif 148 // in case neither of the above was defined 149 Q_UNUSED(decodername); 123 150 return ret; 124 151 } 125 152 // static - Find if a deinterlacer is codec-provided 126 153 bool MythCodecContext::isCodecDeinterlacer(QString decodername) 127 154 { 128 return (decodername.startsWith("vaapi2")); 155 return (decodername.startsWith("vaapi2") 156 || decodername.startsWith("nvdec") ); 129 157 } 130 158 131 132 159 // Currently this will only set up the filter after an interlaced frame. 133 160 // If we need other filters apart from deinterlace filters we will 134 161 // need to make a change here. … … bool MythCodecContext::setDeinterlacer(bool enable, QString name) 230 257 { 231 258 if (deinterlacername.isEmpty()) 232 259 { 233 VideoOutput *vo= nullptr;234 VideoDisplayProfile *vd isp_profile= nullptr;260 DecoderBase *dec = nullptr; 261 VideoDisplayProfile *vdp = nullptr; 235 262 if (player) 236 vo = player->GetVideoOutput();237 if ( vo)238 vd isp_profile = vo->GetProfile();239 if (vd isp_profile)240 name = vd isp_profile->GetFilteredDeint(QString());263 dec = player->GetDecoder(); 264 if (dec) 265 vdp = dec->GetVideoDisplayProfile(); 266 if (vdp) 267 name = vdp->GetFilteredDeint(QString()); 241 268 } 242 269 else 243 270 name = deinterlacername; … … bool MythCodecContext::FallbackDeint(void) 273 300 QString MythCodecContext::GetFallbackDeint(void) 274 301 { 275 302 276 VideoOutput *vo= nullptr;277 VideoDisplayProfile *vd isp_profile= nullptr;303 DecoderBase *dec = nullptr; 304 VideoDisplayProfile *vdp = nullptr; 278 305 if (player) 279 vo = player->GetVideoOutput();280 if ( vo)281 vd isp_profile = vo->GetProfile();282 if (vd isp_profile)283 return vd isp_profile->GetFallbackDeinterlacer();306 dec = player->GetDecoder(); 307 if (dec) 308 vdp = dec->GetVideoDisplayProfile(); 309 if (vdp) 310 return vdp->GetFallbackDeinterlacer(); 284 311 return QString(); 285 312 } 286 313 287 int MythCodecContext::InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame) 314 // Dummy default method for those that do not use deinterlacers 315 316 int MythCodecContext::InitDeinterlaceFilter(AVCodecContext * /*ctx*/, AVFrame *frame) 288 317 { 289 318 QMutexLocker lock(&contextLock); 290 char args[512];291 int ret = 0;292 CloseFilters();293 319 width = frame->width; 294 320 height = frame->height; 295 321 filtersInitialized = true; 296 if (!player || !stream) 297 { 298 LOG(VB_GENERAL, LOG_ERR, LOC + "Player or stream is not set up in MythCodecContext"); 299 return -1; 300 } 301 if (doublerate && !player->CanSupportDoubleRate()) 302 { 303 QString request = deinterlacername; 304 deinterlacername = GetFallbackDeint(); 305 LOG(VB_PLAYBACK, LOG_INFO, LOC 306 + QString("Deinterlacer %1 requires double rate, switching to %2 instead.") 307 .arg(request).arg(deinterlacername)); 308 if (!isCodecDeinterlacer(deinterlacername)) 309 deinterlacername.clear(); 310 doublerate = deinterlacername.contains("doublerate"); 311 312 // if the fallback is a non-vaapi - deinterlace will be turned off 313 // and the videoout methods can take over. 314 } 315 QString filters; 316 if (isValidDeinterlacer(deinterlacername)) 317 filters = GetDeinterlaceFilter(); 318 319 if (filters.isEmpty()) 320 { 321 LOG(VB_GENERAL, LOG_INFO, LOC + 322 "Disabled hardware decoder based deinterlacer."); 323 return ret; 324 } 325 const AVFilter *buffersrc = avfilter_get_by_name("buffer"); 326 const AVFilter *buffersink = avfilter_get_by_name("buffersink"); 327 AVFilterInOut *outputs = avfilter_inout_alloc(); 328 AVFilterInOut *inputs = avfilter_inout_alloc(); 329 AVRational time_base = stream->time_base; 330 AVBufferSrcParameters* params = nullptr; 331 332 filter_graph = avfilter_graph_alloc(); 333 if (!outputs || !inputs || !filter_graph) 334 { 335 ret = AVERROR(ENOMEM); 336 goto end; 337 } 338 339 /* buffer video source: the decoded frames from the decoder will be inserted here. */ 340 snprintf(args, sizeof(args), 341 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", 342 frame->width, frame->height, frame->format, // ctx->pix_fmt, 343 time_base.num, time_base.den, 344 ctx->sample_aspect_ratio.num, ctx->sample_aspect_ratio.den); 345 346 // isInterlaced = frame->interlaced_frame; 347 348 ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", 349 args, nullptr, filter_graph); 350 if (ret < 0) 351 { 352 LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer source"); 353 goto end; 354 } 355 356 params = av_buffersrc_parameters_alloc(); 357 if (hw_frames_ctx) 358 av_buffer_unref(&hw_frames_ctx); 359 hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx); 360 params->hw_frames_ctx = hw_frames_ctx; 361 362 ret = av_buffersrc_parameters_set(buffersrc_ctx, params); 363 364 if (ret < 0) 365 { 366 LOG(VB_GENERAL, LOG_ERR, LOC + "av_buffersrc_parameters_set failed"); 367 goto end; 368 } 369 370 av_freep(¶ms); 371 372 /* buffer video sink: to terminate the filter chain. */ 373 ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", 374 nullptr, nullptr, filter_graph); 375 if (ret < 0) 376 { 377 LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer sink"); 378 goto end; 379 } 380 381 /* 382 * Set the endpoints for the filter graph. The filter_graph will 383 * be linked to the graph described by filters_descr. 384 */ 385 386 /* 387 * The buffer source output must be connected to the input pad of 388 * the first filter described by filters_descr; since the first 389 * filter input label is not specified, it is set to "in" by 390 * default. 391 */ 392 outputs->name = av_strdup("in"); 393 outputs->filter_ctx = buffersrc_ctx; 394 outputs->pad_idx = 0; 395 outputs->next = nullptr; 396 397 /* 398 * The buffer sink input must be connected to the output pad of 399 * the last filter described by filters_descr; since the last 400 * filter output label is not specified, it is set to "out" by 401 * default. 402 */ 403 inputs->name = av_strdup("out"); 404 inputs->filter_ctx = buffersink_ctx; 405 inputs->pad_idx = 0; 406 inputs->next = nullptr; 407 408 if ((ret = avfilter_graph_parse_ptr(filter_graph, filters.toLocal8Bit(), 409 &inputs, &outputs,nullptr)) < 0) 410 { 411 LOG(VB_GENERAL, LOG_ERR, LOC 412 + QString("avfilter_graph_parse_ptr failed for %1").arg(filters)); 413 goto end; 414 } 415 416 if ((ret = avfilter_graph_config(filter_graph, nullptr)) < 0) 417 { 418 LOG(VB_GENERAL, LOG_ERR, LOC 419 + QString("avfilter_graph_config failed")); 420 goto end; 421 } 422 423 LOG(VB_GENERAL, LOG_INFO, LOC + 424 QString("Enabled hardware decoder based deinterlace filter '%1': <%2>.") 425 .arg(deinterlacername).arg(filters)); 426 end: 427 if (ret < 0) 428 { 429 avfilter_graph_free(&filter_graph); 430 filter_graph = nullptr; 431 doublerate = false; 432 } 433 avfilter_inout_free(&inputs); 434 avfilter_inout_free(&outputs); 435 436 return ret; 437 } 438 439 void MythCodecContext::CloseFilters() 440 { 441 avfilter_graph_free(&filter_graph); 442 filter_graph = nullptr; 443 buffersink_ctx = nullptr; 444 buffersrc_ctx = nullptr; 445 filtersInitialized = false; 446 ptsUsed = 0; 447 priorPts[0] = 0; 448 priorPts[1] = 0; 449 // isInterlaced = 0; 450 width = 0; 451 height = 0; 452 453 if (hw_frames_ctx) 454 av_buffer_unref(&hw_frames_ctx); 322 return 0; 455 323 } -
mythtv/libs/libmythtv/mythcodeccontext.h
diff --git a/mythtv/libs/libmythtv/mythcodeccontext.h b/mythtv/libs/libmythtv/mythcodeccontext.h index 077a6de7192..0e5413e4811 100644
a b class MTV_PUBLIC MythCodecContext 61 61 62 62 protected: 63 63 virtual bool isValidDeinterlacer(QString /*name*/) { return false; } 64 int InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame); 65 void CloseFilters(); 64 virtual int InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame); 66 65 AVStream* stream; 67 66 AVFilterContext *buffersink_ctx; 68 67 AVFilterContext *buffersrc_ctx; -
mythtv/libs/libmythtv/mythcodecid.cpp
diff --git a/mythtv/libs/libmythtv/mythcodecid.cpp b/mythtv/libs/libmythtv/mythcodecid.cpp index cff4ba03585..aba6729194e 100644
a b QString toString(MythCodecID codecid) 144 144 case kCodec_HEVC_VAAPI2: 145 145 return "HEVC VAAPI2"; 146 146 147 case kCodec_MPEG1_NVDEC: 148 return "MPEG1 NVDEC"; 149 case kCodec_MPEG2_NVDEC: 150 return "MPEG2 NVDEC"; 151 case kCodec_H263_NVDEC: 152 return "H.263 NVDEC"; 153 case kCodec_MPEG4_NVDEC: 154 return "MPEG4 NVDEC"; 155 case kCodec_H264_NVDEC: 156 return "H.264 NVDEC"; 157 case kCodec_VC1_NVDEC: 158 return "VC1 NVDEC"; 159 case kCodec_WMV3_NVDEC: 160 return "WMV3 NVDEC"; 161 case kCodec_VP8_NVDEC: 162 return "VP8 NVDEC"; 163 case kCodec_VP9_NVDEC: 164 return "VP9 NVDEC"; 165 case kCodec_HEVC_NVDEC: 166 return "HEVC NVDEC"; 167 147 168 default: 148 169 break; 149 170 } … … int myth2av_codecid(MythCodecID codec_id, bool &vdpau) 357 378 ret = AV_CODEC_ID_HEVC; 358 379 break; 359 380 381 case kCodec_MPEG1_NVDEC: 382 ret = AV_CODEC_ID_MPEG1VIDEO; 383 break; 384 case kCodec_MPEG2_NVDEC: 385 ret = AV_CODEC_ID_MPEG2VIDEO; 386 break; 387 case kCodec_H263_NVDEC: 388 ret = AV_CODEC_ID_H263; 389 break; 390 case kCodec_MPEG4_NVDEC: 391 ret = AV_CODEC_ID_MPEG4; 392 break; 393 case kCodec_H264_NVDEC: 394 ret = AV_CODEC_ID_H264; 395 break; 396 case kCodec_VC1_NVDEC: 397 ret = AV_CODEC_ID_VC1; 398 break; 399 case kCodec_WMV3_NVDEC: 400 ret = AV_CODEC_ID_WMV3; 401 break; 402 case kCodec_VP8_NVDEC: 403 ret = AV_CODEC_ID_VP8; 404 break; 405 case kCodec_VP9_NVDEC: 406 ret = AV_CODEC_ID_VP9; 407 break; 408 case kCodec_HEVC_NVDEC: 409 ret = AV_CODEC_ID_HEVC; 410 break; 411 360 412 default: 361 413 LOG(VB_GENERAL, LOG_ERR, 362 414 QString("Error: MythCodecID %1 has not been " … … QString get_encoding_type(MythCodecID codecid) 409 461 case kCodec_MPEG1_DXVA2: 410 462 case kCodec_MPEG1_MEDIACODEC: 411 463 case kCodec_MPEG1_VAAPI2: 464 case kCodec_MPEG1_NVDEC: 412 465 case kCodec_MPEG2: 413 466 case kCodec_MPEG2_VDPAU: 414 467 case kCodec_MPEG2_VAAPI: 415 468 case kCodec_MPEG2_DXVA2: 416 469 case kCodec_MPEG2_MEDIACODEC: 417 470 case kCodec_MPEG2_VAAPI2: 471 case kCodec_MPEG2_NVDEC: 418 472 return "MPEG-2"; 419 473 420 474 case kCodec_H263: … … QString get_encoding_type(MythCodecID codecid) 423 477 case kCodec_H263_DXVA2: 424 478 case kCodec_H263_MEDIACODEC: 425 479 case kCodec_H263_VAAPI2: 480 case kCodec_H263_NVDEC: 426 481 return "H.263"; 427 482 428 483 case kCodec_NUV_MPEG4: … … QString get_encoding_type(MythCodecID codecid) 432 487 case kCodec_MPEG4_DXVA2: 433 488 case kCodec_MPEG4_MEDIACODEC: 434 489 case kCodec_MPEG4_VAAPI2: 490 case kCodec_MPEG4_NVDEC: 435 491 return "MPEG-4"; 436 492 437 493 case kCodec_H264: … … QString get_encoding_type(MythCodecID codecid) 440 496 case kCodec_H264_DXVA2: 441 497 case kCodec_H264_MEDIACODEC: 442 498 case kCodec_H264_VAAPI2: 499 case kCodec_H264_NVDEC: 443 500 return "H.264"; 444 501 445 502 case kCodec_VC1: … … QString get_encoding_type(MythCodecID codecid) 448 505 case kCodec_VC1_DXVA2: 449 506 case kCodec_VC1_MEDIACODEC: 450 507 case kCodec_VC1_VAAPI2: 508 case kCodec_VC1_NVDEC: 451 509 return "VC-1"; 452 510 453 511 case kCodec_WMV3: … … QString get_encoding_type(MythCodecID codecid) 456 514 case kCodec_WMV3_DXVA2: 457 515 case kCodec_WMV3_MEDIACODEC: 458 516 case kCodec_WMV3_VAAPI2: 517 case kCodec_WMV3_NVDEC: 459 518 return "WMV3"; 460 519 461 520 case kCodec_VP8: … … QString get_encoding_type(MythCodecID codecid) 464 523 case kCodec_VP8_DXVA2: 465 524 case kCodec_VP8_MEDIACODEC: 466 525 case kCodec_VP8_VAAPI2: 526 case kCodec_VP8_NVDEC: 467 527 return "VP8"; 468 528 469 529 case kCodec_VP9: … … QString get_encoding_type(MythCodecID codecid) 472 532 case kCodec_VP9_DXVA2: 473 533 case kCodec_VP9_MEDIACODEC: 474 534 case kCodec_VP9_VAAPI2: 535 case kCodec_VP9_NVDEC: 475 536 return "VP8"; 476 537 477 538 case kCodec_HEVC: … … QString get_encoding_type(MythCodecID codecid) 480 541 case kCodec_HEVC_DXVA2: 481 542 case kCodec_HEVC_MEDIACODEC: 482 543 case kCodec_HEVC_VAAPI2: 544 case kCodec_HEVC_NVDEC: 483 545 return "HEVC"; 484 546 485 547 case kCodec_NONE: … … QString get_encoding_type(MythCodecID codecid) 489 551 case kCodec_DXVA2_END: 490 552 case kCodec_MEDIACODEC_END: 491 553 case kCodec_VAAPI2_END: 554 case kCodec_NVDEC_END: 492 555 return QString(); 493 556 } 494 557 … … QString get_decoder_name(MythCodecID codec_id) 512 575 if (codec_is_vaapi2(codec_id)) 513 576 return "vaapi2"; 514 577 578 if (codec_is_nvdec(codec_id)) 579 return "nvdec"; 580 515 581 return "ffmpeg"; 516 582 } -
mythtv/libs/libmythtv/mythcodecid.h
diff --git a/mythtv/libs/libmythtv/mythcodecid.h b/mythtv/libs/libmythtv/mythcodecid.h index f1d225d4beb..a4796acd4c9 100644
a b typedef enum 106 106 107 107 kCodec_VAAPI2_END, 108 108 109 kCodec_NVDEC_BEGIN = kCodec_VAAPI2_END, 110 111 kCodec_MPEG1_NVDEC, 112 kCodec_MPEG2_NVDEC, 113 kCodec_H263_NVDEC, 114 kCodec_MPEG4_NVDEC, 115 kCodec_H264_NVDEC, 116 kCodec_VC1_NVDEC, 117 kCodec_WMV3_NVDEC, 118 kCodec_VP8_NVDEC, 119 kCodec_VP9_NVDEC, 120 kCodec_HEVC_NVDEC, 121 122 kCodec_NVDEC_END, 123 109 124 } MythCodecID; 110 125 111 126 // MythCodecID convenience functions … … typedef enum 130 145 (id < kCodec_MEDIACODEC_END)) 131 146 #define codec_is_vaapi2(id) ((id > kCodec_VAAPI2_BEGIN) && \ 132 147 (id < kCodec_VAAPI2_END)) 148 #define codec_is_nvdec(id) ((id > kCodec_NVDEC_BEGIN) && \ 149 (id < kCodec_NVDEC_END)) 133 150 134 #define codec_sw_copy(id) (codec_is_std(id) || codec_is_mediacodec(id) || codec_is_vaapi2(id)) 151 #define codec_sw_copy(id) (codec_is_std(id) || codec_is_mediacodec(id) \ 152 || codec_is_vaapi2(id || codec_is_nvdec(id))) 135 153 136 154 QString get_encoding_type(MythCodecID codecid); 137 155 QString get_decoder_name(MythCodecID codec_id); -
new file mythtv/libs/libmythtv/nvdeccontext.cpp
diff --git a/mythtv/libs/libmythtv/nvdeccontext.cpp b/mythtv/libs/libmythtv/nvdeccontext.cpp new file mode 100644 index 00000000000..810321c4b48
- + 1 ////////////////////////////////////////////////////////////////////////////// 2 // 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 // 23 ////////////////////////////////////////////////////////////////////////////// 24 25 #include "mythcorecontext.h" 26 #include "mythlogging.h" 27 #include "nvdeccontext.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 "libavutil/opt.h" 35 #include "libavcodec/avcodec.h" 36 } 37 38 #define LOC QString("NVDEC: ") 39 40 NvdecContext::NvdecContext() : 41 MythCodecContext() 42 { 43 44 } 45 46 MythCodecID NvdecContext::GetBestSupportedCodec( 47 AVCodec **ppCodec, 48 const QString &decoder, 49 uint stream_type, 50 AVPixelFormat &pix_fmt) 51 { 52 enum AVHWDeviceType type = AV_HWDEVICE_TYPE_CUDA; 53 54 AVPixelFormat fmt = AV_PIX_FMT_NONE; 55 if (decoder == "nvdec") 56 { 57 for (int i = 0;; i++) { 58 const AVCodecHWConfig *config = avcodec_get_hw_config(*ppCodec, i); 59 if (!config) 60 { 61 LOG(VB_PLAYBACK, LOG_INFO, LOC + 62 QString("Decoder %1 does not support device type %2.") 63 .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type))); 64 break; 65 } 66 if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && 67 config->device_type == type) 68 { 69 QString decodername = QString((*ppCodec)->name) + "_cuvid"; 70 if (decodername == "mpeg2video_cuvid") 71 decodername = "mpeg2_cuvid"; 72 AVCodec *newCodec = avcodec_find_decoder_by_name (decodername.toLocal8Bit()); 73 if (newCodec) 74 { 75 *ppCodec = newCodec; 76 fmt = config->pix_fmt; 77 } 78 else 79 LOG(VB_PLAYBACK, LOG_INFO, LOC + 80 QString("Decoder %1 does not exist.") 81 .arg(decodername)); 82 break; 83 } 84 } 85 } 86 if (fmt == AV_PIX_FMT_NONE) 87 return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1)); 88 else 89 { 90 LOG(VB_PLAYBACK, LOG_INFO, LOC + 91 QString("Decoder %1 supports device type %2.") 92 .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type))); 93 pix_fmt = fmt; 94 return (MythCodecID)(kCodec_MPEG1_NVDEC + (stream_type - 1)); 95 } 96 } 97 98 int NvdecContext::HwDecoderInit(AVCodecContext *ctx) 99 { 100 int ret = 0; 101 AVBufferRef *hw_device_ctx = nullptr; 102 103 const char *device = nullptr; 104 QString nvdecDevice = gCoreContext->GetSetting("NVDECDevice"); 105 if (!nvdecDevice.isEmpty()) 106 { 107 device = nvdecDevice.toLocal8Bit().constData(); 108 } 109 110 ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, 111 device, nullptr, 0); 112 if (ret < 0) 113 { 114 char error[AV_ERROR_MAX_STRING_SIZE]; 115 LOG(VB_GENERAL, LOG_ERR, LOC + 116 QString("av_hwdevice_ctx_create Device = <%3> error: %1 (%2)") 117 .arg(av_make_error_string(error, sizeof(error), ret)) 118 .arg(ret).arg(nvdecDevice)); 119 } 120 else 121 { 122 ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx); 123 av_buffer_unref(&hw_device_ctx); 124 } 125 126 SetDeinterlace(ctx); 127 128 return ret; 129 } 130 131 132 bool NvdecContext::isValidDeinterlacer(QString filtername) 133 { 134 return filtername.startsWith("nvdec"); 135 } 136 137 QStringList NvdecContext::GetDeinterlacers(void) 138 { 139 return MythCodecContext::GetDeinterlacers("nvdec"); 140 } 141 142 int NvdecContext::SetDeinterlace(AVCodecContext *ctx) 143 { 144 QMutexLocker lock(&contextLock); 145 bool dropSecondFld = false; 146 int ret = 0; 147 QString mode = GetDeinterlaceMode(dropSecondFld); 148 if (mode.isEmpty()) 149 { 150 ret = av_opt_set(ctx->priv_data,"deint","weave",0); 151 if (ret == 0) 152 LOG(VB_GENERAL, LOG_INFO, LOC + 153 "Disabled hardware decoder based deinterlacer."); 154 return ret; 155 } 156 ret = av_opt_set(ctx->priv_data,"deint",mode.toLocal8Bit(),0); 157 // ret = av_opt_set(ctx,"deint",mode.toLocal8Bit(),AV_OPT_SEARCH_CHILDREN); 158 if (ret == 0) 159 ret = av_opt_set_int(ctx->priv_data,"drop_second_field",(int)dropSecondFld,0); 160 // ret = av_opt_set_int(ctx,"drop_second_field",(int)dropSecondFld,AV_OPT_SEARCH_CHILDREN); 161 if (ret == 0) 162 LOG(VB_GENERAL, LOG_INFO, LOC + 163 QString("Enabled hardware decoder based deinterlace '%1' mode: <%2>.") 164 .arg(deinterlacername).arg(mode)); 165 166 return ret; 167 } 168 169 QString NvdecContext::GetDeinterlaceMode(bool &dropSecondFld) 170 { 171 // example mode - weave 172 // example deinterlacername - nvdecdoublerateweave 173 174 dropSecondFld=true; 175 QString mode; 176 if (!isValidDeinterlacer(deinterlacername)) 177 return mode; 178 mode = deinterlacername; 179 mode.remove(0,5); //remove "nvdec" 180 if (mode.startsWith("doublerate")) 181 { 182 dropSecondFld=false; 183 mode.remove(0,10); // remove "doublerate" 184 } 185 return mode; 186 } -
new file mythtv/libs/libmythtv/nvdeccontext.h
diff --git a/mythtv/libs/libmythtv/nvdeccontext.h b/mythtv/libs/libmythtv/nvdeccontext.h new file mode 100644 index 00000000000..98aa055c974
- + 1 ////////////////////////////////////////////////////////////////////////////// 2 // 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 // 23 ////////////////////////////////////////////////////////////////////////////// 24 25 26 #ifndef NVDECCONTEXT_H 27 #define NVDECCONTEXT_H 28 29 #include "mythtvexp.h" 30 #include "mythcodecid.h" 31 #include "mythcodeccontext.h" 32 33 extern "C" { 34 #include "libavcodec/avcodec.h" 35 } 36 37 class MTV_PUBLIC NvdecContext : public MythCodecContext 38 { 39 public: 40 NvdecContext(void); 41 static MythCodecID GetBestSupportedCodec(AVCodec **ppCodec, 42 const QString &decoder, 43 uint stream_type, 44 AVPixelFormat &pix_fmt); 45 int HwDecoderInit(AVCodecContext *ctx) override; // MythCodecContext 46 bool isValidDeinterlacer(QString /*name*/ ) override; // MythCodecContext 47 QStringList GetDeinterlacers(void) override; // MythCodecContext 48 49 protected: 50 int SetDeinterlace(AVCodecContext *ctx); 51 QString GetDeinterlaceMode(bool &dropSecondFld); 52 53 54 }; 55 56 #endif // NVDECCONTEXT_H -
mythtv/libs/libmythtv/vaapi2context.cpp
diff --git a/mythtv/libs/libmythtv/vaapi2context.cpp b/mythtv/libs/libmythtv/vaapi2context.cpp index 09ac0579e9e..2b972462ed3 100644
a b extern "C" { 32 32 #include "libavutil/pixfmt.h" 33 33 #include "libavutil/hwcontext.h" 34 34 #include "libavcodec/avcodec.h" 35 #include "libavfilter/avfilter.h" 36 #include "libavformat/avformat.h" 37 #include "libavfilter/buffersrc.h" 35 38 } 36 39 37 40 #define LOC QString("VAAPI2: ") … … Vaapi2Context::Vaapi2Context() : 42 45 43 46 } 44 47 48 Vaapi2Context::~Vaapi2Context() 49 { 50 CloseFilters(); 51 } 52 53 45 54 MythCodecID Vaapi2Context::GetBestSupportedCodec( 46 55 AVCodec **ppCodec, 47 56 const QString &decoder, … … QStringList Vaapi2Context::GetDeinterlacers(void) 146 155 { 147 156 return MythCodecContext::GetDeinterlacers("vaapi2"); 148 157 } 158 159 160 int Vaapi2Context::InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame) 161 { 162 QMutexLocker lock(&contextLock); 163 char args[512]; 164 int ret = 0; 165 CloseFilters(); 166 width = frame->width; 167 height = frame->height; 168 filtersInitialized = true; 169 if (!player || !stream) 170 { 171 LOG(VB_GENERAL, LOG_ERR, LOC + "Player or stream is not set up in MythCodecContext"); 172 return -1; 173 } 174 if (doublerate && !player->CanSupportDoubleRate()) 175 { 176 QString request = deinterlacername; 177 deinterlacername = GetFallbackDeint(); 178 LOG(VB_PLAYBACK, LOG_INFO, LOC 179 + QString("Deinterlacer %1 requires double rate, switching to %2 instead.") 180 .arg(request).arg(deinterlacername)); 181 if (!isCodecDeinterlacer(deinterlacername)) 182 deinterlacername.clear(); 183 doublerate = deinterlacername.contains("doublerate"); 184 185 // if the fallback is a non-vaapi - deinterlace will be turned off 186 // and the videoout methods can take over. 187 } 188 QString filters; 189 if (isValidDeinterlacer(deinterlacername)) 190 filters = GetDeinterlaceFilter(); 191 192 if (filters.isEmpty()) 193 { 194 LOG(VB_GENERAL, LOG_INFO, LOC + 195 "Disabled hardware decoder based deinterlacer."); 196 return ret; 197 } 198 const AVFilter *buffersrc = avfilter_get_by_name("buffer"); 199 const AVFilter *buffersink = avfilter_get_by_name("buffersink"); 200 AVFilterInOut *outputs = avfilter_inout_alloc(); 201 AVFilterInOut *inputs = avfilter_inout_alloc(); 202 AVRational time_base = stream->time_base; 203 AVBufferSrcParameters* params = nullptr; 204 205 filter_graph = avfilter_graph_alloc(); 206 if (!outputs || !inputs || !filter_graph) 207 { 208 ret = AVERROR(ENOMEM); 209 goto end; 210 } 211 212 /* buffer video source: the decoded frames from the decoder will be inserted here. */ 213 snprintf(args, sizeof(args), 214 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", 215 frame->width, frame->height, frame->format, // ctx->pix_fmt, 216 time_base.num, time_base.den, 217 ctx->sample_aspect_ratio.num, ctx->sample_aspect_ratio.den); 218 219 // isInterlaced = frame->interlaced_frame; 220 221 ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", 222 args, nullptr, filter_graph); 223 if (ret < 0) 224 { 225 LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer source"); 226 goto end; 227 } 228 229 params = av_buffersrc_parameters_alloc(); 230 if (hw_frames_ctx) 231 av_buffer_unref(&hw_frames_ctx); 232 hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx); 233 params->hw_frames_ctx = hw_frames_ctx; 234 235 ret = av_buffersrc_parameters_set(buffersrc_ctx, params); 236 237 if (ret < 0) 238 { 239 LOG(VB_GENERAL, LOG_ERR, LOC + "av_buffersrc_parameters_set failed"); 240 goto end; 241 } 242 243 av_freep(¶ms); 244 245 /* buffer video sink: to terminate the filter chain. */ 246 ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", 247 nullptr, nullptr, filter_graph); 248 if (ret < 0) 249 { 250 LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer sink"); 251 goto end; 252 } 253 254 /* 255 * Set the endpoints for the filter graph. The filter_graph will 256 * be linked to the graph described by filters_descr. 257 */ 258 259 /* 260 * The buffer source output must be connected to the input pad of 261 * the first filter described by filters_descr; since the first 262 * filter input label is not specified, it is set to "in" by 263 * default. 264 */ 265 outputs->name = av_strdup("in"); 266 outputs->filter_ctx = buffersrc_ctx; 267 outputs->pad_idx = 0; 268 outputs->next = nullptr; 269 270 /* 271 * The buffer sink input must be connected to the output pad of 272 * the last filter described by filters_descr; since the last 273 * filter output label is not specified, it is set to "out" by 274 * default. 275 */ 276 inputs->name = av_strdup("out"); 277 inputs->filter_ctx = buffersink_ctx; 278 inputs->pad_idx = 0; 279 inputs->next = nullptr; 280 281 if ((ret = avfilter_graph_parse_ptr(filter_graph, filters.toLocal8Bit(), 282 &inputs, &outputs,nullptr)) < 0) 283 { 284 LOG(VB_GENERAL, LOG_ERR, LOC 285 + QString("avfilter_graph_parse_ptr failed for %1").arg(filters)); 286 goto end; 287 } 288 289 if ((ret = avfilter_graph_config(filter_graph, nullptr)) < 0) 290 { 291 LOG(VB_GENERAL, LOG_ERR, LOC 292 + QString("avfilter_graph_config failed")); 293 goto end; 294 } 295 296 LOG(VB_GENERAL, LOG_INFO, LOC + 297 QString("Enabled hardware decoder based deinterlace filter '%1': <%2>.") 298 .arg(deinterlacername).arg(filters)); 299 end: 300 if (ret < 0) 301 { 302 avfilter_graph_free(&filter_graph); 303 filter_graph = nullptr; 304 doublerate = false; 305 } 306 avfilter_inout_free(&inputs); 307 avfilter_inout_free(&outputs); 308 309 return ret; 310 } 311 312 void Vaapi2Context::CloseFilters() 313 { 314 avfilter_graph_free(&filter_graph); 315 filter_graph = nullptr; 316 buffersink_ctx = nullptr; 317 buffersrc_ctx = nullptr; 318 filtersInitialized = false; 319 ptsUsed = 0; 320 priorPts[0] = 0; 321 priorPts[1] = 0; 322 // isInterlaced = 0; 323 width = 0; 324 height = 0; 325 326 if (hw_frames_ctx) 327 av_buffer_unref(&hw_frames_ctx); 328 } -
mythtv/libs/libmythtv/vaapi2context.h
diff --git a/mythtv/libs/libmythtv/vaapi2context.h b/mythtv/libs/libmythtv/vaapi2context.h index 528fd9f8872..76fd05c4741 100644
a b class MTV_PUBLIC Vaapi2Context : public MythCodecContext 38 38 { 39 39 public: 40 40 Vaapi2Context(void); 41 ~Vaapi2Context(); 41 42 static MythCodecID GetBestSupportedCodec(AVCodec **ppCodec, 42 43 const QString &decoder, 43 44 uint stream_type, … … class MTV_PUBLIC Vaapi2Context : public MythCodecContext 47 48 bool isValidDeinterlacer(QString /*name*/ ) override; // MythCodecContext 48 49 QStringList GetDeinterlacers(void) override; // MythCodecContext 49 50 51 protected: 52 int InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame) override; // MythCodecContext 53 void CloseFilters(); 54 50 55 }; 51 56 52 57 #endif // VAAPI2CONTEXT_H -
mythtv/libs/libmythtv/videodisplayprofile.cpp
diff --git a/mythtv/libs/libmythtv/videodisplayprofile.cpp b/mythtv/libs/libmythtv/videodisplayprofile.cpp index 02c2e052826..b3ea9cda490 100644
a b QString VideoDisplayProfile::GetDecoderName(const QString &decoder) 845 845 dec_name["vda"] = QObject::tr("Mac VDA hardware acceleration"); 846 846 dec_name["mediacodec"] = QObject::tr("Android MediaCodec decoder"); 847 847 dec_name["vaapi2"] = QObject::tr("VAAPI2 acceleration"); 848 dec_name["nvdec"] = QObject::tr("NVidia NVDEC acceleration"); 848 849 } 849 850 850 851 QString ret = decoder; … … QString VideoDisplayProfile::GetDecoderHelp(QString decoder) 909 910 "VAAPI2 is a new implementation of VAAPI to will use the graphics hardware to " 910 911 "accelerate video decoding on Intel CPUs. "); 911 912 913 if (decoder == "nvdec") 914 msg += QObject::tr( 915 "Nvdec uses the new NVDEC API to " 916 "accelerate video decoding on NVidia Graphics Adapters. "); 917 912 918 return msg; 913 919 } 914 920 … … QString VideoDisplayProfile::GetDeinterlacerName(const QString &short_name) 996 1002 else if ("vaapi2doubleratemotion_compensated" == short_name) 997 1003 return QObject::tr("Motion Compensated (2x, HW-VA)"); 998 1004 #endif 1005 #ifdef USING_NVDEC 1006 else if ("nvdecweave" == short_name) 1007 return QObject::tr("Weave (HW-NV)"); 1008 else if ("nvdecbob" == short_name) 1009 return QObject::tr("Bob (HW-NV)"); 1010 else if ("nvdecadaptive" == short_name) 1011 return QObject::tr("Adaptive (HW-NV)"); 1012 else if ("nvdecdoublerateweave" == short_name) 1013 return QObject::tr("Weave (2x, HW-NV)"); 1014 else if ("nvdecdoubleratebob" == short_name) 1015 return QObject::tr("Bob (2x, HW-NV)"); 1016 else if ("nvdecdoublerateadaptive" == short_name) 1017 return QObject::tr("Adaptive (2x, HW-NV)"); 1018 #endif // USING_NVDEC 999 1019 1000 1020 return ""; 1001 1021 } … … void VideoDisplayProfile::CreateProfiles(const QString &hostname) 1504 1524 } 1505 1525 #endif 1506 1526 1527 #if defined(USING_NVDEC) && defined(USING_OPENGL_VIDEO) 1528 if (!profiles.contains("NVDEC Normal")) { 1529 (void) QObject::tr("NVDEC Normal", 1530 "Sample: NVDEC Normal"); 1531 groupid = CreateProfileGroup("NVDEC Normal", hostname); 1532 CreateProfile(groupid, 1, "", "", "", 1533 "nvdec", 4, true, "opengl", 1534 "opengl2", true, 1535 "nvdecdoublerateadaptive", "nvdecadaptive", 1536 ""); 1537 } 1538 #endif 1539 1507 1540 } 1508 1541 1509 1542 QStringList VideoDisplayProfile::GetVideoRenderers(const QString &decoder) … … QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 1644 1677 1645 1678 QString kUsingVA = QObject::tr("(VAAPI Hardware Accelerated)"); 1646 1679 1680 QString kUsingNV = QObject::tr("(NVDEC Hardware Accelerated)"); 1681 1647 1682 QString kUsingGL = QObject::tr("(OpenGL Hardware Accelerated)"); 1648 1683 1649 1684 QString kGreedyHMsg = QObject::tr( … … QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 1751 1786 msg = kMAMsg + " " + kDoubleRateMsg + " " + kUsingVA; 1752 1787 else if (deint == "vaapi2doubleratemotion_compensated") 1753 1788 msg = kMCMsg + " " + kDoubleRateMsg + " " + kUsingVA; 1789 1790 else if (deint == "nvdecweave") 1791 msg = kWeaveMsg + " " + kUsingNV; 1792 else if (deint == "nvdecbob") 1793 msg = kBobMsg + " " + kUsingNV; 1794 else if (deint == "nvdecadaptive") 1795 msg = kMAMsg + " " + kUsingNV; 1796 else if (deint == "nvdecdoublerateweave") 1797 msg = kWeaveMsg + " " + kDoubleRateMsg + " " + kUsingNV; 1798 else if (deint == "nvdecdoubleratebob") 1799 msg = kBobMsg + " " + kDoubleRateMsg + " " + kUsingNV; 1800 else if (deint == "nvdecdoublerateadaptive") 1801 msg = kMAMsg + " " + kDoubleRateMsg + " " + kUsingNV; 1754 1802 else 1755 1803 msg = QObject::tr("'%1' has not been documented yet.").arg(deint); 1756 1804 -
mythtv/libs/libmythtv/videoout_opengl.cpp
diff --git a/mythtv/libs/libmythtv/videoout_opengl.cpp b/mythtv/libs/libmythtv/videoout_opengl.cpp index 166af8ac061..2a69628f8b2 100644
a b void VideoOutputOpenGL::GetRenderOptions(render_opts &opts, 46 46 } 47 47 if (opts.decoders->contains("vaapi2")) 48 48 (*opts.safe_renderers)["vaapi2"].append("opengl"); 49 if (opts.decoders->contains("nvdec")) 50 (*opts.safe_renderers)["nvdec"].append("opengl"); 49 51 opts.priorities->insert("opengl", 65); 50 52 51 53 // lite profile - no colourspace control, GPU deinterlacing … … bool VideoOutputOpenGL::InputChanged(const QSize &video_dim_buf, 278 280 279 281 if (!codec_is_std(av_codec_id) 280 282 && !codec_is_mediacodec(av_codec_id) 281 && !codec_is_vaapi2(av_codec_id)) 283 && !codec_is_vaapi2(av_codec_id) 284 && !codec_is_nvdec(av_codec_id)) 282 285 { 283 286 LOG(VB_GENERAL, LOG_ERR, LOC + "New video codec is not supported."); 284 287 errorState = kError_Unknown; … … QStringList VideoOutputOpenGL::GetAllowedRenderers( 749 752 { 750 753 list << "opengl" << "opengl-lite"; 751 754 } 752 else if ((codec_is_mediacodec(myth_codec_id) || codec_is_vaapi2(myth_codec_id)) 755 else if ((codec_is_mediacodec(myth_codec_id) 756 || codec_is_vaapi2(myth_codec_id) 757 || codec_is_nvdec(myth_codec_id)) 753 758 && !getenv("NO_OPENGL")) 754 759 { 755 760 list << "opengl";