mirror of
https://github.com/mpv-player/mpv
synced 2025-04-01 23:00:41 +00:00
drm_common: Add proper help option to drm-mode
This was implemented by using OPT_STRING_VALIDATE for drm-mode, instead of OPT_INT. Using a string here also prepares for future additions to drm-mode that aim to allow specifying a mode by its resolution.
This commit is contained in:
parent
a776628d88
commit
8261924db9
@ -479,13 +479,14 @@ Available video output drivers are:
|
|||||||
``--drm-connector=[<gpu_number>.]<name>``
|
``--drm-connector=[<gpu_number>.]<name>``
|
||||||
Select the connector to use (usually this is a monitor.) If ``<name>``
|
Select the connector to use (usually this is a monitor.) If ``<name>``
|
||||||
is empty or ``auto``, mpv renders the output on the first available
|
is empty or ``auto``, mpv renders the output on the first available
|
||||||
connector. Use ``--drm-connector=help`` to get list of available
|
connector. Use ``--drm-connector=help`` to get a list of available
|
||||||
connectors. When using multiple graphic cards, use the ``<gpu_number>``
|
connectors. When using multiple graphic cards, use the ``<gpu_number>``
|
||||||
argument to disambiguate.
|
argument to disambiguate.
|
||||||
(default: empty)
|
(default: empty)
|
||||||
|
|
||||||
``--drm-mode=<number>``
|
``--drm-mode=<number>``
|
||||||
Mode ID to use (resolution and frame rate).
|
Mode ID to use (resolution and frame rate). Use ``--drm-mode=help`` to
|
||||||
|
get a list of available modes for all active connectors.
|
||||||
(default: 0)
|
(default: 0)
|
||||||
|
|
||||||
``--drm-atomic=<no|auto>``
|
``--drm-atomic=<no|auto>``
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
#include "osdep/io.h"
|
#include "osdep/io.h"
|
||||||
|
#include "misc/ctype.h"
|
||||||
|
|
||||||
#define EVT_RELEASE 1
|
#define EVT_RELEASE 1
|
||||||
#define EVT_ACQUIRE 2
|
#define EVT_ACQUIRE 2
|
||||||
@ -47,7 +48,8 @@ const struct m_sub_options drm_conf = {
|
|||||||
.opts = (const struct m_option[]) {
|
.opts = (const struct m_option[]) {
|
||||||
OPT_STRING_VALIDATE("drm-connector", drm_connector_spec,
|
OPT_STRING_VALIDATE("drm-connector", drm_connector_spec,
|
||||||
0, drm_validate_connector_opt),
|
0, drm_validate_connector_opt),
|
||||||
OPT_INT("drm-mode", drm_mode_id, 0),
|
OPT_STRING_VALIDATE("drm-mode", drm_mode_spec,
|
||||||
|
0, drm_validate_mode_opt),
|
||||||
OPT_CHOICE("drm-atomic", drm_atomic, 0,
|
OPT_CHOICE("drm-atomic", drm_atomic, 0,
|
||||||
({"no", 0},
|
({"no", 0},
|
||||||
{"auto", 1})),
|
{"auto", 1})),
|
||||||
@ -98,8 +100,8 @@ static const char *connector_names[] = {
|
|||||||
|
|
||||||
// KMS ------------------------------------------------------------------------
|
// KMS ------------------------------------------------------------------------
|
||||||
|
|
||||||
static void get_connector_name(
|
static void get_connector_name(const drmModeConnector *connector,
|
||||||
drmModeConnector *connector, char ret[MAX_CONNECTOR_NAME_LEN])
|
char ret[MAX_CONNECTOR_NAME_LEN])
|
||||||
{
|
{
|
||||||
snprintf(ret, MAX_CONNECTOR_NAME_LEN, "%s-%d",
|
snprintf(ret, MAX_CONNECTOR_NAME_LEN, "%s-%d",
|
||||||
connector_names[connector->connector_type],
|
connector_names[connector->connector_type],
|
||||||
@ -240,12 +242,15 @@ static bool setup_crtc(struct kms *kms, const drmModeRes *res)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool setup_mode(struct kms *kms, int mode_id)
|
static bool setup_mode(struct kms *kms, const char *mode_spec)
|
||||||
{
|
{
|
||||||
|
const int mode_id = (mode_spec != NULL) ? atoi(mode_spec) : 0;
|
||||||
|
|
||||||
if (mode_id < 0 || mode_id >= kms->connector->count_modes) {
|
if (mode_id < 0 || mode_id >= kms->connector->count_modes) {
|
||||||
MP_ERR(kms, "Bad mode ID (max = %d).\n",
|
MP_ERR(kms, "Bad mode ID (max = %d).\n",
|
||||||
kms->connector->count_modes - 1);
|
kms->connector->count_modes - 1);
|
||||||
|
|
||||||
|
MP_INFO(kms, "Available modes:\n");
|
||||||
kms_show_available_modes(kms->log, kms->connector);
|
kms_show_available_modes(kms->log, kms->connector);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -281,7 +286,8 @@ static void parse_connector_spec(struct mp_log *log,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct kms *kms_create(struct mp_log *log, const char *connector_spec,
|
struct kms *kms_create(struct mp_log *log, const char *connector_spec,
|
||||||
int mode_id, int draw_plane, int drmprime_video_plane,
|
const char* mode_spec,
|
||||||
|
int draw_plane, int drmprime_video_plane,
|
||||||
bool use_atomic)
|
bool use_atomic)
|
||||||
{
|
{
|
||||||
int card_no = -1;
|
int card_no = -1;
|
||||||
@ -317,7 +323,7 @@ struct kms *kms_create(struct mp_log *log, const char *connector_spec,
|
|||||||
goto err;
|
goto err;
|
||||||
if (!setup_crtc(kms, res))
|
if (!setup_crtc(kms, res))
|
||||||
goto err;
|
goto err;
|
||||||
if (!setup_mode(kms, mode_id))
|
if (!setup_mode(kms, mode_spec))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
// Universal planes allows accessing all the planes (including primary)
|
// Universal planes allows accessing all the planes (including primary)
|
||||||
@ -381,9 +387,8 @@ static double mode_get_Hz(const drmModeModeInfo *mode)
|
|||||||
void kms_show_available_modes(
|
void kms_show_available_modes(
|
||||||
struct mp_log *log, const drmModeConnector *connector)
|
struct mp_log *log, const drmModeConnector *connector)
|
||||||
{
|
{
|
||||||
mp_info(log, "Available modes:\n");
|
|
||||||
for (unsigned int i = 0; i < connector->count_modes; i++) {
|
for (unsigned int i = 0; i < connector->count_modes; i++) {
|
||||||
mp_info(log, "Mode %d: %s (%dx%d@%.2fHz)\n", i,
|
mp_info(log, " Mode %d: %s (%dx%d@%.2fHz)\n", i,
|
||||||
connector->modes[i].name,
|
connector->modes[i].name,
|
||||||
connector->modes[i].hdisplay,
|
connector->modes[i].hdisplay,
|
||||||
connector->modes[i].vdisplay,
|
connector->modes[i].vdisplay,
|
||||||
@ -391,10 +396,10 @@ void kms_show_available_modes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void kms_show_available_connectors(struct mp_log *log, int card_no)
|
static void kms_show_foreach_connector(struct mp_log *log, int card_no,
|
||||||
|
void (*show_fn)(struct mp_log*, int,
|
||||||
|
const drmModeConnector*))
|
||||||
{
|
{
|
||||||
mp_info(log, "Available connectors for card %d:\n", card_no);
|
|
||||||
|
|
||||||
int fd = open_card(card_no);
|
int fd = open_card(card_no);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
mp_err(log, "Failed to open card %d\n", card_no);
|
mp_err(log, "Failed to open card %d\n", card_no);
|
||||||
@ -412,12 +417,7 @@ void kms_show_available_connectors(struct mp_log *log, int card_no)
|
|||||||
= drmModeGetConnector(fd, res->connectors[i]);
|
= drmModeGetConnector(fd, res->connectors[i]);
|
||||||
if (!connector)
|
if (!connector)
|
||||||
continue;
|
continue;
|
||||||
char other_connector_name[MAX_CONNECTOR_NAME_LEN];
|
show_fn(log, card_no, connector);
|
||||||
get_connector_name(connector, other_connector_name);
|
|
||||||
mp_info(log, "%s (%s)\n", other_connector_name,
|
|
||||||
connector->connection == DRM_MODE_CONNECTED
|
|
||||||
? "connected"
|
|
||||||
: "disconnected");
|
|
||||||
drmModeFreeConnector(connector);
|
drmModeFreeConnector(connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,17 +428,65 @@ err:
|
|||||||
drmModeFreeResources(res);
|
drmModeFreeResources(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kms_show_available_cards_and_connectors(struct mp_log *log)
|
static void kms_show_connector_name_and_state_callback(
|
||||||
|
struct mp_log *log, int card_no, const drmModeConnector *connector)
|
||||||
|
{
|
||||||
|
char other_connector_name[MAX_CONNECTOR_NAME_LEN];
|
||||||
|
get_connector_name(connector, other_connector_name);
|
||||||
|
const char *connection_str =
|
||||||
|
(connector->connection == DRM_MODE_CONNECTED) ? "connected" : "disconnected";
|
||||||
|
mp_info(log, " %s (%s)\n", other_connector_name, connection_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void kms_show_available_connectors(struct mp_log *log, int card_no)
|
||||||
|
{
|
||||||
|
mp_info(log, "Available connectors for card %d:\n", card_no);
|
||||||
|
kms_show_foreach_connector(
|
||||||
|
log, card_no, kms_show_connector_name_and_state_callback);
|
||||||
|
mp_info(log, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kms_show_connector_modes_callback(struct mp_log *log, int card_no,
|
||||||
|
const drmModeConnector *connector)
|
||||||
|
{
|
||||||
|
if (connector->connection != DRM_MODE_CONNECTED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char other_connector_name[MAX_CONNECTOR_NAME_LEN];
|
||||||
|
get_connector_name(connector, other_connector_name);
|
||||||
|
mp_info(log, "Available modes for drm-connector=%d.%s\n",
|
||||||
|
card_no, other_connector_name);
|
||||||
|
kms_show_available_modes(log, connector);
|
||||||
|
mp_info(log, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void kms_show_available_connectors_and_modes(struct mp_log *log, int card_no)
|
||||||
|
{
|
||||||
|
kms_show_foreach_connector(log, card_no, kms_show_connector_modes_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kms_show_foreach_card(
|
||||||
|
struct mp_log *log, void (*show_fn)(struct mp_log*,int))
|
||||||
{
|
{
|
||||||
for (int card_no = 0; card_no < DRM_MAX_MINOR; card_no++) {
|
for (int card_no = 0; card_no < DRM_MAX_MINOR; card_no++) {
|
||||||
int fd = open_card(card_no);
|
int fd = open_card(card_no);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
break;
|
break;
|
||||||
close(fd);
|
close(fd);
|
||||||
kms_show_available_connectors(log, card_no);
|
show_fn(log, card_no);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kms_show_available_cards_and_connectors(struct mp_log *log)
|
||||||
|
{
|
||||||
|
kms_show_foreach_card(log, kms_show_available_connectors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void kms_show_available_cards_connectors_and_modes(struct mp_log *log)
|
||||||
|
{
|
||||||
|
kms_show_foreach_card(log, kms_show_available_connectors_and_modes);
|
||||||
|
}
|
||||||
|
|
||||||
double kms_get_display_fps(const struct kms *kms)
|
double kms_get_display_fps(const struct kms *kms)
|
||||||
{
|
{
|
||||||
return mode_get_Hz(&kms->mode.mode);
|
return mode_get_Hz(&kms->mode.mode);
|
||||||
@ -454,7 +502,21 @@ int drm_validate_connector_opt(struct mp_log *log, const struct m_option *opt,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int drm_validate_mode_opt(struct mp_log *log, const struct m_option *opt,
|
||||||
|
struct bstr name, struct bstr param)
|
||||||
|
{
|
||||||
|
if (bstr_equals0(param, "help")) {
|
||||||
|
kms_show_available_cards_connectors_and_modes(log);
|
||||||
|
return M_OPT_EXIT;
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < param.len; ++i) {
|
||||||
|
if (!mp_isdigit(param.start[i])) {
|
||||||
|
mp_fatal(log, "Invalid value for option drm-mode. Must be a positive number or 'help'\n");
|
||||||
|
return M_OPT_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// VT switcher ----------------------------------------------------------------
|
// VT switcher ----------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ struct vt_switcher {
|
|||||||
|
|
||||||
struct drm_opts {
|
struct drm_opts {
|
||||||
char *drm_connector_spec;
|
char *drm_connector_spec;
|
||||||
int drm_mode_id;
|
char *drm_mode_spec;
|
||||||
int drm_atomic;
|
int drm_atomic;
|
||||||
int drm_draw_plane;
|
int drm_draw_plane;
|
||||||
int drm_drmprime_video_plane;
|
int drm_drmprime_video_plane;
|
||||||
@ -66,7 +66,8 @@ void vt_switcher_release(struct vt_switcher *s, void (*handler)(void*),
|
|||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
struct kms *kms_create(struct mp_log *log, const char *connector_spec,
|
struct kms *kms_create(struct mp_log *log, const char *connector_spec,
|
||||||
int mode_id, int draw_plane, int drmprime_video_plane,
|
const char *mode_spec,
|
||||||
|
int draw_plane, int drmprime_video_plane,
|
||||||
bool use_atomic);
|
bool use_atomic);
|
||||||
void kms_destroy(struct kms *kms);
|
void kms_destroy(struct kms *kms);
|
||||||
double kms_get_display_fps(const struct kms *kms);
|
double kms_get_display_fps(const struct kms *kms);
|
||||||
@ -74,9 +75,14 @@ double kms_get_display_fps(const struct kms *kms);
|
|||||||
void kms_show_available_connectors(struct mp_log *log, int card_no);
|
void kms_show_available_connectors(struct mp_log *log, int card_no);
|
||||||
void kms_show_available_modes(struct mp_log *log,
|
void kms_show_available_modes(struct mp_log *log,
|
||||||
const drmModeConnector *connector);
|
const drmModeConnector *connector);
|
||||||
|
void kms_show_available_connectors_and_modes(struct mp_log *log, int card_no);
|
||||||
void kms_show_available_cards_and_connectors(struct mp_log *log);
|
void kms_show_available_cards_and_connectors(struct mp_log *log);
|
||||||
|
void kms_show_available_cards_connectors_and_modes(struct mp_log *log);
|
||||||
|
|
||||||
int drm_validate_connector_opt(struct mp_log *log, const struct m_option *opt,
|
int drm_validate_connector_opt(struct mp_log *log, const struct m_option *opt,
|
||||||
struct bstr name, struct bstr param);
|
struct bstr name, struct bstr param);
|
||||||
|
|
||||||
|
int drm_validate_mode_opt(struct mp_log *log, const struct m_option *opt,
|
||||||
|
struct bstr name, struct bstr param);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -764,7 +764,7 @@ static bool drm_egl_init(struct ra_ctx *ctx)
|
|||||||
|
|
||||||
MP_VERBOSE(ctx, "Initializing KMS\n");
|
MP_VERBOSE(ctx, "Initializing KMS\n");
|
||||||
p->kms = kms_create(ctx->log, ctx->vo->opts->drm_opts->drm_connector_spec,
|
p->kms = kms_create(ctx->log, ctx->vo->opts->drm_opts->drm_connector_spec,
|
||||||
ctx->vo->opts->drm_opts->drm_mode_id,
|
ctx->vo->opts->drm_opts->drm_mode_spec,
|
||||||
ctx->vo->opts->drm_opts->drm_draw_plane,
|
ctx->vo->opts->drm_opts->drm_draw_plane,
|
||||||
ctx->vo->opts->drm_opts->drm_drmprime_video_plane,
|
ctx->vo->opts->drm_opts->drm_drmprime_video_plane,
|
||||||
ctx->vo->opts->drm_opts->drm_atomic);
|
ctx->vo->opts->drm_opts->drm_atomic);
|
||||||
|
@ -419,7 +419,7 @@ static int preinit(struct vo *vo)
|
|||||||
|
|
||||||
p->kms = kms_create(vo->log,
|
p->kms = kms_create(vo->log,
|
||||||
vo->opts->drm_opts->drm_connector_spec,
|
vo->opts->drm_opts->drm_connector_spec,
|
||||||
vo->opts->drm_opts->drm_mode_id,
|
vo->opts->drm_opts->drm_mode_spec,
|
||||||
0, 0, false);
|
0, 0, false);
|
||||||
if (!p->kms) {
|
if (!p->kms) {
|
||||||
MP_ERR(vo, "Failed to create KMS.\n");
|
MP_ERR(vo, "Failed to create KMS.\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user