mirror of
https://github.com/mpv-player/mpv
synced 2025-01-02 21:12:23 +00:00
encode_lavc: mp_msg conversions
Miss two mp_msg calls, because these conflict with future commits.
This commit is contained in:
parent
09e588662e
commit
9428e05b3f
@ -3,16 +3,18 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct MPOpts;
|
struct mpv_global;
|
||||||
|
struct mp_log;
|
||||||
struct encode_lavc_context;
|
struct encode_lavc_context;
|
||||||
struct encode_output_conf;
|
struct encode_output_conf;
|
||||||
|
|
||||||
// interface for mplayer.c
|
// interface for mplayer.c
|
||||||
struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options);
|
struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options,
|
||||||
|
struct mpv_global *global);
|
||||||
void encode_lavc_finish(struct encode_lavc_context *ctx);
|
void encode_lavc_finish(struct encode_lavc_context *ctx);
|
||||||
void encode_lavc_free(struct encode_lavc_context *ctx);
|
void encode_lavc_free(struct encode_lavc_context *ctx);
|
||||||
void encode_lavc_discontinuity(struct encode_lavc_context *ctx);
|
void encode_lavc_discontinuity(struct encode_lavc_context *ctx);
|
||||||
bool encode_lavc_showhelp(struct MPOpts *opts);
|
bool encode_lavc_showhelp(struct mp_log *log, struct encode_output_conf *options);
|
||||||
int encode_lavc_getstatus(struct encode_lavc_context *ctx, char *buf, int bufsize, float relative_position);
|
int encode_lavc_getstatus(struct encode_lavc_context *ctx, char *buf, int bufsize, float relative_position);
|
||||||
void encode_lavc_expect_stream(struct encode_lavc_context *ctx, int mt);
|
void encode_lavc_expect_stream(struct encode_lavc_context *ctx, int mt);
|
||||||
void encode_lavc_set_video_fps(struct encode_lavc_context *ctx, float fps);
|
void encode_lavc_set_video_fps(struct encode_lavc_context *ctx, float fps);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <libavutil/avutil.h>
|
#include <libavutil/avutil.h>
|
||||||
|
|
||||||
#include "encode_lavc.h"
|
#include "encode_lavc.h"
|
||||||
|
#include "common/global.h"
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
#include "video/vfcap.h"
|
#include "video/vfcap.h"
|
||||||
#include "options/options.h"
|
#include "options/options.h"
|
||||||
@ -31,7 +32,9 @@
|
|||||||
#include "talloc.h"
|
#include "talloc.h"
|
||||||
#include "stream/stream.h"
|
#include "stream/stream.h"
|
||||||
|
|
||||||
static int set_to_avdictionary(AVDictionary **dictp, const char *key,
|
static int set_to_avdictionary(struct encode_lavc_context *ctx,
|
||||||
|
AVDictionary **dictp,
|
||||||
|
const char *key,
|
||||||
const char *val)
|
const char *val)
|
||||||
{
|
{
|
||||||
char keybuf[1024];
|
char keybuf[1024];
|
||||||
@ -41,9 +44,8 @@ static int set_to_avdictionary(AVDictionary **dictp, const char *key,
|
|||||||
// we need to split at equals sign
|
// we need to split at equals sign
|
||||||
const char *equals = strchr(val, '=');
|
const char *equals = strchr(val, '=');
|
||||||
if (!equals || equals - val >= sizeof(keybuf)) {
|
if (!equals || equals - val >= sizeof(keybuf)) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
MP_WARN(ctx, "option '%s' does not contain an equals sign\n",
|
||||||
"encode-lavc: option '%s' does not contain an equals sign\n",
|
val);
|
||||||
val);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(keybuf, val, equals - val);
|
memcpy(keybuf, val, equals - val);
|
||||||
@ -63,10 +65,8 @@ static int set_to_avdictionary(AVDictionary **dictp, const char *key,
|
|||||||
val = valuebuf;
|
val = valuebuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_msg(MSGT_ENCODE, MSGL_V,
|
MP_VERBOSE(ctx, "setting value '%s' for key '%s'\n",
|
||||||
"encode-lavc: setting value '%s' for key '%s'\n",
|
val, key);
|
||||||
val,
|
|
||||||
key);
|
|
||||||
|
|
||||||
if (av_dict_set(dictp, key, *val ? val : NULL,
|
if (av_dict_set(dictp, key, *val ? val : NULL,
|
||||||
(val[0] == '+' || val[0] == '-') ? AV_DICT_APPEND : 0) >= 0)
|
(val[0] == '+' || val[0] == '-') ? AV_DICT_APPEND : 0) >= 0)
|
||||||
@ -96,7 +96,7 @@ static bool value_has_flag(const char *value, const char *flag)
|
|||||||
|
|
||||||
#define CHECK_FAIL(ctx, val) \
|
#define CHECK_FAIL(ctx, val) \
|
||||||
if (ctx && (ctx->failed || ctx->finished)) { \
|
if (ctx && (ctx->failed || ctx->finished)) { \
|
||||||
mp_msg(MSGT_ENCODE, MSGL_ERR, \
|
MP_ERR(ctx, \
|
||||||
"Called a function on a %s encoding context. Bailing out.\n", \
|
"Called a function on a %s encoding context. Bailing out.\n", \
|
||||||
ctx->failed ? "failed" : "finished"); \
|
ctx->failed ? "failed" : "finished"); \
|
||||||
return val; \
|
return val; \
|
||||||
@ -114,7 +114,8 @@ int encode_lavc_oformat_flags(struct encode_lavc_context *ctx)
|
|||||||
return ctx->avc ? ctx->avc->oformat->flags : 0;
|
return ctx->avc ? ctx->avc->oformat->flags : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
|
struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options,
|
||||||
|
struct mpv_global *global)
|
||||||
{
|
{
|
||||||
struct encode_lavc_context *ctx;
|
struct encode_lavc_context *ctx;
|
||||||
const char *filename = options->file;
|
const char *filename = options->file;
|
||||||
@ -132,6 +133,8 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
|
|||||||
mp_msg_stdout_in_use = 1;
|
mp_msg_stdout_in_use = 1;
|
||||||
|
|
||||||
ctx = talloc_zero(NULL, struct encode_lavc_context);
|
ctx = talloc_zero(NULL, struct encode_lavc_context);
|
||||||
|
ctx->log = mp_log_new(ctx, global->log, "encode-lavc");
|
||||||
|
ctx->global = global;
|
||||||
encode_lavc_discontinuity(ctx);
|
encode_lavc_discontinuity(ctx);
|
||||||
ctx->options = options;
|
ctx->options = options;
|
||||||
|
|
||||||
@ -153,7 +156,7 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
|
|||||||
ctx->avc->oformat = av_guess_format(NULL, filename, NULL);
|
ctx->avc->oformat = av_guess_format(NULL, filename, NULL);
|
||||||
|
|
||||||
if (!ctx->avc->oformat) {
|
if (!ctx->avc->oformat) {
|
||||||
encode_lavc_fail(ctx, "encode-lavc: format not found\n");
|
encode_lavc_fail(ctx, "format not found\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,9 +167,8 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
|
|||||||
if (ctx->options->fopts) {
|
if (ctx->options->fopts) {
|
||||||
char **p;
|
char **p;
|
||||||
for (p = ctx->options->fopts; *p; ++p) {
|
for (p = ctx->options->fopts; *p; ++p) {
|
||||||
if (!set_to_avdictionary(&ctx->foptions, NULL, *p))
|
if (!set_to_avdictionary(ctx, &ctx->foptions, NULL, *p))
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
MP_WARN(ctx, "could not set option %s\n", *p);
|
||||||
"encode-lavc: could not set option %s\n", *p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +212,7 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
|
|||||||
|
|
||||||
if (!ctx->vc && !ctx->ac) {
|
if (!ctx->vc && !ctx->ac) {
|
||||||
encode_lavc_fail(
|
encode_lavc_fail(
|
||||||
ctx, "encode-lavc: neither audio nor video codec was found\n");
|
ctx, "neither audio nor video codec was found\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +251,7 @@ int encode_lavc_start(struct encode_lavc_context *ctx)
|
|||||||
break;
|
break;
|
||||||
if (i >= ctx->avc->nb_streams) {
|
if (i >= ctx->avc->nb_streams) {
|
||||||
encode_lavc_fail(ctx,
|
encode_lavc_fail(ctx,
|
||||||
"encode-lavc: video stream missing, invalid codec?\n");
|
"video stream missing, invalid codec?\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,7 +261,7 @@ int encode_lavc_start(struct encode_lavc_context *ctx)
|
|||||||
break;
|
break;
|
||||||
if (i >= ctx->avc->nb_streams) {
|
if (i >= ctx->avc->nb_streams) {
|
||||||
encode_lavc_fail(ctx,
|
encode_lavc_fail(ctx,
|
||||||
"encode-lavc: audio stream missing, invalid codec?\n");
|
"audio stream missing, invalid codec?\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,12 +269,12 @@ int encode_lavc_start(struct encode_lavc_context *ctx)
|
|||||||
ctx->header_written = -1;
|
ctx->header_written = -1;
|
||||||
|
|
||||||
if (!(ctx->avc->oformat->flags & AVFMT_NOFILE)) {
|
if (!(ctx->avc->oformat->flags & AVFMT_NOFILE)) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening output file: %s\n",
|
MP_INFO(ctx, "Opening output file: %s\n",
|
||||||
ctx->avc->filename);
|
ctx->avc->filename);
|
||||||
|
|
||||||
if (avio_open(&ctx->avc->pb, ctx->avc->filename,
|
if (avio_open(&ctx->avc->pb, ctx->avc->filename,
|
||||||
AVIO_FLAG_WRITE) < 0) {
|
AVIO_FLAG_WRITE) < 0) {
|
||||||
encode_lavc_fail(ctx, "encode-lavc: could not open '%s'\n",
|
encode_lavc_fail(ctx, "could not open '%s'\n",
|
||||||
ctx->avc->filename);
|
ctx->avc->filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -280,17 +282,17 @@ int encode_lavc_start(struct encode_lavc_context *ctx)
|
|||||||
|
|
||||||
ctx->t0 = mp_time_sec();
|
ctx->t0 = mp_time_sec();
|
||||||
|
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening muxer: %s [%s]\n",
|
MP_INFO(ctx, "Opening muxer: %s [%s]\n",
|
||||||
ctx->avc->oformat->long_name, ctx->avc->oformat->name);
|
ctx->avc->oformat->long_name, ctx->avc->oformat->name);
|
||||||
|
|
||||||
if (avformat_write_header(ctx->avc, &ctx->foptions) < 0) {
|
if (avformat_write_header(ctx->avc, &ctx->foptions) < 0) {
|
||||||
encode_lavc_fail(ctx, "encode-lavc: could not write header\n");
|
encode_lavc_fail(ctx, "could not write header\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (de = NULL; (de = av_dict_get(ctx->foptions, "", de,
|
for (de = NULL; (de = av_dict_get(ctx->foptions, "", de,
|
||||||
AV_DICT_IGNORE_SUFFIX));)
|
AV_DICT_IGNORE_SUFFIX));)
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "ofopts: key '%s' not found.\n", de->key);
|
MP_WARN(ctx, "ofopts: key '%s' not found.\n", de->key);
|
||||||
av_dict_free(&ctx->foptions);
|
av_dict_free(&ctx->foptions);
|
||||||
|
|
||||||
ctx->header_written = 1;
|
ctx->header_written = 1;
|
||||||
@ -361,13 +363,12 @@ void encode_lavc_finish(struct encode_lavc_context *ctx)
|
|||||||
ctx->twopass_bytebuffer_a = NULL;
|
ctx->twopass_bytebuffer_a = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: encoded %lld bytes\n",
|
MP_INFO(ctx, "vo-lavc: encoded %lld bytes\n",
|
||||||
ctx->vbytes);
|
ctx->vbytes);
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "ao-lavc: encoded %lld bytes\n",
|
MP_INFO(ctx, "ao-lavc: encoded %lld bytes\n",
|
||||||
ctx->abytes);
|
ctx->abytes);
|
||||||
if (ctx->avc->pb) {
|
if (ctx->avc->pb) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO,
|
MP_INFO(ctx, "muxing overhead %lld bytes\n",
|
||||||
"encode-lavc: muxing overhead %lld bytes\n",
|
|
||||||
(long long) (avio_size(ctx->avc->pb) - ctx->vbytes
|
(long long) (avio_size(ctx->avc->pb) - ctx->vbytes
|
||||||
- ctx->abytes));
|
- ctx->abytes));
|
||||||
avio_close(ctx->avc->pb);
|
avio_close(ctx->avc->pb);
|
||||||
@ -402,12 +403,12 @@ static void encode_2pass_prepare(struct encode_lavc_context *ctx,
|
|||||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not open '%s', "
|
mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not open '%s', "
|
||||||
"disabling 2-pass encoding at pass 2\n", prefix, buf);
|
"disabling 2-pass encoding at pass 2\n", prefix, buf);
|
||||||
stream->codec->flags &= ~CODEC_FLAG_PASS2;
|
stream->codec->flags &= ~CODEC_FLAG_PASS2;
|
||||||
set_to_avdictionary(dictp, "flags", "-pass2");
|
set_to_avdictionary(ctx, dictp, "flags", "-pass2");
|
||||||
} else {
|
} else {
|
||||||
struct bstr content = stream_read_complete(*bytebuf, NULL,
|
struct bstr content = stream_read_complete(*bytebuf, NULL,
|
||||||
1000000000);
|
1000000000);
|
||||||
if (content.start == NULL) {
|
if (content.start == NULL) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not read '%s', "
|
MP_WARN(ctx, "%s: could not read '%s', "
|
||||||
"disabling 2-pass encoding at pass 1\n",
|
"disabling 2-pass encoding at pass 1\n",
|
||||||
prefix, ctx->avc->filename);
|
prefix, ctx->avc->filename);
|
||||||
} else {
|
} else {
|
||||||
@ -426,7 +427,7 @@ static void encode_2pass_prepare(struct encode_lavc_context *ctx,
|
|||||||
"%s: could not open '%s', disabling "
|
"%s: could not open '%s', disabling "
|
||||||
"2-pass encoding at pass 1\n",
|
"2-pass encoding at pass 1\n",
|
||||||
prefix, ctx->avc->filename);
|
prefix, ctx->avc->filename);
|
||||||
set_to_avdictionary(dictp, "flags", "-pass1");
|
set_to_avdictionary(ctx, dictp, "flags", "-pass1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,13 +455,11 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||||||
// if this stream isn't stream #0, allocate a dummy stream first for
|
// if this stream isn't stream #0, allocate a dummy stream first for
|
||||||
// the next loop to use
|
// the next loop to use
|
||||||
if (mt == AVMEDIA_TYPE_VIDEO && ctx->audio_first) {
|
if (mt == AVMEDIA_TYPE_VIDEO && ctx->audio_first) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO,
|
MP_INFO(ctx, "vo-lavc: preallocated audio stream for later use\n");
|
||||||
"vo-lavc: preallocated audio stream for later use\n");
|
|
||||||
avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now
|
avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now
|
||||||
}
|
}
|
||||||
if (mt == AVMEDIA_TYPE_AUDIO && ctx->video_first) {
|
if (mt == AVMEDIA_TYPE_AUDIO && ctx->video_first) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO,
|
MP_INFO(ctx, "ao-lavc: preallocated video stream for later use\n");
|
||||||
"ao-lavc: preallocated video stream for later use\n");
|
|
||||||
avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now
|
avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -479,8 +478,7 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||||||
r = av_d2q(ctx->options->fps, ctx->options->fps * 1001 + 2);
|
r = av_d2q(ctx->options->fps, ctx->options->fps * 1001 + 2);
|
||||||
else if (ctx->options->autofps && ctx->vo_fps > 0) {
|
else if (ctx->options->autofps && ctx->vo_fps > 0) {
|
||||||
r = av_d2q(ctx->vo_fps, ctx->vo_fps * 1001 + 2);
|
r = av_d2q(ctx->vo_fps, ctx->vo_fps * 1001 + 2);
|
||||||
mp_msg(
|
MP_INFO(ctx, "option --ofps not specified "
|
||||||
MSGT_ENCODE, MSGL_INFO, "vo-lavc: option --ofps not specified "
|
|
||||||
"but --oautofps is active, using guess of %u/%u\n",
|
"but --oautofps is active, using guess of %u/%u\n",
|
||||||
(unsigned)r.num, (unsigned)r.den);
|
(unsigned)r.num, (unsigned)r.den);
|
||||||
} else {
|
} else {
|
||||||
@ -493,8 +491,7 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||||||
// so let's take 1001/30000 out
|
// so let's take 1001/30000 out
|
||||||
r.num = 24000;
|
r.num = 24000;
|
||||||
r.den = 1;
|
r.den = 1;
|
||||||
mp_msg(
|
MP_INFO(ctx, "option --ofps not specified "
|
||||||
MSGT_ENCODE, MSGL_INFO, "vo-lavc: option --ofps not specified "
|
|
||||||
"and fps could not be inferred, using guess of %u/%u\n",
|
"and fps could not be inferred, using guess of %u/%u\n",
|
||||||
(unsigned)r.num, (unsigned)r.den);
|
(unsigned)r.num, (unsigned)r.den);
|
||||||
}
|
}
|
||||||
@ -526,16 +523,15 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||||||
|
|
||||||
if (ctx->options->vopts)
|
if (ctx->options->vopts)
|
||||||
for (p = ctx->options->vopts; *p; ++p)
|
for (p = ctx->options->vopts; *p; ++p)
|
||||||
if (!set_to_avdictionary(&ctx->voptions, NULL, *p))
|
if (!set_to_avdictionary(ctx, &ctx->voptions, NULL, *p))
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
MP_WARN(ctx, "vo-lavc: could not set option %s\n", *p);
|
||||||
"vo-lavc: could not set option %s\n", *p);
|
|
||||||
|
|
||||||
de = av_dict_get(ctx->voptions, "global_quality", NULL, 0);
|
de = av_dict_get(ctx->voptions, "global_quality", NULL, 0);
|
||||||
if (de)
|
if (de)
|
||||||
set_to_avdictionary(&ctx->voptions, "flags", "+qscale");
|
set_to_avdictionary(ctx, &ctx->voptions, "flags", "+qscale");
|
||||||
|
|
||||||
if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER)
|
if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||||
set_to_avdictionary(&ctx->voptions, "flags", "+global_header");
|
set_to_avdictionary(ctx, &ctx->voptions, "flags", "+global_header");
|
||||||
|
|
||||||
encode_2pass_prepare(ctx, &ctx->voptions, stream,
|
encode_2pass_prepare(ctx, &ctx->voptions, stream,
|
||||||
&ctx->twopass_bytebuffer_v,
|
&ctx->twopass_bytebuffer_v,
|
||||||
@ -555,16 +551,15 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||||||
|
|
||||||
if (ctx->options->aopts)
|
if (ctx->options->aopts)
|
||||||
for (p = ctx->options->aopts; *p; ++p)
|
for (p = ctx->options->aopts; *p; ++p)
|
||||||
if (!set_to_avdictionary(&ctx->aoptions, NULL, *p))
|
if (!set_to_avdictionary(ctx, &ctx->aoptions, NULL, *p))
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
MP_WARN(ctx, "ao-lavc: could not set option %s\n", *p);
|
||||||
"ao-lavc: could not set option %s\n", *p);
|
|
||||||
|
|
||||||
de = av_dict_get(ctx->aoptions, "global_quality", NULL, 0);
|
de = av_dict_get(ctx->aoptions, "global_quality", NULL, 0);
|
||||||
if (de)
|
if (de)
|
||||||
set_to_avdictionary(&ctx->aoptions, "flags", "+qscale");
|
set_to_avdictionary(ctx, &ctx->aoptions, "flags", "+qscale");
|
||||||
|
|
||||||
if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER)
|
if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||||
set_to_avdictionary(&ctx->aoptions, "flags", "+global_header");
|
set_to_avdictionary(ctx, &ctx->aoptions, "flags", "+global_header");
|
||||||
|
|
||||||
encode_2pass_prepare(ctx, &ctx->aoptions, stream,
|
encode_2pass_prepare(ctx, &ctx->aoptions, stream,
|
||||||
&ctx->twopass_bytebuffer_a,
|
&ctx->twopass_bytebuffer_a,
|
||||||
@ -572,7 +567,7 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
encode_lavc_fail(ctx, "encode-lavc: requested invalid stream type\n");
|
encode_lavc_fail(ctx, "requested invalid stream type\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,13 +599,12 @@ int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream)
|
|||||||
|
|
||||||
switch (stream->codec->codec_type) {
|
switch (stream->codec->codec_type) {
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening video encoder: %s [%s]\n",
|
MP_INFO(ctx, "Opening video encoder: %s [%s]\n",
|
||||||
ctx->vc->long_name, ctx->vc->name);
|
ctx->vc->long_name, ctx->vc->name);
|
||||||
|
|
||||||
if (ctx->vc->capabilities & CODEC_CAP_EXPERIMENTAL) {
|
if (ctx->vc->capabilities & CODEC_CAP_EXPERIMENTAL) {
|
||||||
stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
MP_WARN(ctx, "\n\n"
|
||||||
"\n\n"
|
|
||||||
" ********************************************\n"
|
" ********************************************\n"
|
||||||
" **** Experimental VIDEO codec selected! ****\n"
|
" **** Experimental VIDEO codec selected! ****\n"
|
||||||
" ********************************************\n\n"
|
" ********************************************\n\n"
|
||||||
@ -634,19 +628,18 @@ int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream)
|
|||||||
// complain about all remaining options, then free the dict
|
// complain about all remaining options, then free the dict
|
||||||
for (de = NULL; (de = av_dict_get(ctx->voptions, "", de,
|
for (de = NULL; (de = av_dict_get(ctx->voptions, "", de,
|
||||||
AV_DICT_IGNORE_SUFFIX));)
|
AV_DICT_IGNORE_SUFFIX));)
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "ovcopts: key '%s' not found.\n",
|
MP_WARN(ctx, "ovcopts: key '%s' not found.\n",
|
||||||
de->key);
|
de->key);
|
||||||
av_dict_free(&ctx->voptions);
|
av_dict_free(&ctx->voptions);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening audio encoder: %s [%s]\n",
|
MP_INFO(ctx, "Opening audio encoder: %s [%s]\n",
|
||||||
ctx->ac->long_name, ctx->ac->name);
|
ctx->ac->long_name, ctx->ac->name);
|
||||||
|
|
||||||
if (ctx->ac->capabilities & CODEC_CAP_EXPERIMENTAL) {
|
if (ctx->ac->capabilities & CODEC_CAP_EXPERIMENTAL) {
|
||||||
stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
MP_WARN(ctx, "\n\n"
|
||||||
"\n\n"
|
|
||||||
" ********************************************\n"
|
" ********************************************\n"
|
||||||
" **** Experimental AUDIO codec selected! ****\n"
|
" **** Experimental AUDIO codec selected! ****\n"
|
||||||
" ********************************************\n\n"
|
" ********************************************\n\n"
|
||||||
@ -669,7 +662,7 @@ int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream)
|
|||||||
// complain about all remaining options, then free the dict
|
// complain about all remaining options, then free the dict
|
||||||
for (de = NULL; (de = av_dict_get(ctx->aoptions, "", de,
|
for (de = NULL; (de = av_dict_get(ctx->aoptions, "", de,
|
||||||
AV_DICT_IGNORE_SUFFIX));)
|
AV_DICT_IGNORE_SUFFIX));)
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "oacopts: key '%s' not found.\n",
|
MP_WARN(ctx, "oacopts: key '%s' not found.\n",
|
||||||
de->key);
|
de->key);
|
||||||
av_dict_free(&ctx->aoptions);
|
av_dict_free(&ctx->aoptions);
|
||||||
|
|
||||||
@ -719,9 +712,8 @@ int encode_lavc_write_frame(struct encode_lavc_context *ctx, AVPacket *packet)
|
|||||||
if (ctx->header_written <= 0)
|
if (ctx->header_written <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
mp_msg(
|
MP_DBG(ctx,
|
||||||
MSGT_ENCODE, MSGL_DBG2,
|
"write frame: stream %d ptsi %d (%f) dtsi %d (%f) size %d\n",
|
||||||
"encode-lavc: write frame: stream %d ptsi %d (%f) dtsi %d (%f) size %d\n",
|
|
||||||
(int)packet->stream_index,
|
(int)packet->stream_index,
|
||||||
(int)packet->pts,
|
(int)packet->pts,
|
||||||
packet->pts
|
packet->pts
|
||||||
@ -787,9 +779,10 @@ void encode_lavc_discontinuity(struct encode_lavc_context *ctx)
|
|||||||
ctx->discontinuity_pts_offset = MP_NOPTS_VALUE;
|
ctx->discontinuity_pts_offset = MP_NOPTS_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encode_lavc_printoptions(void *obj, const char *indent,
|
static void encode_lavc_printoptions(struct mp_log *log, void *obj,
|
||||||
const char *subindent, const char *unit,
|
const char *indent, const char *subindent,
|
||||||
int filter_and, int filter_eq)
|
const char *unit, int filter_and,
|
||||||
|
int filter_eq)
|
||||||
{
|
{
|
||||||
const AVOption *opt = NULL;
|
const AVOption *opt = NULL;
|
||||||
char optbuf[32];
|
char optbuf[32];
|
||||||
@ -811,9 +804,9 @@ static void encode_lavc_printoptions(void *obj, const char *indent,
|
|||||||
&& strcmp(unit, opt->unit))
|
&& strcmp(unit, opt->unit))
|
||||||
continue;
|
continue;
|
||||||
else if (unit && opt->type == AV_OPT_TYPE_CONST)
|
else if (unit && opt->type == AV_OPT_TYPE_CONST)
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "%s", subindent);
|
mp_info(log, "%s", subindent);
|
||||||
else
|
else
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "%s", indent);
|
mp_info(log, "%s", indent);
|
||||||
|
|
||||||
switch (opt->type) {
|
switch (opt->type) {
|
||||||
case AV_OPT_TYPE_FLAGS:
|
case AV_OPT_TYPE_FLAGS:
|
||||||
@ -848,59 +841,57 @@ static void encode_lavc_printoptions(void *obj, const char *indent,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
optbuf[sizeof(optbuf) - 1] = 0;
|
optbuf[sizeof(optbuf) - 1] = 0;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "%-32s ", optbuf);
|
mp_info(log, "%-32s ", optbuf);
|
||||||
if (opt->help)
|
if (opt->help)
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, " %s", opt->help);
|
mp_info(log, " %s", opt->help);
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "\n");
|
mp_info(log, "\n");
|
||||||
if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
|
if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
|
||||||
encode_lavc_printoptions(obj, indent, subindent, opt->unit,
|
encode_lavc_printoptions(log, obj, indent, subindent, opt->unit,
|
||||||
filter_and, filter_eq);
|
filter_and, filter_eq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool encode_lavc_showhelp(struct MPOpts *opts)
|
bool encode_lavc_showhelp(struct mp_log *log, struct encode_output_conf *opts)
|
||||||
{
|
{
|
||||||
bool help_output = false;
|
bool help_output = false;
|
||||||
if (av_codec_next(NULL) == NULL)
|
if (av_codec_next(NULL) == NULL)
|
||||||
mp_msg(MSGT_ENCODE, MSGL_ERR, "NO CODECS\n");
|
mp_err(log, "NO CODECS\n");
|
||||||
#define CHECKS(str) ((str) && \
|
#define CHECKS(str) ((str) && \
|
||||||
strcmp((str), "help") == 0 ? (help_output |= 1) : 0)
|
strcmp((str), "help") == 0 ? (help_output |= 1) : 0)
|
||||||
#define CHECKV(strv) ((strv) && (strv)[0] && \
|
#define CHECKV(strv) ((strv) && (strv)[0] && \
|
||||||
strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0)
|
strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0)
|
||||||
if (CHECKS(opts->encode_output.format)) {
|
if (CHECKS(opts->format)) {
|
||||||
AVOutputFormat *c = NULL;
|
AVOutputFormat *c = NULL;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output formats:\n");
|
mp_info(log, "Available output formats:\n");
|
||||||
while ((c = av_oformat_next(c)))
|
while ((c = av_oformat_next(c)))
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, " --of=%-13s %s\n", c->name,
|
mp_info(log, " --of=%-13s %s\n", c->name,
|
||||||
c->long_name ? c->long_name : "");
|
c->long_name ? c->long_name : "");
|
||||||
av_free(c);
|
av_free(c);
|
||||||
}
|
}
|
||||||
if (CHECKV(opts->encode_output.fopts)) {
|
if (CHECKV(opts->fopts)) {
|
||||||
AVFormatContext *c = avformat_alloc_context();
|
AVFormatContext *c = avformat_alloc_context();
|
||||||
AVOutputFormat *format = NULL;
|
AVOutputFormat *format = NULL;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO,
|
mp_info(log, "Available output format ctx->options:\n");
|
||||||
"Available output format ctx->options:\n");
|
encode_lavc_printoptions(log, c, " --ofopts=", " ", NULL,
|
||||||
encode_lavc_printoptions(c, " --ofopts=", " ", NULL,
|
|
||||||
AV_OPT_FLAG_ENCODING_PARAM,
|
AV_OPT_FLAG_ENCODING_PARAM,
|
||||||
AV_OPT_FLAG_ENCODING_PARAM);
|
AV_OPT_FLAG_ENCODING_PARAM);
|
||||||
av_free(c);
|
av_free(c);
|
||||||
while ((format = av_oformat_next(format))) {
|
while ((format = av_oformat_next(format))) {
|
||||||
if (format->priv_class) {
|
if (format->priv_class) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --of=%s:\n",
|
mp_info(log, "Additionally, for --of=%s:\n",
|
||||||
format->name);
|
format->name);
|
||||||
encode_lavc_printoptions(&format->priv_class, " --ofopts=",
|
encode_lavc_printoptions(log, &format->priv_class, " --ofopts=",
|
||||||
" ", NULL,
|
" ", NULL,
|
||||||
AV_OPT_FLAG_ENCODING_PARAM,
|
AV_OPT_FLAG_ENCODING_PARAM,
|
||||||
AV_OPT_FLAG_ENCODING_PARAM);
|
AV_OPT_FLAG_ENCODING_PARAM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CHECKV(opts->encode_output.vopts)) {
|
if (CHECKV(opts->vopts)) {
|
||||||
AVCodecContext *c = avcodec_alloc_context3(NULL);
|
AVCodecContext *c = avcodec_alloc_context3(NULL);
|
||||||
AVCodec *codec = NULL;
|
AVCodec *codec = NULL;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO,
|
mp_info(log, "Available output video codec ctx->options:\n");
|
||||||
"Available output video codec ctx->options:\n");
|
encode_lavc_printoptions(log,
|
||||||
encode_lavc_printoptions(
|
|
||||||
c, " --ovcopts=", " ", NULL,
|
c, " --ovcopts=", " ", NULL,
|
||||||
AV_OPT_FLAG_ENCODING_PARAM |
|
AV_OPT_FLAG_ENCODING_PARAM |
|
||||||
AV_OPT_FLAG_VIDEO_PARAM,
|
AV_OPT_FLAG_VIDEO_PARAM,
|
||||||
@ -912,13 +903,13 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
|
|||||||
continue;
|
continue;
|
||||||
if (codec->type != AVMEDIA_TYPE_VIDEO)
|
if (codec->type != AVMEDIA_TYPE_VIDEO)
|
||||||
continue;
|
continue;
|
||||||
if (opts->encode_output.vcodec && opts->encode_output.vcodec[0] &&
|
if (opts->vcodec && opts->vcodec[0] &&
|
||||||
strcmp(opts->encode_output.vcodec, codec->name) != 0)
|
strcmp(opts->vcodec, codec->name) != 0)
|
||||||
continue;
|
continue;
|
||||||
if (codec->priv_class) {
|
if (codec->priv_class) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --ovc=%s:\n",
|
mp_info(log, "Additionally, for --ovc=%s:\n",
|
||||||
codec->name);
|
codec->name);
|
||||||
encode_lavc_printoptions(
|
encode_lavc_printoptions(log,
|
||||||
&codec->priv_class, " --ovcopts=",
|
&codec->priv_class, " --ovcopts=",
|
||||||
" ", NULL,
|
" ", NULL,
|
||||||
AV_OPT_FLAG_ENCODING_PARAM |
|
AV_OPT_FLAG_ENCODING_PARAM |
|
||||||
@ -928,12 +919,11 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CHECKV(opts->encode_output.aopts)) {
|
if (CHECKV(opts->aopts)) {
|
||||||
AVCodecContext *c = avcodec_alloc_context3(NULL);
|
AVCodecContext *c = avcodec_alloc_context3(NULL);
|
||||||
AVCodec *codec = NULL;
|
AVCodec *codec = NULL;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO,
|
mp_info(log, "Available output audio codec ctx->options:\n");
|
||||||
"Available output audio codec ctx->options:\n");
|
encode_lavc_printoptions(log,
|
||||||
encode_lavc_printoptions(
|
|
||||||
c, " --oacopts=", " ", NULL,
|
c, " --oacopts=", " ", NULL,
|
||||||
AV_OPT_FLAG_ENCODING_PARAM |
|
AV_OPT_FLAG_ENCODING_PARAM |
|
||||||
AV_OPT_FLAG_AUDIO_PARAM,
|
AV_OPT_FLAG_AUDIO_PARAM,
|
||||||
@ -945,13 +935,13 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
|
|||||||
continue;
|
continue;
|
||||||
if (codec->type != AVMEDIA_TYPE_AUDIO)
|
if (codec->type != AVMEDIA_TYPE_AUDIO)
|
||||||
continue;
|
continue;
|
||||||
if (opts->encode_output.acodec && opts->encode_output.acodec[0] &&
|
if (opts->acodec && opts->acodec[0] &&
|
||||||
strcmp(opts->encode_output.acodec, codec->name) != 0)
|
strcmp(opts->acodec, codec->name) != 0)
|
||||||
continue;
|
continue;
|
||||||
if (codec->priv_class) {
|
if (codec->priv_class) {
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --oac=%s:\n",
|
mp_info(log, "Additionally, for --oac=%s:\n",
|
||||||
codec->name);
|
codec->name);
|
||||||
encode_lavc_printoptions(
|
encode_lavc_printoptions(log,
|
||||||
&codec->priv_class, " --oacopts=",
|
&codec->priv_class, " --oacopts=",
|
||||||
" ", NULL,
|
" ", NULL,
|
||||||
AV_OPT_FLAG_ENCODING_PARAM |
|
AV_OPT_FLAG_ENCODING_PARAM |
|
||||||
@ -961,28 +951,28 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CHECKS(opts->encode_output.vcodec)) {
|
if (CHECKS(opts->vcodec)) {
|
||||||
AVCodec *c = NULL;
|
AVCodec *c = NULL;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output video codecs:\n");
|
mp_info(log, "Available output video codecs:\n");
|
||||||
while ((c = av_codec_next(c))) {
|
while ((c = av_codec_next(c))) {
|
||||||
if (!av_codec_is_encoder(c))
|
if (!av_codec_is_encoder(c))
|
||||||
continue;
|
continue;
|
||||||
if (c->type != AVMEDIA_TYPE_VIDEO)
|
if (c->type != AVMEDIA_TYPE_VIDEO)
|
||||||
continue;
|
continue;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, " --ovc=%-12s %s\n", c->name,
|
mp_info(log, " --ovc=%-12s %s\n", c->name,
|
||||||
c->long_name ? c->long_name : "");
|
c->long_name ? c->long_name : "");
|
||||||
}
|
}
|
||||||
av_free(c);
|
av_free(c);
|
||||||
}
|
}
|
||||||
if (CHECKS(opts->encode_output.acodec)) {
|
if (CHECKS(opts->acodec)) {
|
||||||
AVCodec *c = NULL;
|
AVCodec *c = NULL;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output audio codecs:\n");
|
mp_info(log, "Available output audio codecs:\n");
|
||||||
while ((c = av_codec_next(c))) {
|
while ((c = av_codec_next(c))) {
|
||||||
if (!av_codec_is_encoder(c))
|
if (!av_codec_is_encoder(c))
|
||||||
continue;
|
continue;
|
||||||
if (c->type != AVMEDIA_TYPE_AUDIO)
|
if (c->type != AVMEDIA_TYPE_AUDIO)
|
||||||
continue;
|
continue;
|
||||||
mp_msg(MSGT_ENCODE, MSGL_INFO, " --oac=%-12s %s\n", c->name,
|
mp_info(log, " --oac=%-12s %s\n", c->name,
|
||||||
c->long_name ? c->long_name : "");
|
c->long_name ? c->long_name : "");
|
||||||
}
|
}
|
||||||
av_free(c);
|
av_free(c);
|
||||||
@ -1057,7 +1047,7 @@ void encode_lavc_fail(struct encode_lavc_context *ctx, const char *format, ...)
|
|||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, format);
|
va_start(va, format);
|
||||||
mp_msg_va(MSGT_ENCODE, MSGL_ERR, format, va);
|
mp_msg_log_va(ctx->log, MSGL_ERR, format, va);
|
||||||
if (ctx->failed)
|
if (ctx->failed)
|
||||||
return;
|
return;
|
||||||
ctx->failed = true;
|
ctx->failed = true;
|
||||||
@ -1071,8 +1061,7 @@ bool encode_lavc_set_csp(struct encode_lavc_context *ctx,
|
|||||||
|
|
||||||
if (ctx->header_written) {
|
if (ctx->header_written) {
|
||||||
if (stream->codec->colorspace != mp_csp_to_avcol_spc(csp))
|
if (stream->codec->colorspace != mp_csp_to_avcol_spc(csp))
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
MP_WARN(ctx, "can not change color space during encoding\n");
|
||||||
"encode-lavc: can not change color space during encoding\n");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1087,8 +1076,7 @@ bool encode_lavc_set_csp_levels(struct encode_lavc_context *ctx,
|
|||||||
|
|
||||||
if (ctx->header_written) {
|
if (ctx->header_written) {
|
||||||
if (stream->codec->color_range != mp_csp_levels_to_avcol_range(lev))
|
if (stream->codec->color_range != mp_csp_levels_to_avcol_range(lev))
|
||||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
MP_WARN(ctx, "can not change color space during encoding\n");
|
||||||
"encode-lavc: can not change color space during encoding\n");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,9 @@
|
|||||||
#include "video/csputils.h"
|
#include "video/csputils.h"
|
||||||
|
|
||||||
struct encode_lavc_context {
|
struct encode_lavc_context {
|
||||||
|
struct mpv_global *global;
|
||||||
struct encode_output_conf *options;
|
struct encode_output_conf *options;
|
||||||
|
struct mp_log *log;
|
||||||
|
|
||||||
float vo_fps;
|
float vo_fps;
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ static bool handle_help_options(struct MPContext *mpctx)
|
|||||||
opt_exit = 1;
|
opt_exit = 1;
|
||||||
}
|
}
|
||||||
#if HAVE_ENCODING
|
#if HAVE_ENCODING
|
||||||
if (encode_lavc_showhelp(mpctx->opts))
|
if (encode_lavc_showhelp(log, &opts->encode_output))
|
||||||
opt_exit = 1;
|
opt_exit = 1;
|
||||||
#endif
|
#endif
|
||||||
return opt_exit;
|
return opt_exit;
|
||||||
@ -365,7 +365,8 @@ static int mpv_main(int argc, char *argv[])
|
|||||||
|
|
||||||
#if HAVE_ENCODING
|
#if HAVE_ENCODING
|
||||||
if (opts->encode_output.file && *opts->encode_output.file) {
|
if (opts->encode_output.file && *opts->encode_output.file) {
|
||||||
mpctx->encode_lavc_ctx = encode_lavc_init(&opts->encode_output);
|
mpctx->encode_lavc_ctx = encode_lavc_init(&opts->encode_output,
|
||||||
|
mpctx->global);
|
||||||
if(!mpctx->encode_lavc_ctx) {
|
if(!mpctx->encode_lavc_ctx) {
|
||||||
MP_INFO(mpctx, "Encoding initialization failed.");
|
MP_INFO(mpctx, "Encoding initialization failed.");
|
||||||
exit_player(mpctx, EXIT_ERROR);
|
exit_player(mpctx, EXIT_ERROR);
|
||||||
|
Loading…
Reference in New Issue
Block a user