Ticket #13233: 20180716_1139_smoooooth.patch
File 20180716_1139_smoooooth.patch, 49.8 KB (added by , 6 years ago) |
---|
-
mythtv/configure
diff --git a/mythtv/configure b/mythtv/configure index 32e0098b9f3..4d9c025e3b4 100755
a b Advanced options (experts only): 135 135 --disable-vaapi disable VAAPI hardware accelerated video decoding 136 136 --disable-openmax disable OpenMAX hardware accelerated video decoding 137 137 --disable-dxva2 disable hardware accelerated decoding on windows 138 --disable-mediacodec disable hardware accelerated decoding on android 138 139 --disable-opengl-video disable OpenGL based video display 139 140 --disable-opengl-themepainter disable OpenGL based theme painting 140 141 --disable-libass disable libass SSA/ASS subtitle support … … USING_LIST=' 2038 2039 vaapi 2039 2040 vdpau 2040 2041 openmax 2042 mediacodec 2041 2043 ' 2042 2044 2043 2045 CMDLINE_SELECT=" … … enable libcrypto 2763 2765 enable libdns_sd 2764 2766 enable libxml2 2765 2767 enable lirc 2768 enable mediacodec 2766 2769 enable mheg 2767 2770 enable mythtranscode 2768 2771 enable opengl … … ffmpeg_optset extra_cxxflags extra_ldflags target_os 6971 6974 ffmpeg_optset pkg_config prefix libdir as objcc dep_cc host_cc 6972 6975 ffmpeg_optset host_ld 6973 6976 ffmpeg_optenable cross_compile libmp3lame libx264 libx265 libvpx libxvid 6974 ffmpeg_optenable vdpau vaapi libxml2 libass dxva2 mediacodec6975 ffmpeg_optenable jnilibbluray libfontconfig libfreetype libiec618836977 ffmpeg_optenable vdpau vaapi libxml2 libass dxva2 6978 ffmpeg_optenable libbluray libfontconfig libfreetype libiec61883 6976 6979 ffmpeg_optenable crystalhd sdl2 ffplay 6980 if test $target_os = "android"; then 6981 enabled mediacodec && enable jni 6982 ffmpeg_optenable mediacodec jni 6983 else 6984 disable mediacodec 6985 fi 6986 6977 6987 ffmpeg_extra_cflags="$extra_cflags -w" 6978 6988 6979 6989 ## Call FFmpeg configure here -
mythtv/external/FFmpeg/libavcodec/mediacodec_sw_buffer.c
diff --git a/mythtv/external/FFmpeg/libavcodec/mediacodec_sw_buffer.c b/mythtv/external/FFmpeg/libavcodec/mediacodec_sw_buffer.c index 92428e85f02..30a53f05b36 100644
a b void ff_mediacodec_sw_buffer_copy_yuv420_semi_planar(AVCodecContext *avctx, 150 150 } else if (i == 1) { 151 151 height = avctx->height / 2; 152 152 153 src += s-> slice_height * s->stride;153 src += s->height * s->stride; 154 154 src += s->crop_top * s->stride; 155 155 src += s->crop_left; 156 156 } -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp index 2c3a1985a05..a592bafdb4e 100644
a b extern "C" { 62 62 #include "vaapicontext.h" 63 63 #endif 64 64 65 #ifdef USING_MEDIACODEC 66 #include "mediacodeccontext.h" 67 extern "C" { 68 #include "libavcodec/jni.h" 69 } 70 #include <QtAndroidExtras> 71 #endif 72 65 73 extern "C" { 66 74 #include "libavutil/avutil.h" 67 75 #include "libavutil/error.h" … … static void myth_av_log(void *ptr, int level, const char* fmt, va_list vl) 276 284 static QString full_line(""); 277 285 static const int msg_len = 255; 278 286 static QMutex string_lock; 279 uint64_t verbose_mask = VB_ GENERAL;280 LogLevel_t verbose_level = LOG_ DEBUG;287 uint64_t verbose_mask = VB_LIBAV; 288 LogLevel_t verbose_level = LOG_EMERG; 281 289 282 290 // determine mythtv debug level from av log level 283 291 switch (level) 284 292 { 285 293 case AV_LOG_PANIC: 286 294 verbose_level = LOG_EMERG; 295 verbose_mask |= VB_GENERAL; 287 296 break; 288 297 case AV_LOG_FATAL: 289 298 verbose_level = LOG_CRIT; 299 verbose_mask |= VB_GENERAL; 290 300 break; 291 301 case AV_LOG_ERROR: 292 302 verbose_level = LOG_ERR; 293 verbose_mask |= VB_LIBAV;294 303 break; 295 case AV_LOG_DEBUG: 296 case AV_LOG_VERBOSE: 304 case AV_LOG_WARNING: 305 verbose_level = LOG_WARNING; 306 break; 297 307 case AV_LOG_INFO: 298 verbose_level = LOG_DEBUG; 299 verbose_mask |= VB_LIBAV; 308 verbose_level = LOG_INFO; 300 309 break; 301 case AV_LOG_WARNING: 302 verbose_mask |= VB_LIBAV; 310 case AV_LOG_VERBOSE: 311 case AV_LOG_DEBUG: 312 case AV_LOG_TRACE: 313 verbose_level = LOG_DEBUG; 303 314 break; 304 315 default: 305 316 return; … … void AvFormatDecoder::GetDecoders(render_opts &opts) 374 385 opts.decoders->append("vaapi"); 375 386 (*opts.equiv_decoders)["vaapi"].append("dummy"); 376 387 #endif 388 #ifdef USING_MEDIACODEC 389 opts.decoders->append("mediacodec"); 390 (*opts.equiv_decoders)["mediacodec"].append("dummy"); 391 #endif 377 392 378 393 PrivateDecoder::GetDecoders(opts); 379 394 } … … AvFormatDecoder::AvFormatDecoder(MythPlayer *parent, 405 420 pts_detected(false), 406 421 reordered_pts_detected(false), 407 422 pts_selected(true), 423 use_frame_timing(false), 424 flush_discard(0), 408 425 force_dts_timestamps(false), 409 426 playerFlags(flags), 410 427 video_codec_id(kCodec_NONE), … … AvFormatDecoder::AvFormatDecoder(MythPlayer *parent, 433 450 audioSamples = (uint8_t *)av_mallocz(AudioOutput::MAX_SIZE_BUFFER); 434 451 ccd608->SetIgnoreTimecode(true); 435 452 436 bool debug = VERBOSE_LEVEL_CHECK(VB_LIBAV, LOG_ANY);437 av_log_set_level((debug) ? AV_LOG_DEBUG : AV_LOG_ERROR);438 453 av_log_set_callback(myth_av_log); 439 454 440 455 audioIn.sample_size = -32; // force SetupAudioStream to run once … … bool AvFormatDecoder::DoFastForward(long long desiredFrame, bool discardFrames) 742 757 743 758 lastKey = (long long)((newts*(long double)fps)/AV_TIME_BASE); 744 759 framesPlayed = lastKey; 760 fpsSkip = 0; 745 761 framesRead = lastKey; 746 762 747 763 normalframes = (exactseeks) ? desiredFrame - framesPlayed : 0; … … bool AvFormatDecoder::DoFastForward(long long desiredFrame, bool discardFrames) 753 769 LOG(VB_GENERAL, LOG_INFO, LOC + "No DTS Seeking Hack!"); 754 770 no_dts_hack = true; 755 771 framesPlayed = desiredFrame; 772 fpsSkip = 0; 756 773 framesRead = desiredFrame; 757 774 normalframes = 0; 758 775 } … … void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames, 817 834 // enc->internal = NULL and cause a segfault in 818 835 // avcodec_flush_buffers 819 836 if (enc && enc->internal) 837 { 820 838 avcodec_flush_buffers(enc); 839 if (fpsMultiplier > 1) 840 flush_discard = 4; 841 } 821 842 } 822 843 if (private_dec) 823 844 private_dec->Reset(); … … void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames, 844 865 if (!no_dts_hack) 845 866 { 846 867 framesPlayed = lastKey; 868 fpsSkip = 0; 847 869 framesRead = lastKey; 848 870 } 849 871 … … extern "C" void HandleStreamChange(void *data) 1004 1026 int AvFormatDecoder::FindStreamInfo(void) 1005 1027 { 1006 1028 QMutexLocker lock(avcodeclock); 1007 // Suppress ffmpeg logging unless "-v libav --loglevel debug"1008 if (!VERBOSE_LEVEL_CHECK(VB_LIBAV, LOG_DEBUG))1009 silence_ffmpeg_logging = true;1010 1029 int retval = avformat_find_stream_info(ic, NULL); 1011 1030 silence_ffmpeg_logging = false; 1012 1031 // ffmpeg 3.0 is returning -1 code when there is a channel … … enum AVPixelFormat get_format_vaapi(struct AVCodecContext *avctx, 1540 1559 } 1541 1560 #endif 1542 1561 1562 #ifdef USING_MEDIACODEC 1563 static enum AVPixelFormat get_format_mediacodec(struct AVCodecContext *avctx, 1564 const enum AVPixelFormat *valid_fmts) 1565 { 1566 enum AVPixelFormat ret = *valid_fmts; // default to first 1567 while (*valid_fmts != AV_PIX_FMT_NONE) { 1568 if (*valid_fmts == AV_PIX_FMT_YUV420P) 1569 ret = AV_PIX_FMT_YUV420P; 1570 valid_fmts++; 1571 } 1572 return ret; 1573 } 1574 #endif 1575 1576 1543 1577 static bool IS_DR1_PIX_FMT(const enum AVPixelFormat fmt) 1544 1578 { 1545 1579 switch (fmt) … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1575 1609 enc->debug = 0; 1576 1610 // enc->error_rate = 0; 1577 1611 1578 AVCodec *codec = avcodec_find_decoder(enc->codec_id);1612 const AVCodec *codec = enc->codec; 1579 1613 1580 1614 if (selectedStream) 1581 1615 { … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1612 1646 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1613 1647 } 1614 1648 else 1649 #endif 1650 #ifdef USING_MEDIACODEC 1651 if (CODEC_IS_MEDIACODEC(codec)) 1652 { 1653 enc->get_format = get_format_mediacodec; 1654 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1655 } 1656 else 1615 1657 #endif 1616 1658 if (codec && codec->capabilities & AV_CODEC_CAP_DR1) 1617 1659 { … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1679 1721 } 1680 1722 1681 1723 m_parent->SetKeyframeDistance(keyframedist); 1682 AVCodec *codec = avcodec_find_decoder(enc->codec_id);1724 const AVCodec *codec = enc->codec; 1683 1725 QString codecName; 1684 1726 if (codec) 1685 1727 codecName = codec->name; … … int AvFormatDecoder::ScanStreams(bool novideo) 2368 2410 2369 2411 if (averror_count > SEQ_PKT_ERR_MAX) 2370 2412 gCodecMap->freeCodecContext(ic->streams[selTrack]); 2371 AVCodecContext *enc = gCodecMap->getCodecContext(ic->streams[selTrack] );2413 AVCodecContext *enc = gCodecMap->getCodecContext(ic->streams[selTrack], codec); 2372 2414 StreamInfo si(selTrack, 0, 0, 0, 0); 2373 2415 2374 2416 tracks[kTrackTypeVideo].push_back(si); … … int AvFormatDecoder::ScanStreams(bool novideo) 2393 2435 uint height = max(dim.height(), 16); 2394 2436 QString dec = "ffmpeg"; 2395 2437 uint thread_count = 1; 2396 AVCodec *codec1 = avcodec_find_decoder(enc->codec_id);2397 2438 QString codecName; 2398 if ( codec1)2399 codecName = codec1->name;2439 if (enc->codec) 2440 codecName = enc->codec->name; 2400 2441 if (enc->framerate.den && enc->framerate.num) 2401 2442 fps = float(enc->framerate.num) / float(enc->framerate.den); 2402 2443 else … … int AvFormatDecoder::ScanStreams(bool novideo) 2473 2514 } 2474 2515 #endif // USING_GLVAAPI 2475 2516 #ifdef USING_DXVA2 2476 if (!foundgpudecode )2517 if (!foundgpudecoder) 2477 2518 { 2478 2519 MythCodecID dxva2_mcid; 2479 2520 AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P; … … int AvFormatDecoder::ScanStreams(bool novideo) 2489 2530 } 2490 2531 } 2491 2532 #endif // USING_DXVA2 2492 if (foundgpudecoder) 2533 #ifdef USING_MEDIACODEC 2534 if (!foundgpudecoder) 2493 2535 { 2494 enc->codec_id = (AVCodecID) myth2av_codecid(video_codec_id); 2536 MythCodecID mediacodec_mcid; 2537 AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P; 2538 mediacodec_mcid = MediaCodecContext::GetBestSupportedCodec( 2539 &codec, dec, mpeg_version(enc->codec_id), 2540 pix_fmt); 2541 2542 if (codec_is_mediacodec(mediacodec_mcid)) 2543 { 2544 gCodecMap->freeCodecContext(ic->streams[selTrack]); 2545 enc = gCodecMap->getCodecContext(ic->streams[selTrack], codec); 2546 video_codec_id = mediacodec_mcid; 2547 foundgpudecoder = true; 2548 } 2495 2549 } 2550 #endif // USING_MEDIACODEC 2496 2551 } 2497 2498 2552 // default to mpeg2 2499 2553 if (video_codec_id == kCodec_NONE) 2500 2554 { … … int AvFormatDecoder::ScanStreams(bool novideo) 2502 2556 "Unknown video codec - defaulting to MPEG2"); 2503 2557 video_codec_id = kCodec_MPEG2; 2504 2558 } 2505 else2506 {2507 codec = avcodec_find_decoder(enc->codec_id);2508 }2509 2559 2510 2560 // Use a PrivateDecoder if allowed in playerFlags AND matched 2511 2561 // via the decoder name … … int AvFormatDecoder::ScanStreams(bool novideo) 2516 2566 if (!codec_is_std(video_codec_id)) 2517 2567 thread_count = 1; 2518 2568 2569 use_frame_timing = false; 2570 if (! private_dec 2571 && (codec_is_std(video_codec_id) || codec_is_mediacodec(video_codec_id))) 2572 use_frame_timing = true; 2573 2519 2574 if (FlagIsSet(kDecodeSingleThreaded)) 2520 2575 thread_count = 1; 2521 2576 … … int AvFormatDecoder::ScanStreams(bool novideo) 2531 2586 ScanATSCCaptionStreams(selTrack); 2532 2587 UpdateATSCCaptionTracks(); 2533 2588 2534 LOG(VB_ PLAYBACK, LOG_INFO, LOC +2589 LOG(VB_GENERAL, LOG_INFO, LOC + 2535 2590 QString("Using %1 for video decoding") 2536 2591 .arg(GetCodecDecoderName())); 2537 2592 … … bool AvFormatDecoder::OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec) 2611 2666 { 2612 2667 QMutexLocker locker(avcodeclock); 2613 2668 2669 #ifdef USING_MEDIACODEC 2670 if (QString("mediacodec") == codec->wrapper_name) 2671 av_jni_set_java_vm(QAndroidJniEnvironment::javaVM(), NULL); 2672 #endif 2614 2673 int ret = avcodec_open2(avctx, codec, NULL); 2615 2674 if (ret < 0) 2616 2675 { … … bool AvFormatDecoder::PreProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3536 3595 return true; 3537 3596 } 3538 3597 3598 // Maximum retries - 500 = 5 seconds 3599 #define PACKET_MAX_RETRIES 5000 3600 #define RETRY_WAIT_TIME 10000 // microseconds 3539 3601 bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3540 3602 { 3603 int retryCount = 0; 3541 3604 int ret = 0, gotpicture = 0; 3542 3605 int64_t pts = 0; 3543 3606 AVCodecContext *context = gCodecMap->getCodecContext(curstream); … … bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3551 3614 if (pkt->pts != (int64_t)AV_NOPTS_VALUE) 3552 3615 pts_detected = true; 3553 3616 3554 avcodeclock->lock(); 3555 if (private_dec) 3617 bool tryAgain = true; 3618 bool sentPacket = false; 3619 int ret2 = 0; 3620 while (tryAgain) 3556 3621 { 3557 if (QString(ic->iformat->name).contains("avi") || !pts_detected) 3558 pkt->pts = pkt->dts; 3559 // TODO disallow private decoders for dvd playback 3560 // N.B. we do not reparse the frame as it breaks playback for 3561 // everything but libmpeg2 3562 ret = private_dec->GetFrame(curstream, mpa_pic, &gotpicture, pkt); 3563 } 3564 else 3565 { 3566 context->reordered_opaque = pkt->pts; 3567 // SUGGESTION 3568 // Now that avcodec_decode_video2 is deprecated and replaced 3569 // by 2 calls (receive frame and send packet), this could be optimized 3570 // into separate routines or separate threads. 3571 // Also now that it always consumes a whole buffer some code 3572 // in the caller may be able to be optimized. 3573 ret = avcodec_receive_frame(context, mpa_pic); 3574 if (ret == 0) 3575 gotpicture = 1; 3576 if (ret == AVERROR(EAGAIN)) 3622 tryAgain = false; 3623 gotpicture = 0; 3624 avcodeclock->lock(); 3625 if (private_dec) 3626 { 3627 if (QString(ic->iformat->name).contains("avi") || !pts_detected) 3628 pkt->pts = pkt->dts; 3629 // TODO disallow private decoders for dvd playback 3630 // N.B. we do not reparse the frame as it breaks playback for 3631 // everything but libmpeg2 3632 ret = private_dec->GetFrame(curstream, mpa_pic, &gotpicture, pkt); 3633 sentPacket = true; 3634 } 3635 else 3636 { 3637 if (!use_frame_timing) 3638 context->reordered_opaque = pkt->pts; 3639 3640 // SUGGESTION 3641 // Now that avcodec_decode_video2 is deprecated and replaced 3642 // by 2 calls (receive frame and send packet), this could be optimized 3643 // into separate routines or separate threads. 3644 // Also now that it always consumes a whole buffer some code 3645 // in the caller may be able to be optimized. 3577 3646 ret = 0; 3578 if (ret == 0) 3579 ret = avcodec_send_packet(context, pkt); 3580 // The code assumes that there is always space to add a new 3581 // packet. This seems risky but has always worked. 3582 // It should actually check if (ret == AVERROR(EAGAIN)) and then keep 3583 // the packet around and try it again after processing the frame 3584 // received here. 3585 } 3586 avcodeclock->unlock(); 3647 ret = avcodec_receive_frame(context, mpa_pic); 3587 3648 3588 if (ret <0)3589 {3590 char error[AV_ERROR_MAX_STRING_SIZE];3591 LOG(VB_GENERAL, LOG_ERR, LOC +3592 QString("video decode error: %1 (%2)")3593 .arg(av_make_error_string(error, sizeof(error), ret))3594 .arg(gotpicture));3595 if (ret == AVERROR_INVALIDDATA)3596 {3597 if ( ++averror_count > SEQ_PKT_ERR_MAX)3649 if (ret == 0) 3650 gotpicture = 1; 3651 else 3652 gotpicture = 0; 3653 if (ret == AVERROR(EAGAIN)) 3654 ret = 0; 3655 // If we got a picture do not send the packet until we have 3656 // all available pictures 3657 // if (ret == 0 && !gotpicture) 3658 if (ret==0 && !gotpicture) 3598 3659 { 3599 // If erroring on GPU assist, try switching to software decode 3600 if (codec_is_std(video_codec_id)) 3601 m_parent->SetErrored(QObject::tr("Video Decode Error")); 3660 ret2 = avcodec_send_packet(context, pkt); 3661 if (ret2 == AVERROR(EAGAIN)) 3662 { 3663 tryAgain = true; 3664 ret2 = 0; 3665 } 3602 3666 else 3603 m_streams_changed = true; 3667 { 3668 sentPacket = true; 3669 } 3604 3670 } 3605 3671 } 3606 return false; 3672 avcodeclock->unlock(); 3673 3674 if (ret < 0 || ret2 < 0) 3675 { 3676 char error[AV_ERROR_MAX_STRING_SIZE]; 3677 if (ret < 0) 3678 { 3679 LOG(VB_GENERAL, LOG_ERR, LOC + 3680 QString("video avcodec_receive_frame error: %1 (%2) gotpicture:%3") 3681 .arg(av_make_error_string(error, sizeof(error), ret)) 3682 .arg(ret).arg(gotpicture)); 3683 } 3684 if (ret2 < 0) 3685 LOG(VB_GENERAL, LOG_ERR, LOC + 3686 QString("video avcodec_send_packet error: %1 (%2) gotpicture:%3") 3687 .arg(av_make_error_string(error, sizeof(error), ret2)) 3688 .arg(ret2).arg(gotpicture)); 3689 if (ret == AVERROR_INVALIDDATA || ret2 == AVERROR_INVALIDDATA) 3690 { 3691 if (++averror_count > SEQ_PKT_ERR_MAX) 3692 { 3693 // If erroring on GPU assist, try switching to software decode 3694 if (codec_is_std(video_codec_id)) 3695 m_parent->SetErrored(QObject::tr("Video Decode Error")); 3696 else 3697 m_streams_changed = true; 3698 } 3699 } 3700 if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL) 3701 m_streams_changed = true; 3702 return false; 3703 } 3704 3705 if (tryAgain) 3706 { 3707 if (++retryCount > PACKET_MAX_RETRIES) 3708 { 3709 LOG(VB_GENERAL, LOG_ERR, LOC + 3710 QString("ERROR: Video decode buffering retries exceeded maximum")); 3711 return false; 3712 } 3713 LOG(VB_PLAYBACK, LOG_INFO, LOC + 3714 QString("Video decode buffering retry")); 3715 usleep(RETRY_WAIT_TIME); 3716 } 3607 3717 } 3608 3718 // averror_count counts sequential errors, so if you have a successful 3609 3719 // packet then reset it 3610 3720 averror_count = 0; 3611 3612 if (!gotpicture) 3721 if (gotpicture) 3613 3722 { 3614 return true; 3615 } 3723 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + 3724 QString("video timecodes packet-pts:%1 frame-pts:%2 packet-dts: %3 frame-dts:%4") 3725 .arg(pkt->pts).arg(mpa_pic->pts).arg(pkt->pts) 3726 .arg(mpa_pic->pkt_dts)); 3616 3727 3617 // Detect faulty video timestamps using logic from ffplay. 3618 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3619 { 3620 faulty_dts += (pkt->dts <= last_dts_for_fault_detection); 3621 last_dts_for_fault_detection = pkt->dts; 3622 } 3623 if (mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3624 { 3625 faulty_pts += (mpa_pic->reordered_opaque <= last_pts_for_fault_detection); 3626 last_pts_for_fault_detection = mpa_pic->reordered_opaque; 3627 reordered_pts_detected = true; 3628 } 3728 if (!use_frame_timing) 3729 { 3730 // Detect faulty video timestamps using logic from ffplay. 3731 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3732 { 3733 faulty_dts += (pkt->dts <= last_dts_for_fault_detection); 3734 last_dts_for_fault_detection = pkt->dts; 3735 } 3736 if (mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3737 { 3738 faulty_pts += (mpa_pic->reordered_opaque <= last_pts_for_fault_detection); 3739 last_pts_for_fault_detection = mpa_pic->reordered_opaque; 3740 reordered_pts_detected = true; 3741 } 3629 3742 3630 // Explicity use DTS for DVD since they should always be valid for every 3631 // frame and fixups aren't enabled for DVD. 3632 // Select reordered_opaque (PTS) timestamps if they are less faulty or the 3633 // the DTS timestamp is missing. Also use fixups for missing PTS instead of 3634 // DTS to avoid oscillating between PTS and DTS. Only select DTS if PTS is 3635 // more faulty or never detected. 3636 if (force_dts_timestamps) 3637 { 3638 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3639 pts = pkt->dts; 3640 pts_selected = false; 3641 } 3642 else if (ringBuffer->IsDVD()) 3643 { 3644 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3645 pts = pkt->dts; 3646 pts_selected = false; 3647 } 3648 else if (private_dec && private_dec->NeedsReorderedPTS() && 3649 mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3650 { 3651 pts = mpa_pic->reordered_opaque; 3652 pts_selected = true; 3653 } 3654 else if (faulty_pts <= faulty_dts && reordered_pts_detected) 3655 { 3656 if (mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3657 pts = mpa_pic->reordered_opaque; 3658 pts_selected = true; 3743 // Explicity use DTS for DVD since they should always be valid for every 3744 // frame and fixups aren't enabled for DVD. 3745 // Select reordered_opaque (PTS) timestamps if they are less faulty or the 3746 // the DTS timestamp is missing. Also use fixups for missing PTS instead of 3747 // DTS to avoid oscillating between PTS and DTS. Only select DTS if PTS is 3748 // more faulty or never detected. 3749 if (force_dts_timestamps) 3750 { 3751 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3752 pts = pkt->dts; 3753 pts_selected = false; 3754 } 3755 else if (ringBuffer->IsDVD()) 3756 { 3757 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3758 pts = pkt->dts; 3759 pts_selected = false; 3760 } 3761 else if (private_dec && private_dec->NeedsReorderedPTS() && 3762 mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3763 { 3764 pts = mpa_pic->reordered_opaque; 3765 pts_selected = true; 3766 } 3767 else if (faulty_pts <= faulty_dts && reordered_pts_detected) 3768 { 3769 if (mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3770 pts = mpa_pic->reordered_opaque; 3771 pts_selected = true; 3772 } 3773 else if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3774 { 3775 pts = pkt->dts; 3776 pts_selected = false; 3777 } 3778 3779 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG, LOC + 3780 QString("video packet timestamps reordered %1 pts %2 dts %3 (%4)") 3781 .arg(mpa_pic->reordered_opaque).arg(pkt->pts).arg(pkt->dts) 3782 .arg((force_dts_timestamps) ? "dts forced" : 3783 (pts_selected) ? "reordered" : "dts")); 3784 3785 mpa_pic->reordered_opaque = pts; 3786 } 3787 ProcessVideoFrame(curstream, mpa_pic); 3659 3788 } 3660 else if (pkt->dts != (int64_t)AV_NOPTS_VALUE)3789 if (!sentPacket) 3661 3790 { 3662 pts = pkt->dts; 3663 pts_selected = false; 3791 // MythTV logic expects that only one frame is processed 3792 // Save the packet for later and return. 3793 AVPacket *newPkt = new AVPacket; 3794 memset(newPkt, 0, sizeof(AVPacket)); 3795 av_init_packet(newPkt); 3796 av_packet_ref(newPkt, pkt); 3797 storedPackets.prepend(newPkt); 3664 3798 } 3665 3666 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG, LOC +3667 QString("video packet timestamps reordered %1 pts %2 dts %3 (%4)")3668 .arg(mpa_pic->reordered_opaque).arg(pkt->pts).arg(pkt->dts)3669 .arg((force_dts_timestamps) ? "dts forced" :3670 (pts_selected) ? "reordered" : "dts"));3671 3672 mpa_pic->reordered_opaque = pts;3673 3674 ProcessVideoFrame(curstream, mpa_pic);3675 3676 3799 return true; 3677 3800 } 3678 3801 3679 3802 bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3680 3803 { 3804 3805 if (flush_discard > 0) 3806 { 3807 flush_discard--; 3808 return true; 3809 } 3810 3681 3811 AVCodecContext *context = gCodecMap->getCodecContext(stream); 3682 3812 3683 3813 // We need to mediate between ATSC and SCTE data when both are present. If … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3777 3907 return false; 3778 3908 } 3779 3909 3780 long long pts = (long long)(av_q2d(stream->time_base) * 3910 long long pts; 3911 if (use_frame_timing) 3912 { 3913 pts = mpa_pic->pts; 3914 if (pts == AV_NOPTS_VALUE) 3915 pts = mpa_pic->pkt_dts; 3916 if (pts == AV_NOPTS_VALUE) 3917 { 3918 LOG(VB_GENERAL, LOG_ERR, LOC + "No PTS found - unable to process video."); 3919 return false; 3920 } 3921 pts = (long long)(av_q2d(stream->time_base) * 3922 pts * 1000); 3923 } 3924 else 3925 pts = (long long)(av_q2d(stream->time_base) * 3781 3926 mpa_pic->reordered_opaque * 1000); 3782 3927 3783 3928 long long temppts = pts; … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3794 3939 temppts += (long long)(mpa_pic->repeat_pict * 500 / fps); 3795 3940 } 3796 3941 3942 // Calculate actual fps from the pts values. 3943 long long ptsdiff = temppts - lastvpts; 3944 double calcfps = 1000.0 / ptsdiff; 3945 if (calcfps < 121.0 && calcfps > 3.0) 3946 { 3947 // If fps has doubled due to frame-doubling deinterlace 3948 // Set fps to double value. 3949 double fpschange = calcfps / fps; 3950 if (fpschange > 1.9 && fpschange < 2.1) 3951 fpsMultiplier = 2; 3952 if (fpschange > 0.5 && fpschange < 0.6) 3953 fpsMultiplier = 1; 3954 } 3955 3797 3956 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + 3798 3957 QString("video timecode %1 %2 %3 %4%5") 3799 .arg(mpa_pic->reordered_opaque).arg(pts).arg(temppts).arg(lastvpts) 3958 .arg(use_frame_timing ? mpa_pic->pts : mpa_pic->reordered_opaque).arg(pts) 3959 .arg(temppts).arg(lastvpts) 3800 3960 .arg((pts != temppts) ? " fixup" : "")); 3801 3961 3802 3962 if (picframe) … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3815 3975 3816 3976 decoded_video_frame = picframe; 3817 3977 gotVideoFrame = 1; 3818 ++framesPlayed; 3978 if (++fpsSkip >= fpsMultiplier) 3979 { 3980 ++framesPlayed; 3981 fpsSkip = 0; 3982 } 3819 3983 3820 3984 lastvpts = temppts; 3821 3985 if (!firstvpts && firstvptsinuse) -
mythtv/libs/libmythtv/avformatdecoder.h
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h index 486e0bb1bed..c3da8a6cedf 100644
a b class AvFormatDecoder : public DecoderBase 322 322 bool pts_detected; 323 323 bool reordered_pts_detected; 324 324 bool pts_selected; 325 // set use_frame_timing true to utilize the pts values in returned 326 // frames. Set fale to use deprecated method. 327 bool use_frame_timing; 328 int flush_discard; 325 329 326 330 bool force_dts_timestamps; 327 331 -
mythtv/libs/libmythtv/decoderbase.cpp
diff --git a/mythtv/libs/libmythtv/decoderbase.cpp b/mythtv/libs/libmythtv/decoderbase.cpp index 33b1676c60b..b8a2edef83b 100644
a b DecoderBase::DecoderBase(MythPlayer *parent, const ProgramInfo &pginfo) 20 20 21 21 current_width(640), current_height(480), 22 22 current_aspect(1.33333), fps(29.97), 23 fpsMultiplier(1), fpsSkip(0), 23 24 bitrate(4000), 24 25 25 26 framesPlayed(0), framesRead(0), … … void DecoderBase::Reset(bool reset_video_data, bool seek_reset, bool reset_file) 80 81 { 81 82 ResetPosMap(); 82 83 framesPlayed = 0; 84 fpsSkip = 0; 83 85 framesRead = 0; 84 86 totalDuration = AVRationalInit(0); 85 87 dontSyncPositionMap = false; … … bool DecoderBase::DoRewind(long long desiredFrame, bool discardFrames) 581 583 return false; 582 584 583 585 framesPlayed = lastKey; 586 fpsSkip = 0; 584 587 framesRead = lastKey; 585 588 586 589 // Do any Extra frame-by-frame seeking for exactseeks mode … … void DecoderBase::DoFastForwardSeek(long long desiredFrame, bool &needflush) 880 883 ringBuffer->Seek(e.pos, SEEK_SET); 881 884 needflush = true; 882 885 framesPlayed = lastKey; 886 fpsSkip = 0; 883 887 framesRead = lastKey; 884 888 } 885 889 } -
mythtv/libs/libmythtv/decoderbase.h
diff --git a/mythtv/libs/libmythtv/decoderbase.h b/mythtv/libs/libmythtv/decoderbase.h index 3f7eddb8ca5..608c1e6b336 100644
a b class DecoderBase 269 269 void SaveTotalFrames(void); 270 270 bool GetVideoInverted(void) const { return video_inverted; } 271 271 void TrackTotalDuration(bool track) { trackTotalDuration = track; } 272 int GetfpsMultiplier(void) { return fpsMultiplier; } 272 273 273 274 protected: 274 275 virtual int AutoSelectTrack(uint type); … … class DecoderBase 301 302 int current_height; 302 303 float current_aspect; 303 304 double fps; 305 int fpsMultiplier; 306 int fpsSkip; 304 307 uint bitrate; 305 308 306 309 long long framesPlayed; -
mythtv/libs/libmythtv/libmythtv.pro
diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro index 39356bf774f..953fcb4a8b3 100644
a b 1 1 include ( ../../settings.pro ) 2 2 3 3 QT += network xml sql widgets 4 android: QT += androidextras 4 5 5 6 TEMPLATE = lib 6 7 TARGET = mythtv-$$LIBVERSION … … using_frontend { 503 504 using_opengl_video:DEFINES += USING_GLVAAPI 504 505 } 505 506 507 using_mediacodec { 508 DEFINES += USING_MEDIACODEC 509 HEADERS += mediacodeccontext.h 510 SOURCES += mediacodeccontext.cpp 511 } 512 506 513 # Misc. frontend 507 514 HEADERS += DetectLetterbox.h 508 515 SOURCES += DetectLetterbox.cpp -
new file mythtv/libs/libmythtv/mediacodeccontext.cpp
diff --git a/mythtv/libs/libmythtv/mediacodeccontext.cpp b/mythtv/libs/libmythtv/mediacodeccontext.cpp new file mode 100644 index 00000000000..d95de6a01a1
- + 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 "mediacodeccontext.h" 26 27 #include "mythlogging.h" 28 29 extern "C" { 30 #include "libavutil/pixfmt.h" 31 #include "libavutil/hwcontext.h" 32 #include "libavcodec/avcodec.h" 33 } 34 35 #define LOC QString("MEDIACODEC: ") 36 37 MythCodecID MediaCodecContext::GetBestSupportedCodec( 38 AVCodec **ppCodec, 39 const QString &decoder, 40 uint stream_type, 41 AVPixelFormat &pix_fmt) 42 { 43 enum AVHWDeviceType type = AV_HWDEVICE_TYPE_MEDIACODEC; 44 45 AVPixelFormat fmt = AV_PIX_FMT_NONE; 46 if (decoder == "mediacodec") 47 { 48 QString decodername = QString((*ppCodec)->name) + "_mediacodec"; 49 if (decodername == "mpeg2video_mediacodec") 50 decodername = "mpeg2_mediacodec"; 51 AVCodec *newCodec = avcodec_find_decoder_by_name (decodername.toLocal8Bit()); 52 if (newCodec) 53 { 54 *ppCodec = newCodec; 55 fmt = AV_PIX_FMT_MEDIACODEC; 56 } 57 else 58 LOG(VB_PLAYBACK, LOG_INFO, LOC + 59 QString("Decoder %1 does not support device type %2.") 60 .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type))); 61 } 62 63 if (fmt == AV_PIX_FMT_NONE) 64 return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1)); 65 else 66 { 67 LOG(VB_PLAYBACK, LOG_INFO, LOC + 68 QString("Decoder %1 supports device type %2.") 69 .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type))); 70 pix_fmt = fmt; 71 return (MythCodecID)(kCodec_MPEG1_MEDIACODEC + (stream_type - 1)); 72 } 73 } -
new file mythtv/libs/libmythtv/mediacodeccontext.h
diff --git a/mythtv/libs/libmythtv/mediacodeccontext.h b/mythtv/libs/libmythtv/mediacodeccontext.h new file mode 100644 index 00000000000..7f116487e0b
- + 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 VIDEOOUTOPENGLMEDIACODEC_H 27 #define VIDEOOUTOPENGLMEDIACODEC_H 28 29 #include "videoout_opengl.h" 30 31 32 class MediaCodecContext 33 { 34 public: 35 static MythCodecID GetBestSupportedCodec(AVCodec **ppCodec, 36 const QString &decoder, 37 uint stream_type, 38 AVPixelFormat &pix_fmt); 39 }; 40 41 #endif // VIDEOOUTOPENGLMEDIACODEC_H 42 No newline at end of file -
mythtv/libs/libmythtv/mythcodecid.cpp
diff --git a/mythtv/libs/libmythtv/mythcodecid.cpp b/mythtv/libs/libmythtv/mythcodecid.cpp index cd9170a648d..b2023512b5f 100644
a b QString toString(MythCodecID codecid) 102 102 case kCodec_HEVC_DXVA2: 103 103 return "HEVC DXVA2"; 104 104 105 case kCodec_MPEG1_MEDIACODEC: 106 return "MPEG1 MEDIACODEC"; 107 case kCodec_MPEG2_MEDIACODEC: 108 return "MPEG2 MEDIACODEC"; 109 case kCodec_H263_MEDIACODEC: 110 return "H.263 MEDIACODEC"; 111 case kCodec_MPEG4_MEDIACODEC: 112 return "MPEG4 MEDIACODEC"; 113 case kCodec_H264_MEDIACODEC: 114 return "H.264 MEDIACODEC"; 115 case kCodec_VC1_MEDIACODEC: 116 return "VC1 MEDIACODEC"; 117 case kCodec_WMV3_MEDIACODEC: 118 return "WMV3 MEDIACODEC"; 119 case kCodec_VP8_MEDIACODEC: 120 return "VP8 MEDIACODEC"; 121 case kCodec_VP9_MEDIACODEC: 122 return "VP9 MEDIACODEC"; 123 case kCodec_HEVC_MEDIACODEC: 124 return "HEVC MEDIACODEC"; 125 105 126 default: 106 127 break; 107 128 } … … int myth2av_codecid(MythCodecID codec_id, bool &vdpau) 253 274 ret = AV_CODEC_ID_HEVC; 254 275 break; 255 276 277 case kCodec_MPEG1_MEDIACODEC: 278 ret = AV_CODEC_ID_MPEG1VIDEO; 279 break; 280 case kCodec_MPEG2_MEDIACODEC: 281 ret = AV_CODEC_ID_MPEG2VIDEO; 282 break; 283 case kCodec_H263_MEDIACODEC: 284 ret = AV_CODEC_ID_H263; 285 break; 286 case kCodec_MPEG4_MEDIACODEC: 287 ret = AV_CODEC_ID_MPEG4; 288 break; 289 case kCodec_H264_MEDIACODEC: 290 ret = AV_CODEC_ID_H264; 291 break; 292 case kCodec_VC1_MEDIACODEC: 293 ret = AV_CODEC_ID_VC1; 294 break; 295 case kCodec_WMV3_MEDIACODEC: 296 ret = AV_CODEC_ID_WMV3; 297 break; 298 case kCodec_VP8_MEDIACODEC: 299 ret = AV_CODEC_ID_VP8; 300 break; 301 case kCodec_VP9_MEDIACODEC: 302 ret = AV_CODEC_ID_VP9; 303 break; 304 case kCodec_HEVC_MEDIACODEC: 305 ret = AV_CODEC_ID_HEVC; 306 break; 307 256 308 default: 257 309 LOG(VB_GENERAL, LOG_ERR, 258 310 QString("Error: MythCodecID %1 has not been " … … QString get_encoding_type(MythCodecID codecid) 303 355 case kCodec_MPEG1_VDPAU: 304 356 case kCodec_MPEG1_VAAPI: 305 357 case kCodec_MPEG1_DXVA2: 358 case kCodec_MPEG1_MEDIACODEC: 306 359 case kCodec_MPEG2: 307 360 case kCodec_MPEG2_VDPAU: 308 361 case kCodec_MPEG2_VAAPI: 309 362 case kCodec_MPEG2_DXVA2: 363 case kCodec_MPEG2_MEDIACODEC: 310 364 return "MPEG-2"; 311 365 312 366 case kCodec_H263: 313 367 case kCodec_H263_VDPAU: 314 368 case kCodec_H263_VAAPI: 315 369 case kCodec_H263_DXVA2: 370 case kCodec_H263_MEDIACODEC: 316 371 return "H.263"; 317 372 318 373 case kCodec_NUV_MPEG4: … … QString get_encoding_type(MythCodecID codecid) 320 375 case kCodec_MPEG4_VDPAU: 321 376 case kCodec_MPEG4_VAAPI: 322 377 case kCodec_MPEG4_DXVA2: 378 case kCodec_MPEG4_MEDIACODEC: 323 379 return "MPEG-4"; 324 380 325 381 case kCodec_H264: 326 382 case kCodec_H264_VDPAU: 327 383 case kCodec_H264_VAAPI: 328 384 case kCodec_H264_DXVA2: 385 case kCodec_H264_MEDIACODEC: 329 386 return "H.264"; 330 387 331 388 case kCodec_VC1: 332 389 case kCodec_VC1_VDPAU: 333 390 case kCodec_VC1_VAAPI: 334 391 case kCodec_VC1_DXVA2: 392 case kCodec_VC1_MEDIACODEC: 335 393 return "VC-1"; 336 394 337 395 case kCodec_WMV3: 338 396 case kCodec_WMV3_VDPAU: 339 397 case kCodec_WMV3_VAAPI: 340 398 case kCodec_WMV3_DXVA2: 399 case kCodec_WMV3_MEDIACODEC: 341 400 return "WMV3"; 342 401 343 402 case kCodec_VP8: 344 403 case kCodec_VP8_VDPAU: 345 404 case kCodec_VP8_VAAPI: 346 405 case kCodec_VP8_DXVA2: 406 case kCodec_VP8_MEDIACODEC: 347 407 return "VP8"; 348 408 349 409 case kCodec_VP9: 350 410 case kCodec_VP9_VDPAU: 351 411 case kCodec_VP9_VAAPI: 352 412 case kCodec_VP9_DXVA2: 413 case kCodec_VP9_MEDIACODEC: 353 414 return "VP8"; 354 415 355 416 case kCodec_HEVC: 356 417 case kCodec_HEVC_VDPAU: 357 418 case kCodec_HEVC_VAAPI: 358 419 case kCodec_HEVC_DXVA2: 420 case kCodec_HEVC_MEDIACODEC: 359 421 return "HEVC"; 360 422 361 423 case kCodec_NONE: … … QString get_encoding_type(MythCodecID codecid) 363 425 case kCodec_VDPAU_END: 364 426 case kCodec_VAAPI_END: 365 427 case kCodec_DXVA2_END: 428 case kCodec_MEDIACODEC_END: 366 429 return QString(); 367 430 } 368 431 … … QString get_decoder_name(MythCodecID codec_id) 380 443 if (codec_is_dxva2(codec_id)) 381 444 return "dxva2"; 382 445 446 if (codec_is_mediacodec(codec_id)) 447 return "mediacodec"; 448 383 449 return "ffmpeg"; 384 450 } -
mythtv/libs/libmythtv/mythcodecid.h
diff --git a/mythtv/libs/libmythtv/mythcodecid.h b/mythtv/libs/libmythtv/mythcodecid.h index 92466df9b8c..ce3620467d9 100644
a b typedef enum 75 75 kCodec_HEVC_DXVA2, 76 76 77 77 kCodec_DXVA2_END, 78 79 kCodec_MEDIACODEC_BEGIN = kCodec_DXVA2_END, 80 81 kCodec_MPEG1_MEDIACODEC, 82 kCodec_MPEG2_MEDIACODEC, 83 kCodec_H263_MEDIACODEC, 84 kCodec_MPEG4_MEDIACODEC, 85 kCodec_H264_MEDIACODEC, 86 kCodec_VC1_MEDIACODEC, 87 kCodec_WMV3_MEDIACODEC, 88 kCodec_VP8_MEDIACODEC, 89 kCodec_VP9_MEDIACODEC, 90 kCodec_HEVC_MEDIACODEC, 91 92 kCodec_MEDIACODEC_END, 93 78 94 } MythCodecID; 79 95 80 96 // MythCodecID convenience functions … … typedef enum 95 111 ((id == kCodec_H264_DXVA2) || \ 96 112 (id == kCodec_MPEG2_DXVA2) || \ 97 113 (id == kCodec_VC1_DXVA2))) 114 #define codec_is_mediacodec(id) ((id > kCodec_MEDIACODEC_BEGIN) && \ 115 (id < kCodec_MEDIACODEC_END)) 116 117 #define codec_sw_copy(id) (codec_is_std(id) || codec_is_mediacodec(id)) 98 118 99 119 QString get_encoding_type(MythCodecID codecid); 100 120 QString get_decoder_name(MythCodecID codec_id); … … int mpeg_version(int codec_id); 130 150 #define CODEC_IS_DXVA2(codec, enc) (0) 131 151 #endif 132 152 153 #ifdef USING_MEDIACODEC 154 #define CODEC_IS_MEDIACODEC(codec) (codec && (QString("mediacodec") == codec->wrapper_name)) 155 #else 156 #define CODEC_IS_MEDIACODEC(codec) (0) 157 #endif 158 133 159 #define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_VDPAU(codec) || \ 134 160 CODEC_IS_VAAPI(codec, enc) || \ 135 CODEC_IS_DXVA2(codec, enc)) 161 CODEC_IS_DXVA2(codec, enc) || \ 162 CODEC_IS_MEDIACODEC(codec)) 136 163 137 164 #endif // _MYTH_CODEC_ID_H_ -
mythtv/libs/libmythtv/mythplayer.cpp
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp index 1fa28968898..3955db9596f 100644
a b int MythPlayer::NextCaptionTrack(int mode) 1747 1747 1748 1748 void MythPlayer::SetFrameInterval(FrameScanType scan, double frame_period) 1749 1749 { 1750 frame_interval = (int)(1000000.0f * frame_period + 0.5f); 1750 frame_interval = (int)(1000000.0f * frame_period + 0.5f) 1751 / decoder->GetfpsMultiplier() ; 1751 1752 if (!avsync_predictor_enabled) 1752 1753 avsync_predictor = 0; 1753 1754 avsync_predictor_enabled = false; … … void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 1940 1941 if (!player_ctx->IsPBP() || player_ctx->IsPrimaryPBP()) 1941 1942 { 1942 1943 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, 1943 LOC + QString("AVSync waitforframe %1 %2 ")1944 .arg( avsync_adjustment).arg(m_double_framerate));1944 LOC + QString("AVSync waitforframe %1 %2 %3") 1945 .arg(frameDelay).arg(avsync_adjustment).arg(m_double_framerate)); 1945 1946 vsync_delay_clock = videosync->WaitForFrame(frameDelay, avsync_adjustment + repeat_delay); 1946 1947 } 1947 1948 else … … void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 1979 1980 osdLock.unlock(); 1980 1981 // Display the second field 1981 1982 if (!player_ctx->IsPBP() || player_ctx->IsPrimaryPBP()) 1983 { 1984 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, 1985 LOC + QString("AVSync waitforframe %1 %2 %3") 1986 .arg(frameDelay).arg(avsync_adjustment).arg(m_double_framerate)); 1982 1987 vsync_delay_clock = videosync->WaitForFrame(frameDelay, avsync_adjustment); 1988 } 1983 1989 videoOutput->Show(ps); 1984 1990 } 1985 1991 … … bool MythPlayer::UpdateFFRewSkip(void) 3737 3743 if (play_speed >= 0.0f && play_speed <= 3.0f) 3738 3744 { 3739 3745 skip_changed = (ffrew_skip != 1); 3740 frame_interval = (int) (1000000.0f / video_frame_rate / temp_speed); 3746 frame_interval = (int) (1000000.0f / video_frame_rate / temp_speed) 3747 / decoder->GetfpsMultiplier() ; 3741 3748 ffrew_skip = (play_speed != 0.0f); 3742 3749 } 3743 3750 else -
mythtv/libs/libmythtv/videobuffers.cpp
diff --git a/mythtv/libs/libmythtv/videobuffers.cpp b/mythtv/libs/libmythtv/videobuffers.cpp index e20c13d2772..92620924ca9 100644
a b extern "C" { 15 15 #include "compat.h" 16 16 #include "mythlogging.h" 17 17 18 #define TRY_LOCK_SPINS 10019 #define TRY_LOCK_SPINS_BEFORE_WARNING 1020 #define TRY_LOCK_SPIN_WAIT 100 /* usec */18 #define TRY_LOCK_SPINS 2000 19 #define TRY_LOCK_SPINS_BEFORE_WARNING 9999 20 #define TRY_LOCK_SPIN_WAIT 1000 /* usec */ 21 21 22 22 int next_dbg_str = 0; 23 23 … … VideoFrame *VideoBuffers::GetNextFreeFrame(BufferType enqueue_to) 289 289 290 290 if (tries >= TRY_LOCK_SPINS) 291 291 { 292 LOG(VB_GENERAL, LOG_ERR, QString("GetNextFreeFrame: " 293 "available:%1 used:%2 limbo:%3 pause:%4 displayed:%5 decode:%6 finished:%7") 294 .arg(available.size()).arg(used.size()).arg(limbo.size()).arg(pause.size()).arg(displayed.size()).arg(decode.size()).arg(finished.size())); 292 295 LOG(VB_GENERAL, LOG_ERR, 293 296 QString("GetNextFreeFrame() unable to " 294 297 "lock frame %1 times. Discarding Frames.") -
mythtv/libs/libmythtv/videodisplayprofile.cpp
diff --git a/mythtv/libs/libmythtv/videodisplayprofile.cpp b/mythtv/libs/libmythtv/videodisplayprofile.cpp index 4aec35f421d..700ee3bb990 100644
a b QString VideoDisplayProfile::GetDecoderName(const QString &decoder) 851 851 dec_name["vaapi"] = QObject::tr("VAAPI acceleration"); 852 852 dec_name["dxva2"] = QObject::tr("Windows hardware acceleration"); 853 853 dec_name["vda"] = QObject::tr("Mac VDA hardware acceleration"); 854 dec_name["mediacodec"] = QObject::tr("Android MediaCodec decoder"); 854 855 } 855 856 856 857 QString ret = decoder; … … QString VideoDisplayProfile::GetDecoderHelp(QString decoder) 907 908 "Openmax will use the graphics hardware to " 908 909 "accelerate video decoding on Raspberry Pi. "); 909 910 911 if (decoder == "mediacodec") 912 msg += QObject::tr( 913 "Mediacodec will use the graphics hardware to " 914 "accelerate video decoding on Android. "); 915 910 916 return msg; 911 917 } 912 918 … … void VideoDisplayProfile::CreateProfiles(const QString &hostname) 1453 1459 ""); 1454 1460 } 1455 1461 #endif 1462 1463 #ifdef USING_MEDIACODEC 1464 if (!profiles.contains("MediaCodec Normal")) { 1465 (void) QObject::tr("MediaCodec Normal", 1466 "Sample: MediaCodec Normal"); 1467 groupid = CreateProfileGroup("MediaCodec Normal", hostname); 1468 CreateProfile(groupid, 1, "", "", "", 1469 "mediacodec", 4, true, "opengl", 1470 "opengl2", true, 1471 "none", "none", 1472 ""); 1473 } 1474 #endif 1475 1456 1476 } 1457 1477 1458 1478 QStringList VideoDisplayProfile::GetVideoRenderers(const QString &decoder) -
mythtv/libs/libmythtv/videoout_opengl.cpp
diff --git a/mythtv/libs/libmythtv/videoout_opengl.cpp b/mythtv/libs/libmythtv/videoout_opengl.cpp index af80727f7ef..b689947d738 100644
a b void VideoOutputOpenGL::GetRenderOptions(render_opts &opts, 38 38 (*opts.safe_renderers)["crystalhd"].append("opengl"); 39 39 if (opts.decoders->contains("openmax")) 40 40 (*opts.safe_renderers)["openmax"].append("opengl"); 41 if (opts.decoders->contains("mediacodec")) 42 (*opts.safe_renderers)["mediacodec"].append("opengl"); 41 43 opts.priorities->insert("opengl", 65); 42 44 43 45 // lite profile - no colourspace control, GPU deinterlacing … … bool VideoOutputOpenGL::InputChanged(const QSize &video_dim_buf, 268 270 StopEmbedding(); 269 271 } 270 272 271 if (!codec_is_std(av_codec_id) )273 if (!codec_is_std(av_codec_id) && !codec_is_mediacodec(av_codec_id)) 272 274 { 273 275 LOG(VB_GENERAL, LOG_ERR, LOC + "New video codec is not supported."); 274 276 errorState = kError_Unknown; … … bool VideoOutputOpenGL::SetupOpenGL(void) 417 419 window.GetVideoDispDim(), dvr, 418 420 window.GetDisplayVideoRect(), 419 421 window.GetVideoRect(), true, 420 options, !codec_ is_std(video_codec_id));422 options, !codec_sw_copy(video_codec_id)); 421 423 if (success) 422 424 { 423 425 bool temp_deinterlacing = m_deinterlacing; … … void VideoOutputOpenGL::CreatePainter(void) 473 475 bool VideoOutputOpenGL::CreateBuffers(void) 474 476 { 475 477 QMutexLocker locker(&gl_context_lock); 476 vbuffers.Init(31, true, 1, 12, 4, 2); 478 if (codec_is_mediacodec(video_codec_id)) 479 // vbuffers.Init(4, true, 1, 2, 2, 1); 480 vbuffers.Init(8, true, 1, 4, 2, 1); 481 else 482 vbuffers.Init(31, true, 1, 12, 4, 2); 477 483 return vbuffers.CreateBuffers(FMT_YV12, 478 484 window.GetVideoDim().width(), 479 485 window.GetVideoDim().height()); … … void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD */*osd*/, 525 531 gl_valid = true; 526 532 } 527 533 528 bool sw_frame = codec_ is_std(video_codec_id) &&534 bool sw_frame = codec_sw_copy(video_codec_id) && 529 535 video_codec_id != kCodec_NONE; 530 536 bool deint_proc = m_deinterlacing && (m_deintFilter != NULL); 531 537 OpenGLLocker ctx_lock(gl_context); … … QStringList VideoOutputOpenGL::GetAllowedRenderers( 735 741 { 736 742 list << "opengl" << "opengl-lite"; 737 743 } 744 else if (codec_is_mediacodec(myth_codec_id) && !getenv("NO_OPENGL")) 745 { 746 list << "opengl"; 747 } 738 748 739 749 return list; 740 750 }