I Have recently embarked upon creating some base examples using libmpv.
https://github.com/mpv-player/mpv/tree/master/libmpv
I have Done just a basic command line video splash screen in the native C API (will look at embedding the playback window in SDL2 or raylib/raygui at a latter date) and also plan on doing some Python examples of which 2 binders are readily available.
FreeBASIC doesn't currently have a libmpv binder, so I have rolled one up with FBFrog to have a shot at it.
I am only using the libmpv client.h and the shared libmpv-2.dll at the moment. The definitions and declarations of the output FBFrog client is only about 300 lines so not too much.
I am currently stuck on 2 issues that I can't seam to find a way past and both may be related. It's difficult to debug what is going on inside the dll so I am attempting to be pedantic with the data being sent to the dll.
Issue one is with type name conflicts between FB and C. As and example the C routines are using "char *string;" in one of the structures which conflicts with the FB String type:
Code: Select all
typedef struct mpv_node {
union {
char *string; /** valid if format==MPV_FORMAT_STRING */
int flag; /** valid if format==MPV_FORMAT_FLAG */
int64_t int64; /** valid if format==MPV_FORMAT_INT64 */
double double_; /** valid if format==MPV_FORMAT_DOUBLE */
struct mpv_node_list *list;
struct mpv_byte_array *ba;
} u;
Code: Select all
union mpv_node_u
string as zstring ptr
flag as long
int64 as longint
double_ as double
list as mpv_node_list ptr
ba as mpv_byte_array ptr
end union
I have about 6 of these type conflicts to correct.
Second issue is in sending a 2D array of zstring Ptr to the dll
I feel sure that I have constructed the array correctly but sending it to the libmpv-2.dll via the client.bi returns an error message:
mpv API error: invalid parameter
I am uncertain if I am mangling the pointers via the binder, or if it is related to the type name conflict above.
Here is the basic routines.
In C:
Code: Select all
const char *cmd1[] = {"loadfile", "donkey.mp4", NULL}; // A 2D static array **cmd1
mpv_command(ctx, cmd1) // The function call. ctx is the handle mpv_handle *ctx = mpv_create();
int mpv_command(mpv_handle *ctx, const char **args) // the function declaration from the dll header.
Code: Select all
Dim As zString Ptr cmd1(2) = {@"loadfile", @"donkey.mp4", NULL}
mpv_command(ctx, cmd1())
'declare function mpv_command(byval ctx as mpv_handle ptr, byval args as const zstring ptr ptr) as long '' FBFrog Output (type error)
declare function mpv_command(byval ctx as mpv_handle ptr, args() as const zstring ptr ptr) as long '' <- my correction args()
Printing the zString before sending it as an argument appears correct:
Code: Select all
dim j As Integer
For j = 0 To 2 Step +1
Print *cmd1(j); "|"
'Print *cast(zstring ptr, cmd1(j))
Next j
Some more context to how mpv_command( , args()) is used within the libmpv source:
Code: Select all
'' client.bi
declare function mpv_command(byval ctx as mpv_handle ptr, args() as const zstring ptr ptr) as long
// C Source
// wrapper
int mpv_command(mpv_handle *ctx, const char **args)
{
return run_client_command(ctx, mp_input_parse_cmd_strv(ctx->log, args), NULL);
}
Code: Select all
// tokenise the array of 3 strings to a node structure
struct mp_cmd *mp_input_parse_cmd_strv(struct mp_log *log, const char **argv)
{
int count = 0;
while (argv[count])
count++;
mpv_node *items = talloc_zero_array(NULL, mpv_node, count);
mpv_node_list list = {.values = items, .num = count};
mpv_node node = {.format = MPV_FORMAT_NODE_ARRAY, .u = {.list = &list}};
for (int n = 0; n < count; n++) {
items[n] = (mpv_node){.format = MPV_FORMAT_STRING,
.u = {.string = (char *)argv[n]}};
}
struct mp_cmd *res = mp_input_parse_cmd_node(log, &node);
talloc_free(items);
return res;
}
Code: Select all
// The structure
typedef struct mp_cmd {
char *name;
struct mp_cmd_arg *args;
int nargs;
int flags; // mp_cmd_flags bitfield
char *original;
char *desc; // (usually NULL since stripped away later)
char *input_section;
bool is_up_down : 1;
bool is_up : 1;
bool emit_on_up : 1;
bool is_mouse_button : 1;
bool repeated : 1;
bool mouse_move : 1;
int mouse_x, mouse_y;
struct mp_cmd *queue_next;
double scale; // for scaling numeric arguments
int scale_units;
const struct mp_cmd_def *def;
char *sender; // name of the client API user which sent this
char *key_name; // string representation of the key binding
char *key_text; // text if key is a text key
} mp_cmd_t;
Code: Select all
// Finally runs node structure with the 3 arg()
static int run_client_command(mpv_handle *ctx, struct mp_cmd *cmd, mpv_node *res)
{
if (!cmd)
return MPV_ERROR_INVALID_PARAMETER;
if (!ctx->mpctx->initialized) {
talloc_free(cmd);
return MPV_ERROR_UNINITIALIZED;
}
cmd->sender = ctx->name;
struct cmd_request req = {
.mpctx = ctx->mpctx,
.cmd = cmd,
.res = res,
.completion = MP_WAITER_INITIALIZER,
};
bool async = cmd->flags & MP_ASYNC_CMD;
lock_core(ctx);
if (async) {
run_command(ctx->mpctx, cmd, NULL, NULL, NULL);
} else {
struct mp_abort_entry *abort = NULL;
if (cmd->def->can_abort) {
abort = talloc_zero(NULL, struct mp_abort_entry);
abort->client = ctx;
}
run_command(ctx->mpctx, cmd, abort, cmd_complete, &req);
}
unlock_core(ctx);
if (!async)
mp_waiter_wait(&req.completion);
return req.status;
}
1. How to fix the type conflict between C and FB?
2. Does the 2D zString array look correct? or maybe it is just because of the C/BF type conflict 1. causing 2.?
Thanks
Axle