player/command: add video-codec-info and audio-codec-info

Adds support for extracting codec profile. Old properties are redirected
to new one and removed from docs. Likely will stay like that forever as
there is no reason to remove them.

As a effect of unification of properties between audio and video,
video-codec will now print codec (format) descriptive name, not decoder
long name as it were before. In practice this change fixes what docs
says. If you really need decoder name, use the `track-list/N/decoder-desc`.
This commit is contained in:
Kacper Michajłow 2024-04-10 21:24:06 +02:00
parent 3995cd3714
commit e720159f72
8 changed files with 109 additions and 49 deletions

View File

@ -0,0 +1 @@
add `video-codec-info` and `audio-codec-info` properties

View File

@ -2401,11 +2401,25 @@ Property list
Similar to ``ao-volume``, but controls the mute state. May be unimplemented
even if ``ao-volume`` works.
``audio-codec``
Audio codec selected for decoding.
``audio-codec-info``
Audio codec information.
``audio-codec-name``
Audio codec.
``audio-codec-info/name``
The codec name used by this track, for example ``aac``.
``audio-codec-info/desc``
The codec descriptive name used by this track.
``audio-codec-info/profile``
The codec profile used by this track. Available only if the track has
been already decoded.
::
MPV_FORMAT_NODE_MAP
"name" MPV_FORMAT_STRING
"desc" MPV_FORMAT_STRING
"profile" MPV_FORMAT_STRING
``audio-params``
Audio format as output by the audio decoder.
@ -2490,11 +2504,25 @@ Property list
multiple interop drivers for the same hardware decoder, depending on
platform and VO.
``video-format``
Video format as string.
``video-codec-info``
Video codec information.
``video-codec``
Video codec selected for decoding.
``video-codec-info/name``
The codec name used by this track, for example ``h264``.
``video-codec-info/desc``
The codec descriptive name used by this track.
``video-codec-info/profile``
The codec profile used by this track. Available only if the track has
been already decoded.
::
MPV_FORMAT_NODE_MAP
"name" MPV_FORMAT_STRING
"desc" MPV_FORMAT_STRING
"profile" MPV_FORMAT_STRING
``width``, ``height``
Video size. This uses the size of the video as decoded, or if no video
@ -3057,6 +3085,13 @@ Property list
The codec name used by this track, for example ``h264``. Unavailable
in some rare cases.
``track-list/N/codec-desc``
The codec descriptive name used by this track.
``track-list/N/codec-profile``
The codec profile used by this track. Available only if the track has
been already decoded.
``track-list/N/external``
``yes``/true if the track is an external file, ``no``/false or
unavailable otherwise. This is set for separate subtitle files.
@ -3157,6 +3192,8 @@ Property list
"external" MPV_FORMAT_FLAG
"external-filename" MPV_FORMAT_STRING
"codec" MPV_FORMAT_STRING
"codec-desc" MPV_FORMAT_STRING
"codec-profile" MPV_FORMAT_STRING
"ff-index" MPV_FORMAT_INT64
"decoder-desc" MPV_FORMAT_STRING
"demux-w" MPV_FORMAT_INT64

View File

@ -44,6 +44,7 @@
#include "options/options.h"
struct priv {
struct mp_codec_params *codec;
AVCodecContext *avctx;
AVFrame *avframe;
AVPacket *avpkt;
@ -219,6 +220,8 @@ static int receive_frame(struct mp_filter *da, struct mp_frame *out)
if (!priv->avframe->buf[0])
return ret;
mp_codec_info_from_av(avctx, priv->codec);
double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase);
struct mp_aframe *mpframe = mp_aframe_from_avframe(priv->avframe);
@ -305,12 +308,16 @@ static struct mp_decoder *create(struct mp_filter *parent,
da->log = mp_log_new(da, parent->log, NULL);
struct priv *priv = da->priv;
priv->codec = codec;
priv->public.f = da;
if (!init(da, codec, decoder)) {
talloc_free(da);
return NULL;
}
codec->codec_desc = priv->avctx->codec_descriptor->long_name;
return &priv->public;
}

View File

@ -402,3 +402,12 @@ void mp_free_av_packet(AVPacket **pkt)
}
av_packet_free(pkt);
}
void mp_codec_info_from_av(const AVCodecContext *avctx, struct mp_codec_params *c)
{
c->codec_profile = av_get_profile_name(avctx->codec, avctx->profile);
if (!c->codec_profile)
c->codec_profile = avcodec_profile_name(avctx->codec_id, avctx->profile);
c->codec = avctx->codec_descriptor->name;
c->codec_desc = avctx->codec_descriptor->long_name;
}

View File

@ -50,5 +50,6 @@ void mp_avdict_print_unset(struct mp_log *log, int msgl, struct AVDictionary *d)
int mp_set_avopts(struct mp_log *log, void *avobj, char **kv);
int mp_set_avopts_pos(struct mp_log *log, void *avobj, void *posargs, char **kv);
void mp_free_av_packet(AVPacket **pkt);
void mp_codec_info_from_av(const AVCodecContext *avctx, struct mp_codec_params *c);
#endif

View File

@ -72,6 +72,12 @@ struct mp_codec_params {
// E.g. "h264" (usually corresponds to AVCodecDescriptor.name)
const char *codec;
// Usually corresponds to AVCodecDescriptor.long_name
const char *codec_desc;
// Corresponding codec profile
const char *codec_profile;
// Usually a FourCC, exact meaning depends on codec.
unsigned int codec_tag;

View File

@ -1829,26 +1829,30 @@ static int mp_property_audio_delay(void *ctx, struct m_property *prop,
return mp_property_generic_option(mpctx, prop, action, arg);
}
/// Audio codec tag (RO)
static int mp_property_audio_codec_name(void *ctx, struct m_property *prop,
int action, void *arg)
static int property_codec_info(MPContext *mpctx, struct m_property *prop,
int action, void *arg, enum stream_type st)
{
MPContext *mpctx = ctx;
struct track *track = mpctx->current_track[0][STREAM_AUDIO];
const char *c = track && track->stream ? track->stream->codec->codec : NULL;
return m_property_strdup_ro(action, arg, c);
struct track *track = mpctx->current_track[0][st];
if (!track || !track->stream)
return M_PROPERTY_UNAVAILABLE;
struct m_sub_property props[] = {
{"name", SUB_PROP_STR(track->stream->codec->codec),
.unavailable = !track->stream->codec->codec},
{"desc", SUB_PROP_STR(track->stream->codec->codec_desc),
.unavailable = !track->stream->codec->codec_desc},
{"profile", SUB_PROP_STR(track->stream->codec->codec_profile),
.unavailable = !track->stream->codec->codec_profile},
{0}
};
return m_property_read_sub(props, action, arg);
}
/// Audio codec name (RO)
static int mp_property_audio_codec(void *ctx, struct m_property *prop,
int action, void *arg)
static int mp_property_audio_codec_info(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
struct track *track = mpctx->current_track[0][STREAM_AUDIO];
char desc[256] = "";
if (track && track->dec)
mp_decoder_wrapper_get_desc(track->dec, desc, sizeof(desc));
return m_property_strdup_ro(action, arg, desc[0] ? desc : NULL);
return property_codec_info(ctx, prop, action, arg, STREAM_AUDIO);
}
static int property_audiofmt(struct mp_aframe *fmt, int action, void *arg)
@ -2055,6 +2059,10 @@ static int get_track_entry(int item, int action, void *arg, void *ctx)
.unavailable = !decoder_desc[0]},
{"codec", SUB_PROP_STR(p.codec),
.unavailable = !p.codec},
{"codec-desc", SUB_PROP_STR(p.codec_desc),
.unavailable = !p.codec_desc},
{"codec-profile", SUB_PROP_STR(p.codec_profile),
.unavailable = !p.codec_profile},
{"demux-w", SUB_PROP_INT(p.disp_w), .unavailable = !p.disp_w},
{"demux-h", SUB_PROP_INT(p.disp_h), .unavailable = !p.disp_h},
{"demux-crop-x",SUB_PROP_INT(p.crop.x0), .unavailable = !has_crop},
@ -2264,26 +2272,10 @@ static int mp_property_frame_count(void *ctx, struct m_property *prop,
return m_property_int_ro(action, arg, frames);
}
/// Video codec tag (RO)
static int mp_property_video_format(void *ctx, struct m_property *prop,
int action, void *arg)
static int mp_property_video_codec_info(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
struct track *track = mpctx->current_track[0][STREAM_VIDEO];
const char *c = track && track->stream ? track->stream->codec->codec : NULL;
return m_property_strdup_ro(action, arg, c);
}
/// Video codec name (RO)
static int mp_property_video_codec(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
struct track *track = mpctx->current_track[0][STREAM_VIDEO];
char desc[256] = "";
if (track && track->dec)
mp_decoder_wrapper_get_desc(track->dec, desc, sizeof(desc));
return m_property_strdup_ro(action, arg, desc[0] ? desc : NULL);
return property_codec_info(ctx, prop, action, arg, STREAM_VIDEO);
}
static const char *get_aspect_ratio_name(double ratio)
@ -4027,8 +4019,9 @@ static const struct m_property mp_properties_base[] = {
{"ao-volume", mp_property_ao_volume},
{"ao-mute", mp_property_ao_mute},
{"audio-delay", mp_property_audio_delay},
{"audio-codec-name", mp_property_audio_codec_name},
{"audio-codec", mp_property_audio_codec},
{"audio-codec-info", mp_property_audio_codec_info},
M_PROPERTY_ALIAS("audio-codec-name", "audio-codec-info/name"),
M_PROPERTY_ALIAS("audio-codec", "audio-codec-info/desc"),
{"audio-params", mp_property_audio_params},
{"audio-out-params", mp_property_audio_out_params},
{"aid", property_switch_track, .priv = (void *)(const int[]){0, STREAM_AUDIO}},
@ -4041,9 +4034,10 @@ static const struct m_property mp_properties_base[] = {
{"video-out-params", mp_property_vo_imgparams},
{"video-dec-params", mp_property_dec_imgparams},
{"video-params", mp_property_vd_imgparams},
{"video-format", mp_property_video_format},
{"video-frame-info", mp_property_video_frame_info},
{"video-codec", mp_property_video_codec},
{"video-codec-info", mp_property_video_codec_info},
M_PROPERTY_ALIAS("video-format", "video-codec-info/name"),
M_PROPERTY_ALIAS("video-codec", "video-codec-info/desc"),
M_PROPERTY_ALIAS("dwidth", "video-out-params/dw"),
M_PROPERTY_ALIAS("dheight", "video-out-params/dh"),
M_PROPERTY_ALIAS("width", "video-params/w"),
@ -4189,10 +4183,10 @@ static const char *const *const mp_event_property_change[] = {
"video-format", "video-codec", "video-bitrate", "dwidth", "dheight",
"width", "height", "container-fps", "aspect", "aspect-name", "vo-configured", "current-vo",
"video-dec-params", "osd-dimensions", "hwdec", "hwdec-current", "hwdec-interop",
"window-id"),
"window-id", "video-codec-info"),
E(MPV_EVENT_AUDIO_RECONFIG, "audio-format", "audio-codec", "audio-bitrate",
"samplerate", "channels", "audio", "volume", "volume-gain", "mute",
"current-ao", "audio-codec-name", "audio-params",
"current-ao", "audio-codec-name", "audio-params", "audio-codec-info",
"audio-out-params", "volume-max", "volume-gain-min", "volume-gain-max", "mixer-active"),
E(MPV_EVENT_SEEK, "seeking", "core-idle", "eof-reached"),
E(MPV_EVENT_PLAYBACK_RESTART, "seeking", "core-idle", "eof-reached"),

View File

@ -1215,6 +1215,8 @@ static int decode_frame(struct mp_filter *vd)
return ret;
}
mp_codec_info_from_av(avctx, ctx->codec);
// If something was decoded successfully, it must return a frame with valid
// data.
assert(ctx->pic->buf[0]);
@ -1443,6 +1445,9 @@ static struct mp_decoder *create(struct mp_filter *parent,
talloc_free(vd);
return NULL;
}
codec->codec_desc = ctx->avctx->codec_descriptor->long_name;
return &ctx->public;
}