mirror of
https://github.com/mpv-player/mpv
synced 2024-12-29 02:22:19 +00:00
vd_lavc: fix codec vs. decoder confusion
Some functions which expected a codec name (i.e. the name of the video format itself) were passed a decoder name. Most "native" libavcodec decoders have the same name as the codec, so this was never an issue. This should mean that e.g. using "--vd=lavc:h264_mmal --hwdec=mmal" should now actually enable native surface mode (instead of doing copy- back).
This commit is contained in:
parent
32a92071b4
commit
f009d16f36
@ -97,9 +97,9 @@ static const struct d3dva_mode d3dva_modes[] = {
|
|||||||
#undef MODE
|
#undef MODE
|
||||||
#undef MODE2
|
#undef MODE2
|
||||||
|
|
||||||
int d3d_probe_codec(const char *decoder)
|
int d3d_probe_codec(const char *codec)
|
||||||
{
|
{
|
||||||
enum AVCodecID codec = mp_codec_to_av_codec_id(decoder);
|
enum AVCodecID codec = mp_codec_to_av_codec_id(codec);
|
||||||
for (int i = 0; i < MP_ARRAY_SIZE(d3dva_modes); i++) {
|
for (int i = 0; i < MP_ARRAY_SIZE(d3dva_modes); i++) {
|
||||||
const struct d3dva_mode *mode = &d3dva_modes[i];
|
const struct d3dva_mode *mode = &d3dva_modes[i];
|
||||||
if (mode->codec == codec)
|
if (mode->codec == codec)
|
||||||
|
@ -30,7 +30,7 @@ struct d3d_decoder_fmt {
|
|||||||
DWORD dxfmt_decoded; // D3DFORMAT or DXGI_FORMAT
|
DWORD dxfmt_decoded; // D3DFORMAT or DXGI_FORMAT
|
||||||
};
|
};
|
||||||
|
|
||||||
int d3d_probe_codec(const char *decode);
|
int d3d_probe_codec(const char *codec);
|
||||||
struct d3d_decoder_fmt d3d_select_decoder_mode(
|
struct d3d_decoder_fmt d3d_select_decoder_mode(
|
||||||
struct lavc_ctx *s, const GUID *device_guids, UINT n_guids,
|
struct lavc_ctx *s, const GUID *device_guids, UINT n_guids,
|
||||||
DWORD (*get_dxfmt_cb)(struct lavc_ctx *s, const GUID *guid, int depth));
|
DWORD (*get_dxfmt_cb)(struct lavc_ctx *s, const GUID *guid, int depth));
|
||||||
|
@ -480,10 +480,10 @@ fail:
|
|||||||
|
|
||||||
static int d3d11va_probe(struct vd_lavc_hwdec *hwdec,
|
static int d3d11va_probe(struct vd_lavc_hwdec *hwdec,
|
||||||
struct mp_hwdec_info *info,
|
struct mp_hwdec_info *info,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
hwdec_request_api(info, "d3d11va");
|
hwdec_request_api(info, "d3d11va");
|
||||||
return d3d_probe_codec(decoder);
|
return d3d_probe_codec(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy = {
|
const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy = {
|
||||||
|
@ -485,7 +485,7 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int dxva2_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
static int dxva2_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
hwdec_request_api(info, "dxva2");
|
hwdec_request_api(info, "dxva2");
|
||||||
// dxva2-copy can do without external context; dxva2 requires it.
|
// dxva2-copy can do without external context; dxva2 requires it.
|
||||||
@ -494,7 +494,7 @@ static int dxva2_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
|||||||
info->hwctx->type == HWDEC_DXVA2_COPY)
|
info->hwctx->type == HWDEC_DXVA2_COPY)
|
||||||
return HWDEC_ERR_NO_CTX;
|
return HWDEC_ERR_NO_CTX;
|
||||||
}
|
}
|
||||||
return d3d_probe_codec(decoder);
|
return d3d_probe_codec(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct vd_lavc_hwdec mp_vd_lavc_dxva2 = {
|
const struct vd_lavc_hwdec mp_vd_lavc_dxva2 = {
|
||||||
|
@ -50,7 +50,7 @@ struct vd_lavc_hwdec {
|
|||||||
// get_format callback.
|
// get_format callback.
|
||||||
int image_format;
|
int image_format;
|
||||||
int (*probe)(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
int (*probe)(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
const char *decoder);
|
const char *codec);
|
||||||
int (*init)(struct lavc_ctx *ctx);
|
int (*init)(struct lavc_ctx *ctx);
|
||||||
int (*init_decoder)(struct lavc_ctx *ctx, int w, int h);
|
int (*init_decoder)(struct lavc_ctx *ctx, int w, int h);
|
||||||
void (*uninit)(struct lavc_ctx *ctx);
|
void (*uninit)(struct lavc_ctx *ctx);
|
||||||
@ -80,7 +80,7 @@ struct hwdec_profile_entry {
|
|||||||
|
|
||||||
const struct hwdec_profile_entry *hwdec_find_profile(
|
const struct hwdec_profile_entry *hwdec_find_profile(
|
||||||
struct lavc_ctx *ctx, const struct hwdec_profile_entry *table);
|
struct lavc_ctx *ctx, const struct hwdec_profile_entry *table);
|
||||||
bool hwdec_check_codec_support(const char *decoder,
|
bool hwdec_check_codec_support(const char *codec,
|
||||||
const struct hwdec_profile_entry *table);
|
const struct hwdec_profile_entry *table);
|
||||||
int hwdec_get_max_refs(struct lavc_ctx *ctx);
|
int hwdec_get_max_refs(struct lavc_ctx *ctx);
|
||||||
|
|
||||||
|
@ -50,9 +50,9 @@ static int init(struct lavc_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
return map_codec(decoder) ? 0 : HWDEC_ERR_NO_CODEC;
|
return map_codec(codec) ? 0 : HWDEC_ERR_NO_CODEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *get_codec(struct lavc_ctx *ctx, const char *codec)
|
static const char *get_codec(struct lavc_ctx *ctx, const char *codec)
|
||||||
|
@ -431,12 +431,12 @@ static int init(struct lavc_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
hwdec_request_api(info, "vaapi");
|
hwdec_request_api(info, "vaapi");
|
||||||
if (!info || !info->hwctx || !info->hwctx->vaapi_ctx)
|
if (!info || !info->hwctx || !info->hwctx->vaapi_ctx)
|
||||||
return HWDEC_ERR_NO_CTX;
|
return HWDEC_ERR_NO_CTX;
|
||||||
if (!hwdec_check_codec_support(decoder, profiles))
|
if (!hwdec_check_codec_support(codec, profiles))
|
||||||
return HWDEC_ERR_NO_CODEC;
|
return HWDEC_ERR_NO_CODEC;
|
||||||
if (va_guess_if_emulated(info->hwctx->vaapi_ctx))
|
if (va_guess_if_emulated(info->hwctx->vaapi_ctx))
|
||||||
return HWDEC_ERR_EMULATED;
|
return HWDEC_ERR_EMULATED;
|
||||||
@ -444,14 +444,14 @@ static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int probe_copy(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
static int probe_copy(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
struct priv dummy = {mp_null_log};
|
struct priv dummy = {mp_null_log};
|
||||||
if (!create_va_dummy_ctx(&dummy))
|
if (!create_va_dummy_ctx(&dummy))
|
||||||
return HWDEC_ERR_NO_CTX;
|
return HWDEC_ERR_NO_CTX;
|
||||||
bool emulated = va_guess_if_emulated(dummy.ctx);
|
bool emulated = va_guess_if_emulated(dummy.ctx);
|
||||||
destroy_va_dummy_ctx(&dummy);
|
destroy_va_dummy_ctx(&dummy);
|
||||||
if (!hwdec_check_codec_support(decoder, profiles))
|
if (!hwdec_check_codec_support(codec, profiles))
|
||||||
return HWDEC_ERR_NO_CODEC;
|
return HWDEC_ERR_NO_CODEC;
|
||||||
if (emulated)
|
if (emulated)
|
||||||
return HWDEC_ERR_EMULATED;
|
return HWDEC_ERR_EMULATED;
|
||||||
|
@ -214,12 +214,12 @@ const struct hwdec_profile_entry *hwdec_find_profile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check codec support, without checking the profile.
|
// Check codec support, without checking the profile.
|
||||||
bool hwdec_check_codec_support(const char *decoder,
|
bool hwdec_check_codec_support(const char *codec,
|
||||||
const struct hwdec_profile_entry *table)
|
const struct hwdec_profile_entry *table)
|
||||||
{
|
{
|
||||||
enum AVCodecID codec = mp_codec_to_av_codec_id(decoder);
|
enum AVCodecID codecid = mp_codec_to_av_codec_id(codec);
|
||||||
for (int n = 0; table[n].av_codec; n++) {
|
for (int n = 0; table[n].av_codec; n++) {
|
||||||
if (table[n].av_codec == codec)
|
if (table[n].av_codec == codecid)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -240,17 +240,17 @@ void hwdec_request_api(struct mp_hwdec_info *info, const char *api_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int hwdec_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
static int hwdec_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
if (hwdec->probe)
|
if (hwdec->probe)
|
||||||
r = hwdec->probe(hwdec, info, decoder);
|
r = hwdec->probe(hwdec, info, codec);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vd_lavc_hwdec *probe_hwdec(struct dec_video *vd, bool autoprobe,
|
static struct vd_lavc_hwdec *probe_hwdec(struct dec_video *vd, bool autoprobe,
|
||||||
enum hwdec_type api,
|
enum hwdec_type api,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
MP_VERBOSE(vd, "Probing '%s'...\n", m_opt_choice_str(mp_hwdec_names, api));
|
MP_VERBOSE(vd, "Probing '%s'...\n", m_opt_choice_str(mp_hwdec_names, api));
|
||||||
struct vd_lavc_hwdec *hwdec = find_hwcodec(api);
|
struct vd_lavc_hwdec *hwdec = find_hwcodec(api);
|
||||||
@ -258,7 +258,7 @@ static struct vd_lavc_hwdec *probe_hwdec(struct dec_video *vd, bool autoprobe,
|
|||||||
MP_VERBOSE(vd, "Requested hardware decoder not compiled.\n");
|
MP_VERBOSE(vd, "Requested hardware decoder not compiled.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int r = hwdec_probe(hwdec, vd->hwdec_info, decoder);
|
int r = hwdec_probe(hwdec, vd->hwdec_info, codec);
|
||||||
if (r == HWDEC_ERR_EMULATED) {
|
if (r == HWDEC_ERR_EMULATED) {
|
||||||
if (autoprobe)
|
if (autoprobe)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -269,8 +269,8 @@ static struct vd_lavc_hwdec *probe_hwdec(struct dec_video *vd, bool autoprobe,
|
|||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
return hwdec;
|
return hwdec;
|
||||||
} else if (r == HWDEC_ERR_NO_CODEC) {
|
} else if (r == HWDEC_ERR_NO_CODEC) {
|
||||||
MP_VERBOSE(vd, "Hardware decoder '%s' not found in libavcodec.\n",
|
MP_VERBOSE(vd, "Hardware decoder for '%s' with the given API not found "
|
||||||
decoder);
|
"in libavcodec.\n", codec);
|
||||||
} else if (r == HWDEC_ERR_NO_CTX && !autoprobe) {
|
} else if (r == HWDEC_ERR_NO_CTX && !autoprobe) {
|
||||||
MP_WARN(vd, "VO does not support requested hardware decoder, or "
|
MP_WARN(vd, "VO does not support requested hardware decoder, or "
|
||||||
"loading it failed.\n");
|
"loading it failed.\n");
|
||||||
@ -301,25 +301,26 @@ static void reinit(struct dec_video *vd)
|
|||||||
{
|
{
|
||||||
vd_ffmpeg_ctx *ctx = vd->priv;
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
||||||
const char *decoder = ctx->decoder;
|
const char *decoder = ctx->decoder;
|
||||||
|
const char *codec = vd->codec->codec;
|
||||||
|
|
||||||
uninit_avctx(vd);
|
uninit_avctx(vd);
|
||||||
|
|
||||||
struct vd_lavc_hwdec *hwdec = NULL;
|
struct vd_lavc_hwdec *hwdec = NULL;
|
||||||
|
|
||||||
if (hwdec_codec_allowed(vd, decoder)) {
|
if (hwdec_codec_allowed(vd, codec)) {
|
||||||
if (vd->opts->hwdec_api == HWDEC_AUTO) {
|
if (vd->opts->hwdec_api == HWDEC_AUTO) {
|
||||||
for (int n = 0; hwdec_list[n]; n++) {
|
for (int n = 0; hwdec_list[n]; n++) {
|
||||||
hwdec = probe_hwdec(vd, true, hwdec_list[n]->type, decoder);
|
hwdec = probe_hwdec(vd, true, hwdec_list[n]->type, codec);
|
||||||
if (hwdec)
|
if (hwdec)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (vd->opts->hwdec_api != HWDEC_NONE) {
|
} else if (vd->opts->hwdec_api != HWDEC_NONE) {
|
||||||
hwdec = probe_hwdec(vd, false, vd->opts->hwdec_api, decoder);
|
hwdec = probe_hwdec(vd, false, vd->opts->hwdec_api, codec);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MP_VERBOSE(vd, "Not trying to use hardware decoding: codec %s is not "
|
MP_VERBOSE(vd, "Not trying to use hardware decoding: codec %s is not "
|
||||||
"on whitelist, or does not support hardware acceleration.\n",
|
"on whitelist, or does not support hardware acceleration.\n",
|
||||||
decoder);
|
codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hwdec) {
|
if (hwdec) {
|
||||||
|
@ -84,7 +84,7 @@ static int init(struct lavc_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
hwdec_request_api(info, "vdpau");
|
hwdec_request_api(info, "vdpau");
|
||||||
if (!info || !info->hwctx || !info->hwctx->vdpau_ctx)
|
if (!info || !info->hwctx || !info->hwctx->vdpau_ctx)
|
||||||
|
@ -28,12 +28,12 @@
|
|||||||
|
|
||||||
|
|
||||||
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
const char *decoder)
|
const char *codec)
|
||||||
{
|
{
|
||||||
hwdec_request_api(info, "videotoolbox");
|
hwdec_request_api(info, "videotoolbox");
|
||||||
if (!info || !info->hwctx || info->hwctx->type != HWDEC_VIDEOTOOLBOX)
|
if (!info || !info->hwctx || info->hwctx->type != HWDEC_VIDEOTOOLBOX)
|
||||||
return HWDEC_ERR_NO_CTX;
|
return HWDEC_ERR_NO_CTX;
|
||||||
switch (mp_codec_to_av_codec_id(decoder)) {
|
switch (mp_codec_to_av_codec_id(codec)) {
|
||||||
case AV_CODEC_ID_H264:
|
case AV_CODEC_ID_H264:
|
||||||
case AV_CODEC_ID_H263:
|
case AV_CODEC_ID_H263:
|
||||||
case AV_CODEC_ID_MPEG1VIDEO:
|
case AV_CODEC_ID_MPEG1VIDEO:
|
||||||
|
Loading…
Reference in New Issue
Block a user