Experimental MPV player backend Related to #14, #22, & #85 You can switch to MPV in advanced settings and toggle using hardware decoding or not. This uses code and buildscripts from https://github.com/mpv-android/mpv-android, plus other third party libraries to build MPV
125 lines
4.4 KiB
C++
125 lines
4.4 KiB
C++
#include <jni.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <mpv/client.h>
|
|
|
|
#include "jni_utils.h"
|
|
#include "log.h"
|
|
#include "globals.h"
|
|
|
|
extern "C" {
|
|
jni_func(jint, setOptionString, jstring option, jstring value);
|
|
|
|
jni_func(jobject, getPropertyInt, jstring property);
|
|
jni_func(void, setPropertyInt, jstring property, jint value);
|
|
jni_func(jobject, getPropertyDouble, jstring property);
|
|
jni_func(void, setPropertyDouble, jstring property, jdouble value);
|
|
jni_func(jobject, getPropertyBoolean, jstring property);
|
|
jni_func(void, setPropertyBoolean, jstring property, jboolean value);
|
|
jni_func(jstring, getPropertyString, jstring jproperty);
|
|
jni_func(void, setPropertyString, jstring jproperty, jstring jvalue);
|
|
|
|
jni_func(void, observeProperty, jstring property, jint format);
|
|
}
|
|
|
|
jni_func(jint, setOptionString, jstring joption, jstring jvalue) {
|
|
CHECK_MPV_INIT();
|
|
|
|
const char *option = env->GetStringUTFChars(joption, NULL);
|
|
const char *value = env->GetStringUTFChars(jvalue, NULL);
|
|
|
|
int result = mpv_set_option_string(g_mpv, option, value);
|
|
|
|
env->ReleaseStringUTFChars(joption, option);
|
|
env->ReleaseStringUTFChars(jvalue, value);
|
|
|
|
return result;
|
|
}
|
|
|
|
static int common_get_property(JNIEnv *env, jstring jproperty, mpv_format format, void *output)
|
|
{
|
|
CHECK_MPV_INIT();
|
|
|
|
const char *prop = env->GetStringUTFChars(jproperty, NULL);
|
|
int result = mpv_get_property(g_mpv, prop, format, output);
|
|
if (result == MPV_ERROR_PROPERTY_UNAVAILABLE)
|
|
ALOGV("mpv_get_property(%s) format %d was unavailable", prop, format);
|
|
else if (result < 0)
|
|
ALOGE("mpv_get_property(%s) format %d returned error %s", prop, format, mpv_error_string(result));
|
|
env->ReleaseStringUTFChars(jproperty, prop);
|
|
|
|
return result;
|
|
}
|
|
|
|
static int common_set_property(JNIEnv *env, jstring jproperty, mpv_format format, void *value)
|
|
{
|
|
CHECK_MPV_INIT();
|
|
|
|
const char *prop = env->GetStringUTFChars(jproperty, NULL);
|
|
int result = mpv_set_property(g_mpv, prop, format, value);
|
|
if (result < 0)
|
|
ALOGE("mpv_set_property(%s, %p) format %d returned error %s", prop, value, format, mpv_error_string(result));
|
|
env->ReleaseStringUTFChars(jproperty, prop);
|
|
|
|
return result;
|
|
}
|
|
|
|
jni_func(jobject, getPropertyInt, jstring jproperty) {
|
|
int64_t value = 0;
|
|
if (common_get_property(env, jproperty, MPV_FORMAT_INT64, &value) < 0)
|
|
return NULL;
|
|
return env->NewObject(java_Integer, java_Integer_init, (jint)value);
|
|
}
|
|
|
|
jni_func(jobject, getPropertyDouble, jstring jproperty) {
|
|
double value = 0;
|
|
if (common_get_property(env, jproperty, MPV_FORMAT_DOUBLE, &value) < 0)
|
|
return NULL;
|
|
return env->NewObject(java_Double, java_Double_init, (jdouble)value);
|
|
}
|
|
|
|
jni_func(jobject, getPropertyBoolean, jstring jproperty) {
|
|
int value = 0;
|
|
if (common_get_property(env, jproperty, MPV_FORMAT_FLAG, &value) < 0)
|
|
return NULL;
|
|
return env->NewObject(java_Boolean, java_Boolean_init, (jboolean)value);
|
|
}
|
|
|
|
jni_func(jstring, getPropertyString, jstring jproperty) {
|
|
char *value;
|
|
if (common_get_property(env, jproperty, MPV_FORMAT_STRING, &value) < 0)
|
|
return NULL;
|
|
jstring jvalue = env->NewStringUTF(value);
|
|
mpv_free(value);
|
|
return jvalue;
|
|
}
|
|
|
|
jni_func(void, setPropertyInt, jstring jproperty, jint jvalue) {
|
|
int64_t value = static_cast<int64_t>(jvalue);
|
|
common_set_property(env, jproperty, MPV_FORMAT_INT64, &value);
|
|
}
|
|
|
|
jni_func(void, setPropertyDouble, jstring jproperty, jdouble jvalue) {
|
|
double value = static_cast<double>(jvalue);
|
|
common_set_property(env, jproperty, MPV_FORMAT_DOUBLE, &value);
|
|
}
|
|
|
|
jni_func(void, setPropertyBoolean, jstring jproperty, jboolean jvalue) {
|
|
int value = jvalue == JNI_TRUE ? 1 : 0;
|
|
common_set_property(env, jproperty, MPV_FORMAT_FLAG, &value);
|
|
}
|
|
|
|
jni_func(void, setPropertyString, jstring jproperty, jstring jvalue) {
|
|
const char *value = env->GetStringUTFChars(jvalue, NULL);
|
|
common_set_property(env, jproperty, MPV_FORMAT_STRING, &value);
|
|
env->ReleaseStringUTFChars(jvalue, value);
|
|
}
|
|
|
|
jni_func(void, observeProperty, jstring property, jint format) {
|
|
CHECK_MPV_INIT();
|
|
const char *prop = env->GetStringUTFChars(property, NULL);
|
|
int result = mpv_observe_property(g_mpv, 0, prop, (mpv_format)format);
|
|
if (result < 0)
|
|
ALOGE("mpv_observe_property(%s) format %d returned error %s", prop, format, mpv_error_string(result));
|
|
env->ReleaseStringUTFChars(property, prop);
|
|
}
|