| @@ -81,13 +81,8 @@ struct vd_lavc_params { · 80 unmodified lines |
| 81 | 81 | bool old_x264; |
| 82 | 82 | bool apply_cropping; |
| 83 | 83 | bool check_hw_profile; |
| 84 | | − int software_fallback; |
| 85 | 84 | char **avopts; |
| 86 | 85 | int dr; |
| 87 | | − char **hwdec_api; |
| 88 | | − char *hwdec_codecs; |
| 89 | | − int hwdec_image_format; |
| 90 | | − int hwdec_extra_frames; |
| 91 | 86 | }; |
| 92 | 87 | |
| 93 | 88 | static const struct m_opt_choice_alternatives discard_names[] = { |
| @@ -111,34 +106,61 @@ const struct m_sub_options vd_lavc_conf = { · 17 unmodified lines |
| 111 | 106 | {"vd-lavc-skipidct", OPT_DISCARD(skip_idct)}, |
| 112 | 107 | {"vd-lavc-skipframe", OPT_DISCARD(skip_frame)}, |
| 113 | 108 | {"vd-lavc-framedrop", OPT_DISCARD(framedrop)}, |
| 114 | | − {"vd-lavc-threads", OPT_INT(threads), M_RANGE(0, DBL_MAX), .flags = UPDATE_VD}, |
| 109 | + {"vd-lavc-threads", OPT_INT(threads), M_RANGE(0, DBL_MAX)}, |
| 115 | 110 | {"vd-lavc-bitexact", OPT_BOOL(bitexact)}, |
| 116 | 111 | {"vd-lavc-assume-old-x264", OPT_BOOL(old_x264)}, |
| 117 | 112 | {"vd-lavc-check-hw-profile", OPT_BOOL(check_hw_profile)}, |
| 118 | | − {"vd-lavc-software-fallback", OPT_CHOICE(software_fallback, |
| 119 | | − {"no", INT_MAX}, {"yes", 1}), M_RANGE(1, INT_MAX)}, |
| 120 | 113 | {"vd-lavc-o", OPT_KEYVALUELIST(avopts)}, |
| 121 | 114 | {"vd-lavc-dr", OPT_CHOICE(dr, |
| 122 | 115 | {"auto", -1}, {"no", 0}, {"yes", 1})}, |
| 123 | 116 | {"vd-apply-cropping", OPT_BOOL(apply_cropping)}, |
| 124 | | − {"hwdec", OPT_STRINGLIST(hwdec_api), |
| 125 | | − .help = hwdec_opt_help, |
| 126 | | − .flags = M_OPT_OPTIONAL_PARAM | M_OPT_ALLOW_NO | UPDATE_HWDEC}, |
| 127 | | − {"hwdec-codecs", OPT_STRING(hwdec_codecs)}, |
| 128 | | − {"hwdec-image-format", OPT_IMAGEFORMAT(hwdec_image_format)}, |
| 129 | | − {"hwdec-extra-frames", OPT_INT(hwdec_extra_frames), M_RANGE(0, 256)}, |
| 130 | 117 | {0} |
| 131 | 118 | }, |
| 119 | + .change_flags = UPDATE_VD, |
| 132 | 120 | .size = sizeof(struct vd_lavc_params), |
| 133 | 121 | .defaults = &(const struct vd_lavc_params){ |
| 134 | 122 | .film_grain = -1 /*auto*/, |
| 135 | 123 | .check_hw_profile = true, |
| 136 | | − .software_fallback = 3, |
| 137 | 124 | .skip_loop_filter = AVDISCARD_DEFAULT, |
| 138 | 125 | .skip_idct = AVDISCARD_DEFAULT, |
| 139 | 126 | .skip_frame = AVDISCARD_DEFAULT, |
| 140 | 127 | .framedrop = AVDISCARD_NONREF, |
| 141 | 128 | .dr = -1, |
| 129 | + .apply_cropping = true, |
| 130 | + }, |
| 131 | +}; |
| 132 | + |
| 133 | +#undef OPT_BASE_STRUCT |
| 134 | +#define OPT_BASE_STRUCT struct hwdec_opts |
| 135 | + |
| 136 | +struct hwdec_opts { |
| 137 | + int software_fallback; |
| 138 | + char **hwdec_api; |
| 139 | + char *hwdec_codecs; |
| 140 | + int hwdec_image_format; |
| 141 | + int hwdec_extra_frames; |
| 142 | +}; |
| 143 | + |
| 144 | +const struct m_sub_options hwdec_conf = { |
| 145 | + .opts = (const m_option_t[]){ |
| 146 | + {"hwdec", OPT_STRINGLIST(hwdec_api), |
| 147 | + .help = hwdec_opt_help, |
| 148 | + .flags = M_OPT_OPTIONAL_PARAM | M_OPT_ALLOW_NO | UPDATE_HWDEC}, |
| 149 | + {"hwdec-codecs", OPT_STRING(hwdec_codecs), |
| 150 | + .flags = UPDATE_HWDEC}, |
| 151 | + {"hwdec-extra-frames", OPT_INT(hwdec_extra_frames), M_RANGE(0, 256), |
| 152 | + .flags = UPDATE_VD}, |
| 153 | + {"hwdec-image-format", OPT_IMAGEFORMAT(hwdec_image_format), |
| 154 | + .flags = UPDATE_VO}, |
| 155 | + {"hwdec-software-fallback", OPT_CHOICE(software_fallback, |
| 156 | + {"no", INT_MAX}, {"yes", 1}), M_RANGE(1, INT_MAX), |
| 157 | + .flags = UPDATE_HWDEC}, |
| 158 | + {"vd-lavc-software-fallback", OPT_REPLACED("hwdec-software-fallback")}, |
| 159 | + {0} |
| 160 | + }, |
| 161 | + .size = sizeof(struct hwdec_opts), |
| 162 | + .defaults = &(const struct hwdec_opts){ |
| 163 | + .software_fallback = 3, |
| 142 | 164 | .hwdec_api = (char *[]){"no", NULL,}, |
| 143 | 165 | .hwdec_codecs = "h264,vc1,hevc,vp8,vp9,av1,prores", |
| 144 | 166 | // Maximum number of surfaces the player wants to buffer. This number |
| @@ -146,7 +168,6 @@ const struct m_sub_options vd_lavc_conf = { · 1 unmodified line |
| 146 | 168 | // for example, if vo_gpu increases the number of reference surfaces for |
| 147 | 169 | // interpolation, this value has to be increased too. |
| 148 | 170 | .hwdec_extra_frames = 6, |
| 149 | | − .apply_cropping = true, |
| 150 | 171 | }, |
| 151 | 172 | }; |
| 152 | 173 | |
| @@ -170,6 +191,8 @@ typedef struct lavc_ctx { · 17 unmodified lines |
| 170 | 191 | struct mp_log *log; |
| 171 | 192 | struct m_config_cache *opts_cache; |
| 172 | 193 | struct vd_lavc_params *opts; |
| 194 | + struct m_config_cache *hwdec_opts_cache; |
| 195 | + struct hwdec_opts *hwdec_opts; |
| 173 | 196 | struct mp_codec_params *codec; |
| 174 | 197 | AVCodecContext *avctx; |
| 175 | 198 | AVFrame *pic; |
| @@ -418,7 +441,7 @@ static void add_all_hwdec_methods(struct hwdec_info **infos, int *num_infos) · 242 unmodified lines |
| 418 | 441 | static bool hwdec_codec_allowed(struct mp_filter *vd, const char *codec) |
| 419 | 442 | { |
| 420 | 443 | vd_ffmpeg_ctx *ctx = vd->priv; |
| 421 | | − bstr s = bstr0(ctx->opts->hwdec_codecs); |
| 444 | + bstr s = bstr0(ctx->hwdec_opts->hwdec_codecs); |
| 422 | 445 | while (s.len) { |
| 423 | 446 | bstr item; |
| 424 | 447 | bstr_split_tok(s, ",", &item, &s); |
| @@ -473,13 +496,13 @@ static void select_and_set_hwdec(struct mp_filter *vd) · 48 unmodified lines |
| 473 | 496 | vd_ffmpeg_ctx *ctx = vd->priv; |
| 474 | 497 | const char *codec = ctx->codec->codec; |
| 475 | 498 | |
| 476 | | − m_config_cache_update(ctx->opts_cache); |
| 499 | + m_config_cache_update(ctx->hwdec_opts_cache); |
| 477 | 500 | |
| 478 | 501 | struct hwdec_info *hwdecs = NULL; |
| 479 | 502 | int num_hwdecs = 0; |
| 480 | 503 | add_all_hwdec_methods(&hwdecs, &num_hwdecs); |
| 481 | 504 | |
| 482 | | − char **hwdec_api = ctx->opts->hwdec_api; |
| 505 | + char **hwdec_api = ctx->hwdec_opts->hwdec_api; |
| 483 | 506 | for (int i = 0; hwdec_api && hwdec_api[i]; i++) { |
| 484 | 507 | bstr opt = bstr0(hwdec_api[i]); |
| 485 | 508 | |
| @@ -597,7 +620,7 @@ static void select_and_set_hwdec(struct mp_filter *vd) · 111 unmodified lines |
| 597 | 620 | } else { |
| 598 | 621 | // If software fallback is disabled and we get here, all hwdec must |
| 599 | 622 | // have failed. Tell the ctx to always force an eof. |
| 600 | | − if (ctx->opts->software_fallback == INT_MAX) { |
| 623 | + if (ctx->hwdec_opts->software_fallback == INT_MAX) { |
| 601 | 624 | MP_WARN(ctx, "Software decoding fallback is disabled.\n"); |
| 602 | 625 | ctx->force_eof = true; |
| 603 | 626 | } else { |
| @@ -905,13 +928,13 @@ static int init_generic_hwaccel(struct mp_filter *vd, enum AVPixelFormat hw_fmt) · 301 unmodified lines |
| 905 | 928 | |
| 906 | 929 | AVHWFramesContext *new_fctx = (void *)new_frames_ctx->data; |
| 907 | 930 | |
| 908 | | − if (ctx->opts->hwdec_image_format) |
| 909 | | − new_fctx->sw_format = imgfmt2pixfmt(ctx->opts->hwdec_image_format); |
| 931 | + if (ctx->hwdec_opts->hwdec_image_format) |
| 932 | + new_fctx->sw_format = imgfmt2pixfmt(ctx->hwdec_opts->hwdec_image_format); |
| 910 | 933 | |
| 911 | 934 | // 1 surface is already included by libavcodec. The field is 0 if the |
| 912 | 935 | // hwaccel supports dynamic surface allocation. |
| 913 | 936 | if (new_fctx->initial_pool_size) |
| 914 | | − new_fctx->initial_pool_size += ctx->opts->hwdec_extra_frames - 1; |
| 937 | + new_fctx->initial_pool_size += ctx->hwdec_opts->hwdec_extra_frames - 1; |
| 915 | 938 | |
| 916 | 939 | const struct hwcontext_fns *fns = |
| 917 | 940 | hwdec_get_hwcontext_fns(new_fctx->device_ctx->type); |
| @@ -1112,14 +1135,14 @@ static void prepare_decoding(struct mp_filter *vd) · 194 unmodified lines |
| 1112 | 1135 | static void handle_err(struct mp_filter *vd) |
| 1113 | 1136 | { |
| 1114 | 1137 | vd_ffmpeg_ctx *ctx = vd->priv; |
| 1115 | | − struct vd_lavc_params *opts = ctx->opts; |
| 1138 | + struct hwdec_opts *hwdec_opts = ctx->hwdec_opts; |
| 1116 | 1139 | |
| 1117 | 1140 | MP_WARN(vd, "Error while decoding frame%s!\n", |
| 1118 | 1141 | ctx->use_hwdec ? " (hardware decoding)" : ""); |
| 1119 | 1142 | |
| 1120 | 1143 | if (ctx->use_hwdec) { |
| 1121 | 1144 | ctx->hwdec_fail_count += 1; |
| 1122 | | − if (ctx->hwdec_fail_count >= opts->software_fallback) |
| 1145 | + if (ctx->hwdec_fail_count >= hwdec_opts->software_fallback) |
| 1123 | 1146 | ctx->hwdec_failed = true; |
| 1124 | 1147 | } |
| 1125 | 1148 | } |
| @@ -1150,7 +1173,7 @@ static int send_packet(struct mp_filter *vd, struct demux_packet *pkt) · 24 unmodified lines |
| 1150 | 1173 | return ret; |
| 1151 | 1174 | |
| 1152 | 1175 | if (ctx->hw_probing && ctx->num_sent_packets < 32 && |
| 1153 | | − ctx->opts->software_fallback <= 32) |
| 1176 | + ctx->hwdec_opts->software_fallback <= 32) |
| 1154 | 1177 | { |
| 1155 | 1178 | pkt = pkt ? demux_copy_packet(pkt) : NULL; |
| 1156 | 1179 | MP_TARRAY_APPEND(ctx, ctx->sent_packets, ctx->num_sent_packets, pkt); |
| @@ -1406,6 +1429,8 @@ static struct mp_decoder *create(struct mp_filter *parent, · 249 unmodified lines |
| 1406 | 1429 | ctx->log = vd->log; |
| 1407 | 1430 | ctx->opts_cache = m_config_cache_alloc(ctx, vd->global, &vd_lavc_conf); |
| 1408 | 1431 | ctx->opts = ctx->opts_cache->opts; |
| 1432 | + ctx->hwdec_opts_cache = m_config_cache_alloc(ctx, vd->global, &hwdec_conf); |
| 1433 | + ctx->hwdec_opts = ctx->hwdec_opts_cache->opts; |
| 1409 | 1434 | ctx->codec = codec; |
| 1410 | 1435 | ctx->decoder = talloc_strdup(ctx, decoder); |
| 1411 | 1436 | ctx->hwdec_swpool = mp_image_pool_new(ctx); |