summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/decode/vd_lavc.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 8c5c7e8af5..96b6b2ca7b 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -174,6 +174,8 @@ typedef struct lavc_ctx {
AVPacket *avpkt;
bool use_hwdec;
struct hwdec_info hwdec; // valid only if use_hwdec==true
+ bstr *attempted_hwdecs;
+ int num_attempted_hwdecs;
AVRational codec_timebase;
enum AVDiscard skip_frame;
bool flushing;
@@ -500,6 +502,18 @@ static void select_and_set_hwdec(struct mp_filter *vd)
continue;
hwdec_name_supported = true;
+ bool already_attempted = false;
+ for (int j = 0; j < ctx->num_attempted_hwdecs; j++) {
+ if (bstr_equals0(ctx->attempted_hwdecs[j], hwdec->name)) {
+ MP_DBG(vd, "Skipping previously attempted hwdec: %s\n",
+ hwdec->name);
+ already_attempted = true;
+ break;
+ }
+ }
+ if (already_attempted)
+ continue;
+
const char *hw_codec = mp_codec_from_av_codec_id(hwdec->codec->id);
if (!hw_codec || strcmp(hw_codec, codec) != 0)
continue;
@@ -509,6 +523,16 @@ static void select_and_set_hwdec(struct mp_filter *vd)
MP_VERBOSE(vd, "Looking at hwdec %s...\n", hwdec->name);
+ /*
+ * Past this point, any kind of failure that results in us
+ * looking for a new hwdec should not lead to use trying this
+ * hwdec again - so add it to the list, regardless of whether
+ * initialisation will succeed or not.
+ */
+ MP_TARRAY_APPEND(ctx, ctx->attempted_hwdecs,
+ ctx->num_attempted_hwdecs,
+ bstrdup(ctx, bstr0(hwdec->name)));
+
if (hwdec_auto_copy && !hwdec->copying) {
MP_VERBOSE(vd, "Not using this for auto-copy.\n");
continue;
@@ -599,7 +623,9 @@ static void force_fallback(struct mp_filter *vd)
uninit_avctx(vd);
int lev = ctx->hwdec_notified ? MSGL_WARN : MSGL_V;
- mp_msg(vd->log, lev, "Falling back to software decoding.\n");
+ mp_msg(vd->log, lev, "Attempting next decoding method after failure of %.*s.\n",
+ BSTR_P(ctx->attempted_hwdecs[ctx->num_attempted_hwdecs - 1]));
+ select_and_set_hwdec(vd);
init_avctx(vd);
}
@@ -609,6 +635,16 @@ static void reinit(struct mp_filter *vd)
uninit_avctx(vd);
+ /*
+ * Reset attempted hwdecs so that if the hwdec list is reconfigured
+ * we attempt all of them from the beginning. The most practical
+ * reason for this is that ctrl+h toggles between `no` and
+ * `auto-safe`, and we want to reevaluate from a clean slate each time.
+ */
+ TA_FREEP(&ctx->attempted_hwdecs);
+ ctx->num_attempted_hwdecs = 0;
+ ctx->hwdec_notified = false;
+
select_and_set_hwdec(vd);
bool use_hwdec = ctx->use_hwdec;
@@ -1116,7 +1152,6 @@ static void send_queued_packet(struct mp_filter *vd)
vd_ffmpeg_ctx *ctx = vd->priv;
assert(ctx->num_requeue_packets);
- assert(!ctx->hw_probing);
if (send_packet(vd, ctx->requeue_packets[0]) != AVERROR(EAGAIN)) {
talloc_free(ctx->requeue_packets[0]);