Ticket #13233: 20180623_1115_mediacodec_fixed_jump_but_time_bug.patch
File 20180623_1115_mediacodec_fixed_jump_but_time_bug.patch, 40.2 KB (added by , 6 years ago) |
---|
-
mythtv/configure
diff --git a/mythtv/configure b/mythtv/configure index 105992b11f2..7801ea3d1d1 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=' 2032 2033 vaapi 2033 2034 vdpau 2034 2035 openmax 2036 mediacodec 2035 2037 ' 2036 2038 2037 2039 CMDLINE_SELECT=" … … enable libcrypto 2757 2759 enable libdns_sd 2758 2760 enable libxml2 2759 2761 enable lirc 2762 enable mediacodec 2760 2763 enable mheg 2761 2764 enable mythtranscode 2762 2765 enable opengl … … ffmpeg_optset extra_cxxflags extra_ldflags target_os 6964 6967 ffmpeg_optset pkg_config prefix libdir as objcc dep_cc host_cc 6965 6968 ffmpeg_optset host_ld 6966 6969 ffmpeg_optenable cross_compile libmp3lame libx264 libx265 libvpx libxvid 6967 ffmpeg_optenable vdpau vaapi libxml2 libass dxva2 mediacodec6968 ffmpeg_optenable jnilibbluray libfontconfig libfreetype libiec618836970 ffmpeg_optenable vdpau vaapi libxml2 libass dxva2 6971 ffmpeg_optenable libbluray libfontconfig libfreetype libiec61883 6969 6972 ffmpeg_optenable crystalhd sdl2 ffplay 6973 if test $target_os = "android"; then 6974 enabled mediacodec && enable jni 6975 ffmpeg_optenable mediacodec jni 6976 else 6977 disable mediacodec 6978 fi 6979 6970 6980 ffmpeg_extra_cflags="$extra_cflags -w" 6971 6981 6972 6982 ## Call FFmpeg configure here -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp index 2c3a1985a05..c35cb3309d0 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" … … void AvFormatDecoder::GetDecoders(render_opts &opts) 374 382 opts.decoders->append("vaapi"); 375 383 (*opts.equiv_decoders)["vaapi"].append("dummy"); 376 384 #endif 385 #ifdef USING_MEDIACODEC 386 opts.decoders->append("mediacodec"); 387 (*opts.equiv_decoders)["mediacodec"].append("dummy"); 388 #endif 377 389 378 390 PrivateDecoder::GetDecoders(opts); 379 391 } … … AvFormatDecoder::AvFormatDecoder(MythPlayer *parent, 405 417 pts_detected(false), 406 418 reordered_pts_detected(false), 407 419 pts_selected(true), 420 use_frame_timing(false), 408 421 force_dts_timestamps(false), 409 422 playerFlags(flags), 410 423 video_codec_id(kCodec_NONE), … … enum AVPixelFormat get_format_vaapi(struct AVCodecContext *avctx, 1540 1553 } 1541 1554 #endif 1542 1555 1556 #ifdef USING_MEDIACODEC 1557 static enum AVPixelFormat get_format_mediacodec(struct AVCodecContext *avctx, 1558 const enum AVPixelFormat *valid_fmts) 1559 { 1560 enum AVPixelFormat ret = *valid_fmts; // default to first 1561 while (*valid_fmts != AV_PIX_FMT_NONE) { 1562 if (*valid_fmts == AV_PIX_FMT_YUV420P) 1563 ret = AV_PIX_FMT_YUV420P; 1564 valid_fmts++; 1565 } 1566 return ret; 1567 } 1568 #endif 1569 1570 1543 1571 static bool IS_DR1_PIX_FMT(const enum AVPixelFormat fmt) 1544 1572 { 1545 1573 switch (fmt) … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1575 1603 enc->debug = 0; 1576 1604 // enc->error_rate = 0; 1577 1605 1578 AVCodec *codec = avcodec_find_decoder(enc->codec_id);1606 const AVCodec *codec = enc->codec; 1579 1607 1580 1608 if (selectedStream) 1581 1609 { … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1612 1640 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1613 1641 } 1614 1642 else 1643 #endif 1644 #ifdef USING_MEDIACODEC 1645 if (CODEC_IS_MEDIACODEC(codec)) 1646 { 1647 enc->get_format = get_format_mediacodec; 1648 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1649 } 1650 else 1615 1651 #endif 1616 1652 if (codec && codec->capabilities & AV_CODEC_CAP_DR1) 1617 1653 { … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1679 1715 } 1680 1716 1681 1717 m_parent->SetKeyframeDistance(keyframedist); 1682 AVCodec *codec = avcodec_find_decoder(enc->codec_id);1718 const AVCodec *codec = enc->codec; 1683 1719 QString codecName; 1684 1720 if (codec) 1685 1721 codecName = codec->name; … … int AvFormatDecoder::ScanStreams(bool novideo) 2368 2404 2369 2405 if (averror_count > SEQ_PKT_ERR_MAX) 2370 2406 gCodecMap->freeCodecContext(ic->streams[selTrack]); 2371 AVCodecContext *enc = gCodecMap->getCodecContext(ic->streams[selTrack] );2407 AVCodecContext *enc = gCodecMap->getCodecContext(ic->streams[selTrack], codec); 2372 2408 StreamInfo si(selTrack, 0, 0, 0, 0); 2373 2409 2374 2410 tracks[kTrackTypeVideo].push_back(si); … … int AvFormatDecoder::ScanStreams(bool novideo) 2393 2429 uint height = max(dim.height(), 16); 2394 2430 QString dec = "ffmpeg"; 2395 2431 uint thread_count = 1; 2396 AVCodec *codec1 = avcodec_find_decoder(enc->codec_id);2397 2432 QString codecName; 2398 if ( codec1)2399 codecName = codec1->name;2433 if (enc->codec) 2434 codecName = enc->codec->name; 2400 2435 if (enc->framerate.den && enc->framerate.num) 2401 2436 fps = float(enc->framerate.num) / float(enc->framerate.den); 2402 2437 else … … int AvFormatDecoder::ScanStreams(bool novideo) 2473 2508 } 2474 2509 #endif // USING_GLVAAPI 2475 2510 #ifdef USING_DXVA2 2476 if (!foundgpudecode )2511 if (!foundgpudecoder) 2477 2512 { 2478 2513 MythCodecID dxva2_mcid; 2479 2514 AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P; … … int AvFormatDecoder::ScanStreams(bool novideo) 2489 2524 } 2490 2525 } 2491 2526 #endif // USING_DXVA2 2492 if (foundgpudecoder) 2527 #ifdef USING_MEDIACODEC 2528 if (!foundgpudecoder) 2493 2529 { 2494 enc->codec_id = (AVCodecID) myth2av_codecid(video_codec_id); 2530 MythCodecID mediacodec_mcid; 2531 AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P; 2532 mediacodec_mcid = MediaCodecContext::GetBestSupportedCodec( 2533 &codec, dec, mpeg_version(enc->codec_id), 2534 pix_fmt); 2535 2536 if (codec_is_mediacodec(mediacodec_mcid)) 2537 { 2538 gCodecMap->freeCodecContext(ic->streams[selTrack]); 2539 enc = gCodecMap->getCodecContext(ic->streams[selTrack], codec); 2540 video_codec_id = mediacodec_mcid; 2541 foundgpudecoder = true; 2542 } 2495 2543 } 2544 #endif // USING_MEDIACODEC 2496 2545 } 2497 2498 2546 // default to mpeg2 2499 2547 if (video_codec_id == kCodec_NONE) 2500 2548 { … … int AvFormatDecoder::ScanStreams(bool novideo) 2502 2550 "Unknown video codec - defaulting to MPEG2"); 2503 2551 video_codec_id = kCodec_MPEG2; 2504 2552 } 2505 else2506 {2507 codec = avcodec_find_decoder(enc->codec_id);2508 }2509 2553 2510 2554 // Use a PrivateDecoder if allowed in playerFlags AND matched 2511 2555 // via the decoder name … … int AvFormatDecoder::ScanStreams(bool novideo) 2516 2560 if (!codec_is_std(video_codec_id)) 2517 2561 thread_count = 1; 2518 2562 2563 use_frame_timing = false; 2564 if (! private_dec 2565 && (codec_is_std(video_codec_id) || codec_is_mediacodec(video_codec_id))) 2566 use_frame_timing = true; 2567 2519 2568 if (FlagIsSet(kDecodeSingleThreaded)) 2520 2569 thread_count = 1; 2521 2570 … … int AvFormatDecoder::ScanStreams(bool novideo) 2531 2580 ScanATSCCaptionStreams(selTrack); 2532 2581 UpdateATSCCaptionTracks(); 2533 2582 2534 LOG(VB_ PLAYBACK, LOG_INFO, LOC +2583 LOG(VB_GENERAL, LOG_INFO, LOC + 2535 2584 QString("Using %1 for video decoding") 2536 2585 .arg(GetCodecDecoderName())); 2537 2586 … … bool AvFormatDecoder::OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec) 2611 2660 { 2612 2661 QMutexLocker locker(avcodeclock); 2613 2662 2663 #ifdef USING_MEDIACODEC 2664 if (QString("mediacodec") == codec->wrapper_name) 2665 av_jni_set_java_vm(QAndroidJniEnvironment::javaVM(), NULL); 2666 #endif 2614 2667 int ret = avcodec_open2(avctx, codec, NULL); 2615 2668 if (ret < 0) 2616 2669 { … … bool AvFormatDecoder::PreProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3536 3589 return true; 3537 3590 } 3538 3591 3592 // Maximum retries - 500 = 5 seconds 3593 #define PACKET_MAX_RETRIES 5000 3594 #define RETRY_WAIT_TIME 10000 // microseconds 3539 3595 bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3540 3596 { 3597 int retryCount = 0; 3541 3598 int ret = 0, gotpicture = 0; 3542 3599 int64_t pts = 0; 3543 3600 AVCodecContext *context = gCodecMap->getCodecContext(curstream); … … bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3551 3608 if (pkt->pts != (int64_t)AV_NOPTS_VALUE) 3552 3609 pts_detected = true; 3553 3610 3554 avcodeclock->lock(); 3555 if (private_dec) 3556 { 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 3611 bool tryAgain = true; 3612 bool sentPacket = false; 3613 while (tryAgain) 3565 3614 { 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)) 3577 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(); 3587 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) 3615 tryAgain = false; 3616 gotpicture = 0; 3617 avcodeclock->lock(); 3618 if (private_dec) 3619 { 3620 if (QString(ic->iformat->name).contains("avi") || !pts_detected) 3621 pkt->pts = pkt->dts; 3622 // TODO disallow private decoders for dvd playback 3623 // N.B. we do not reparse the frame as it breaks playback for 3624 // everything but libmpeg2 3625 ret = private_dec->GetFrame(curstream, mpa_pic, &gotpicture, pkt); 3626 sentPacket = true; 3627 } 3628 else 3596 3629 { 3597 if (++averror_count > SEQ_PKT_ERR_MAX) 3630 if (!use_frame_timing) 3631 context->reordered_opaque = pkt->pts; 3632 3633 // SUGGESTION 3634 // Now that avcodec_decode_video2 is deprecated and replaced 3635 // by 2 calls (receive frame and send packet), this could be optimized 3636 // into separate routines or separate threads. 3637 // Also now that it always consumes a whole buffer some code 3638 // in the caller may be able to be optimized. 3639 ret = avcodec_receive_frame(context, mpa_pic); 3640 3641 if (ret == 0) 3642 gotpicture = 1; 3643 else 3644 gotpicture = 0; 3645 if (ret == AVERROR(EAGAIN)) 3646 ret = 0; 3647 // If we got a picture do not send the packet until we have 3648 // all available pictures 3649 if (ret == 0 && !gotpicture) 3598 3650 { 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")); 3651 ret = avcodec_send_packet(context, pkt); 3652 if (ret == AVERROR(EAGAIN)) 3653 { 3654 tryAgain = true; 3655 ret = 0; 3656 } 3602 3657 else 3603 m_streams_changed= true;3658 sentPacket = true; 3604 3659 } 3605 3660 } 3606 return false; 3661 avcodeclock->unlock(); 3662 3663 if (ret < 0) 3664 { 3665 char error[AV_ERROR_MAX_STRING_SIZE]; 3666 LOG(VB_GENERAL, LOG_ERR, LOC + 3667 QString("video decode error: %1 (%2) gotpicture:%3") 3668 .arg(av_make_error_string(error, sizeof(error), ret)) 3669 .arg(ret).arg(gotpicture)); 3670 if (ret == AVERROR_INVALIDDATA) 3671 { 3672 if (++averror_count > SEQ_PKT_ERR_MAX) 3673 { 3674 // If erroring on GPU assist, try switching to software decode 3675 if (codec_is_std(video_codec_id)) 3676 m_parent->SetErrored(QObject::tr("Video Decode Error")); 3677 else 3678 m_streams_changed = true; 3679 } 3680 } 3681 return false; 3682 } 3683 3684 if (tryAgain) 3685 { 3686 if (++retryCount > PACKET_MAX_RETRIES) 3687 { 3688 LOG(VB_GENERAL, LOG_ERR, LOC + 3689 QString("ERROR: Video decode buffering retries exceeded maximum")); 3690 return false; 3691 } 3692 LOG(VB_PLAYBACK, LOG_INFO, LOC + 3693 QString("Video decode buffering retry")); 3694 usleep(RETRY_WAIT_TIME); 3695 } 3607 3696 } 3608 3697 // averror_count counts sequential errors, so if you have a successful 3609 3698 // packet then reset it 3610 3699 averror_count = 0; 3611 3612 if (!gotpicture) 3700 if (gotpicture) 3613 3701 { 3614 return true; 3615 } 3702 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + 3703 QString("video timecodes packet-pts:%1 frame-pts:%2 packet-dts: %3 frame-dts:%4") 3704 .arg(pkt->pts).arg(mpa_pic->pts).arg(pkt->pts) 3705 .arg(mpa_pic->pkt_dts)); 3616 3706 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 } 3707 if (!use_frame_timing) 3708 { 3709 // Detect faulty video timestamps using logic from ffplay. 3710 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3711 { 3712 faulty_dts += (pkt->dts <= last_dts_for_fault_detection); 3713 last_dts_for_fault_detection = pkt->dts; 3714 } 3715 if (mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3716 { 3717 faulty_pts += (mpa_pic->reordered_opaque <= last_pts_for_fault_detection); 3718 last_pts_for_fault_detection = mpa_pic->reordered_opaque; 3719 reordered_pts_detected = true; 3720 } 3629 3721 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; 3722 // Explicity use DTS for DVD since they should always be valid for every 3723 // frame and fixups aren't enabled for DVD. 3724 // Select reordered_opaque (PTS) timestamps if they are less faulty or the 3725 // the DTS timestamp is missing. Also use fixups for missing PTS instead of 3726 // DTS to avoid oscillating between PTS and DTS. Only select DTS if PTS is 3727 // more faulty or never detected. 3728 if (force_dts_timestamps) 3729 { 3730 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3731 pts = pkt->dts; 3732 pts_selected = false; 3733 } 3734 else if (ringBuffer->IsDVD()) 3735 { 3736 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3737 pts = pkt->dts; 3738 pts_selected = false; 3739 } 3740 else if (private_dec && private_dec->NeedsReorderedPTS() && 3741 mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3742 { 3743 pts = mpa_pic->reordered_opaque; 3744 pts_selected = true; 3745 } 3746 else if (faulty_pts <= faulty_dts && reordered_pts_detected) 3747 { 3748 if (mpa_pic->reordered_opaque != (int64_t)AV_NOPTS_VALUE) 3749 pts = mpa_pic->reordered_opaque; 3750 pts_selected = true; 3751 } 3752 else if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3753 { 3754 pts = pkt->dts; 3755 pts_selected = false; 3756 } 3757 3758 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG, LOC + 3759 QString("video packet timestamps reordered %1 pts %2 dts %3 (%4)") 3760 .arg(mpa_pic->reordered_opaque).arg(pkt->pts).arg(pkt->dts) 3761 .arg((force_dts_timestamps) ? "dts forced" : 3762 (pts_selected) ? "reordered" : "dts")); 3763 3764 mpa_pic->reordered_opaque = pts; 3765 } 3766 ProcessVideoFrame(curstream, mpa_pic); 3659 3767 } 3660 else if (pkt->dts != (int64_t)AV_NOPTS_VALUE)3768 if (!sentPacket) 3661 3769 { 3662 pts = pkt->dts; 3663 pts_selected = false; 3770 // MythTV logic expects that only one frame is processed 3771 // Save the packet for later and return. 3772 AVPacket *newPkt = new AVPacket; 3773 memset(newPkt, 0, sizeof(AVPacket)); 3774 av_init_packet(newPkt); 3775 av_packet_ref(newPkt, pkt); 3776 storedPackets.prepend(newPkt); 3664 3777 } 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 3778 return true; 3677 3779 } 3678 3780 … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3777 3879 return false; 3778 3880 } 3779 3881 3780 long long pts = (long long)(av_q2d(stream->time_base) * 3882 long long pts; 3883 if (use_frame_timing) 3884 { 3885 pts = mpa_pic->pts; 3886 if (pts == AV_NOPTS_VALUE) 3887 pts = mpa_pic->pkt_dts; 3888 if (pts == AV_NOPTS_VALUE) 3889 { 3890 LOG(VB_GENERAL, LOG_ERR, LOC + "No PTS found - unable to process video."); 3891 return false; 3892 } 3893 pts = (long long)(av_q2d(stream->time_base) * 3894 pts * 1000); 3895 } 3896 else 3897 pts = (long long)(av_q2d(stream->time_base) * 3781 3898 mpa_pic->reordered_opaque * 1000); 3782 3899 3783 3900 long long temppts = pts; … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3796 3913 3797 3914 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + 3798 3915 QString("video timecode %1 %2 %3 %4%5") 3799 .arg(mpa_pic->reordered_opaque).arg(pts).arg(temppts).arg(lastvpts) 3916 .arg(use_frame_timing ? mpa_pic->pts : mpa_pic->reordered_opaque).arg(pts) 3917 .arg(temppts).arg(lastvpts) 3800 3918 .arg((pts != temppts) ? " fixup" : "")); 3801 3919 3802 3920 if (picframe) -
mythtv/libs/libmythtv/avformatdecoder.h
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h index 486e0bb1bed..e4dded21576 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; 325 328 326 329 bool force_dts_timestamps; 327 330 -
mythtv/libs/libmythtv/libmythtv.pro
diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro index 438207f3096..6eb6127ca7a 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..7ad5f157065 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 81 97 #define codec_is_std(id) (id < kCodec_NORMAL_END) 98 // temporary test 82 99 #define codec_is_std_mpeg(id) (id == kCodec_MPEG1 || id == kCodec_MPEG2) 83 100 #define codec_is_vdpau(id) ((id > kCodec_VDPAU_BEGIN) && \ 84 101 (id < kCodec_VDPAU_END)) … … typedef enum 95 112 ((id == kCodec_H264_DXVA2) || \ 96 113 (id == kCodec_MPEG2_DXVA2) || \ 97 114 (id == kCodec_VC1_DXVA2))) 115 #define codec_is_mediacodec(id) ((id > kCodec_MEDIACODEC_BEGIN) && \ 116 (id < kCodec_MEDIACODEC_END)) 117 118 #define codec_sw_copy(id) (codec_is_std(id) || codec_is_mediacodec(id)) 98 119 99 120 QString get_encoding_type(MythCodecID codecid); 100 121 QString get_decoder_name(MythCodecID codec_id); … … int mpeg_version(int codec_id); 130 151 #define CODEC_IS_DXVA2(codec, enc) (0) 131 152 #endif 132 153 154 #ifdef USING_MEDIACODEC 155 #define CODEC_IS_MEDIACODEC(codec) (codec && (QString("mediacodec") == codec->wrapper_name)) 156 #else 157 #define CODEC_IS_MEDIACODEC(codec) (0) 158 #endif 159 133 160 #define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_VDPAU(codec) || \ 134 161 CODEC_IS_VAAPI(codec, enc) || \ 135 CODEC_IS_DXVA2(codec, enc)) 162 CODEC_IS_DXVA2(codec, enc) || \ 163 CODEC_IS_MEDIACODEC(codec)) 136 164 137 165 #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..d7710f01570 100644
a b bool MythPlayer::DecoderGetFrame(DecodeType decodetype, bool unsafe) 3491 3491 if (killdecoder) 3492 3492 return false; 3493 3493 3494 // if (decoderSeek >= 0) 3495 // return false; 3496 3494 3497 if (++tries > 10) 3495 3498 { 3496 3499 if (++videobuf_retries >= 2000) -
mythtv/libs/libmythtv/mythplayer.h
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h index 7fe3bb3cec4..de2bf4eb526 100644
a b class MTV_PUBLIC MythPlayer 376 376 void SaveTotalFrames(void); 377 377 void SetErrored(const QString &reason); 378 378 379 // bool DecodeOneFrame() { return pauseDecoder || unpauseDecoder || decodeOneFrame || decoderSeek >= 0; } 380 379 381 protected: 380 382 // Initialization 381 383 void OpenDummy(void); -
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..a4532542d4e 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::ProcessFrame(VideoFrame *frame, OSD */*osd*/, 525 527 gl_valid = true; 526 528 } 527 529 528 bool sw_frame = codec_ is_std(video_codec_id) &&530 bool sw_frame = codec_sw_copy(video_codec_id) && 529 531 video_codec_id != kCodec_NONE; 530 532 bool deint_proc = m_deinterlacing && (m_deintFilter != NULL); 531 533 OpenGLLocker ctx_lock(gl_context); … … QStringList VideoOutputOpenGL::GetAllowedRenderers( 735 737 { 736 738 list << "opengl" << "opengl-lite"; 737 739 } 740 else if (codec_is_mediacodec(myth_codec_id) && !getenv("NO_OPENGL")) 741 { 742 list << "opengl"; 743 } 738 744 739 745 return list; 740 746 }