| @@ -81,13 +81,8 @@ struct vd_lavc_params { · 80 unmodified lines |
| 81 | bool old_x264; | 81 | bool old_x264; |
| 82 | bool apply_cropping; | 82 | bool apply_cropping; |
| 83 | bool check_hw_profile; | 83 | bool check_hw_profile; |
| 84 | int software_fallback; | | |
| 85 | char **avopts; | 84 | char **avopts; |
| 86 | int dr; | 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 | static const struct m_opt_choice_alternatives discard_names[] = { | 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 | {"vd-lavc-skipidct", OPT_DISCARD(skip_idct)}, | 106 | {"vd-lavc-skipidct", OPT_DISCARD(skip_idct)}, |
| 112 | {"vd-lavc-skipframe", OPT_DISCARD(skip_frame)}, | 107 | {"vd-lavc-skipframe", OPT_DISCARD(skip_frame)}, |
| 113 | {"vd-lavc-framedrop", OPT_DISCARD(framedrop)}, | 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 | {"vd-lavc-bitexact", OPT_BOOL(bitexact)}, | 110 | {"vd-lavc-bitexact", OPT_BOOL(bitexact)}, |
| 116 | {"vd-lavc-assume-old-x264", OPT_BOOL(old_x264)}, | 111 | {"vd-lavc-assume-old-x264", OPT_BOOL(old_x264)}, |
| 117 | {"vd-lavc-check-hw-profile", OPT_BOOL(check_hw_profile)}, | 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 | {"vd-lavc-o", OPT_KEYVALUELIST(avopts)}, | 113 | {"vd-lavc-o", OPT_KEYVALUELIST(avopts)}, |
| 121 | {"vd-lavc-dr", OPT_CHOICE(dr, | 114 | {"vd-lavc-dr", OPT_CHOICE(dr, |
| 122 | {"auto", -1}, {"no", 0}, {"yes", 1})}, | 115 | {"auto", -1}, {"no", 0}, {"yes", 1})}, |
| 123 | {"vd-apply-cropping", OPT_BOOL(apply_cropping)}, | 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 | {0} | 117 | {0} |
| 131 | }, | 118 | }, |
| | 119 | .change_flags = UPDATE_VD, |
| 132 | .size = sizeof(struct vd_lavc_params), | 120 | .size = sizeof(struct vd_lavc_params), |
| 133 | .defaults = &(const struct vd_lavc_params){ | 121 | .defaults = &(const struct vd_lavc_params){ |
| 134 | .film_grain = -1 /*auto*/, | 122 | .film_grain = -1 /*auto*/, |
| 135 | .check_hw_profile = true, | 123 | .check_hw_profile = true, |
| 136 | .software_fallback = 3, | | |
| 137 | .skip_loop_filter = AVDISCARD_DEFAULT, | 124 | .skip_loop_filter = AVDISCARD_DEFAULT, |
| 138 | .skip_idct = AVDISCARD_DEFAULT, | 125 | .skip_idct = AVDISCARD_DEFAULT, |
| 139 | .skip_frame = AVDISCARD_DEFAULT, | 126 | .skip_frame = AVDISCARD_DEFAULT, |
| 140 | .framedrop = AVDISCARD_NONREF, | 127 | .framedrop = AVDISCARD_NONREF, |
| 141 | .dr = -1, | 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 | .hwdec_api = (char *[]){"no", NULL,}, | 164 | .hwdec_api = (char *[]){"no", NULL,}, |
| 143 | .hwdec_codecs = "h264,vc1,hevc,vp8,vp9,av1,prores", | 165 | .hwdec_codecs = "h264,vc1,hevc,vp8,vp9,av1,prores", |
| 144 | // Maximum number of surfaces the player wants to buffer. This number | 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 | // for example, if vo_gpu increases the number of reference surfaces for | 168 | // for example, if vo_gpu increases the number of reference surfaces for |
| 147 | // interpolation, this value has to be increased too. | 169 | // interpolation, this value has to be increased too. |
| 148 | .hwdec_extra_frames = 6, | 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 | struct mp_log *log; | 191 | struct mp_log *log; |
| 171 | struct m_config_cache *opts_cache; | 192 | struct m_config_cache *opts_cache; |
| 172 | struct vd_lavc_params *opts; | 193 | struct vd_lavc_params *opts; |
| | 194 | struct m_config_cache *hwdec_opts_cache; |
| | 195 | struct hwdec_opts *hwdec_opts; |
| 173 | struct mp_codec_params *codec; | 196 | struct mp_codec_params *codec; |
| 174 | AVCodecContext *avctx; | 197 | AVCodecContext *avctx; |
| 175 | AVFrame *pic; | 198 | AVFrame *pic; |
| @@ -418,7 +441,7 @@ static void add_all_hwdec_methods(struct hwdec_info **infos, int *num_infos) · 242 unmodified lines |
| 418 | static bool hwdec_codec_allowed(struct mp_filter *vd, const char *codec) | 441 | static bool hwdec_codec_allowed(struct mp_filter *vd, const char *codec) |
| 419 | { | 442 | { |
| 420 | vd_ffmpeg_ctx *ctx = vd->priv; | 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 | while (s.len) { | 445 | while (s.len) { |
| 423 | bstr item; | 446 | bstr item; |
| 424 | bstr_split_tok(s, ",", &item, &s); | 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 | vd_ffmpeg_ctx *ctx = vd->priv; | 496 | vd_ffmpeg_ctx *ctx = vd->priv; |
| 474 | const char *codec = ctx->codec->codec; | 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 | struct hwdec_info *hwdecs = NULL; | 501 | struct hwdec_info *hwdecs = NULL; |
| 479 | int num_hwdecs = 0; | 502 | int num_hwdecs = 0; |
| 480 | add_all_hwdec_methods(&hwdecs, &num_hwdecs); | 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 | for (int i = 0; hwdec_api && hwdec_api[i]; i++) { | 506 | for (int i = 0; hwdec_api && hwdec_api[i]; i++) { |
| 484 | bstr opt = bstr0(hwdec_api[i]); | 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 | } else { | 620 | } else { |
| 598 | // If software fallback is disabled and we get here, all hwdec must | 621 | // If software fallback is disabled and we get here, all hwdec must |
| 599 | // have failed. Tell the ctx to always force an eof. | 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 | MP_WARN(ctx, "Software decoding fallback is disabled.\n"); | 624 | MP_WARN(ctx, "Software decoding fallback is disabled.\n"); |
| 602 | ctx->force_eof = true; | 625 | ctx->force_eof = true; |
| 603 | } else { | 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 | AVHWFramesContext *new_fctx = (void *)new_frames_ctx->data; | 929 | AVHWFramesContext *new_fctx = (void *)new_frames_ctx->data; |
| 907 | | 930 | |
| 908 | if (ctx->opts->hwdec_image_format) | 931 | if (ctx->hwdec_opts->hwdec_image_format) |
| 909 | new_fctx->sw_format = imgfmt2pixfmt(ctx->opts->hwdec_image_format); | 932 | new_fctx->sw_format = imgfmt2pixfmt(ctx->hwdec_opts->hwdec_image_format); |
| 910 | | 933 | |
| 911 | // 1 surface is already included by libavcodec. The field is 0 if the | 934 | // 1 surface is already included by libavcodec. The field is 0 if the |
| 912 | // hwaccel supports dynamic surface allocation. | 935 | // hwaccel supports dynamic surface allocation. |
| 913 | if (new_fctx->initial_pool_size) | 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 | const struct hwcontext_fns *fns = | 939 | const struct hwcontext_fns *fns = |
| 917 | hwdec_get_hwcontext_fns(new_fctx->device_ctx->type); | 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 | static void handle_err(struct mp_filter *vd) | 1135 | static void handle_err(struct mp_filter *vd) |
| 1113 | { | 1136 | { |
| 1114 | vd_ffmpeg_ctx *ctx = vd->priv; | 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 | MP_WARN(vd, "Error while decoding frame%s!\n", | 1140 | MP_WARN(vd, "Error while decoding frame%s!\n", |
| 1118 | ctx->use_hwdec ? " (hardware decoding)" : ""); | 1141 | ctx->use_hwdec ? " (hardware decoding)" : ""); |
| 1119 | | 1142 | |
| 1120 | if (ctx->use_hwdec) { | 1143 | if (ctx->use_hwdec) { |
| 1121 | ctx->hwdec_fail_count += 1; | 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 | ctx->hwdec_failed = true; | 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 | return ret; | 1173 | return ret; |
| 1151 | | 1174 | |
| 1152 | if (ctx->hw_probing && ctx->num_sent_packets < 32 && | 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 | pkt = pkt ? demux_copy_packet(pkt) : NULL; | 1178 | pkt = pkt ? demux_copy_packet(pkt) : NULL; |
| 1156 | MP_TARRAY_APPEND(ctx, ctx->sent_packets, ctx->num_sent_packets, pkt); | 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 | ctx->log = vd->log; | 1429 | ctx->log = vd->log; |
| 1407 | ctx->opts_cache = m_config_cache_alloc(ctx, vd->global, &vd_lavc_conf); | 1430 | ctx->opts_cache = m_config_cache_alloc(ctx, vd->global, &vd_lavc_conf); |
| 1408 | ctx->opts = ctx->opts_cache->opts; | 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 | ctx->codec = codec; | 1434 | ctx->codec = codec; |
| 1410 | ctx->decoder = talloc_strdup(ctx, decoder); | 1435 | ctx->decoder = talloc_strdup(ctx, decoder); |
| 1411 | ctx->hwdec_swpool = mp_image_pool_new(ctx); | 1436 | ctx->hwdec_swpool = mp_image_pool_new(ctx); |