summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-10-26 19:44:26 +0200
committerwm4 <wm4@nowhere>2017-10-26 19:44:26 +0200
commit22fa498bf9968e622e7d6326006c3f321a3bf2e4 (patch)
tree923293fc81020effe754ba8411708d1103dca583
parentae8b531207b3206b9ff1ab7d17092899bd67c565 (diff)
downloadmpv-22fa498bf9968e622e7d6326006c3f321a3bf2e4.tar.bz2
mpv-22fa498bf9968e622e7d6326006c3f321a3bf2e4.tar.xz
vd_lavc: more aggressive frame dropping for intra only codecs
Should speed up seeks. (Unfortunately it's useless for backstepping. Backstepping is like precise seeking, except we're unable to drop frames, as we can't know the previous frame if we drop it.)
-rw-r--r--video/decode/lavc.h1
-rw-r--r--video/decode/vd_lavc.c19
2 files changed, 15 insertions, 5 deletions
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index ff819d751b..8383c0a67f 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -37,6 +37,7 @@ typedef struct lavc_ctx {
bool hwdec_failed;
bool hwdec_notified;
+ bool intra_only;
int framedrop_flags;
// For HDR side-data caching
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index bf610e83e4..64b6249fd8 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -537,6 +537,9 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
if (!lavc_codec)
return;
+ const AVCodecDescriptor *desc = avcodec_descriptor_get(lavc_codec->id);
+ ctx->intra_only = desc && (desc->props & AV_CODEC_PROP_INTRA_ONLY);
+
ctx->codec_timebase = mp_get_codec_timebase(vd->codec);
// This decoder does not read pkt_timebase correctly yet.
@@ -1059,12 +1062,15 @@ static bool prepare_decoding(struct dec_video *vd)
return false;
int drop = ctx->framedrop_flags;
- if (drop) {
- // hr-seek framedrop vs. normal framedrop
- avctx->skip_frame = drop == 2 ? AVDISCARD_NONREF : opts->framedrop;
+ if (drop == 1) {
+ avctx->skip_frame = opts->framedrop; // normal framedrop
+ } else if (drop == 2) {
+ avctx->skip_frame = AVDISCARD_NONREF; // hr-seek framedrop
+ // Can be much more aggressive for true intra codecs.
+ if (ctx->intra_only)
+ avctx->skip_frame = AVDISCARD_ALL;
} else {
- // normal playback
- avctx->skip_frame = ctx->skip_frame;
+ avctx->skip_frame = ctx->skip_frame; // normal playback
}
if (ctx->hwdec_request_reinit)
@@ -1095,6 +1101,9 @@ static bool do_send_packet(struct dec_video *vd, struct demux_packet *pkt)
if (!prepare_decoding(vd))
return false;
+ if (avctx->skip_frame == AVDISCARD_ALL)
+ return true;
+
AVPacket avpkt;
mp_set_av_packet(&avpkt, pkt, &ctx->codec_timebase);