Skip to content

Commit

Permalink
Fix[ffmpeg_plugin]: better FFmpeg plugin insertion
Browse files Browse the repository at this point in the history
NOTE: requires a different version of the FFmpeg plugin which I haven't made yet
  • Loading branch information
artdeell committed Jan 5, 2025
1 parent 80e0a6a commit 4885012
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@
import android.content.pm.PackageManager;
import android.util.Log;

import java.io.File;

public class FFmpegPlugin {
public static boolean isAvailable = false;
public static String libraryPath;
public static String executablePath;
public static void discover(Context context) {
PackageManager manager = context.getPackageManager();
try {
PackageInfo ffmpegPluginInfo = manager.getPackageInfo("net.kdt.pojavlaunch.ffmpeg", PackageManager.GET_SHARED_LIBRARY_FILES);
libraryPath = ffmpegPluginInfo.applicationInfo.nativeLibraryDir;
isAvailable = true;
File ffmpegExecutable = new File(libraryPath, "libffmpeg.so");
executablePath = ffmpegExecutable.getAbsolutePath();
// Older plugin versions still have the old executable location
isAvailable = ffmpegExecutable.exists();
}catch (Exception e) {
Log.i("FFmpegPlugin", "Failed to discover plugin", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public static void setJavaEnvironment(Activity activity, String jreHome) throws
envMap.put("LD_LIBRARY_PATH", LD_LIBRARY_PATH);
envMap.put("PATH", jreHome + "/bin:" + Os.getenv("PATH"));
if(FFmpegPlugin.isAvailable) {
envMap.put("PATH", FFmpegPlugin.libraryPath+":"+envMap.get("PATH"));
envMap.put("POJAV_FFMPEG_PATH", FFmpegPlugin.executablePath);
}

if(LOCAL_RENDERER != null) {
Expand Down
35 changes: 25 additions & 10 deletions app_pojavlauncher/src/main/jni/input_bridge_v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,23 +230,38 @@ void sendData(int type, int i1, int i2, int i3, int i4) {
atomic_fetch_add_explicit(&pojav_environ->eventCounter, 1, memory_order_acquire);
}

static jbyteArray stringToBytes(JNIEnv *env, const char* string) {
const jsize string_data_len = (jsize)(strlen(string) + 1);
jbyteArray result = (*env)->NewByteArray(env, (jsize)string_data_len);
(*env)->SetByteArrayRegion(env, result, 0, (jsize)string_data_len, (const jbyte*) string);
return result;
}

/**
* Hooked version of java.lang.UNIXProcess.forkAndExec()
* which is used to handle the "open" command.
* which is used to handle the "open" command and "ffmpeg" invocations
*/
jint
hooked_ProcessImpl_forkAndExec(JNIEnv *env, jobject process, jint mode, jbyteArray helperpath, jbyteArray prog, jbyteArray argBlock, jint argc, jbyteArray envBlock, jint envc, jbyteArray dir, jintArray std_fds, jboolean redirectErrorStream) {
char *pProg = (char *)((*env)->GetByteArrayElements(env, prog, NULL));

// Here we only handle the "xdg-open" command
if (strcmp(basename(pProg), "xdg-open") != 0) {
(*env)->ReleaseByteArrayElements(env, prog, (jbyte *)pProg, 0);
return orig_ProcessImpl_forkAndExec(env, process, mode, helperpath, prog, argBlock, argc, envBlock, envc, dir, std_fds, redirectErrorStream);
}
const char *pProg = (char *)((*env)->GetByteArrayElements(env, prog, NULL));
const char* pProgBaseName = basename(pProg);
const size_t basename_len = strlen(pProgBaseName);
char prog_basename[basename_len];
memcpy(&prog_basename, pProgBaseName, basename_len + 1);
(*env)->ReleaseByteArrayElements(env, prog, (jbyte *)pProg, 0);

Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(env, NULL, /* CLIPBOARD_OPEN */ 2002, argBlock);
return 0;
if(strcmp(prog_basename, "xdg-open") == 0) {
// When invoking xdg-open, send that open command into the android half instead
Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(env, NULL, /* CLIPBOARD_OPEN */ 2002, argBlock);
return 0;
}else if(strcmp(prog_basename, "ffmpeg") == 0) {
// When invoking ffmpeg, always replace the program path with the path to ffmpeg from the plugin.
const char* ffmpeg_path = getenv("POJAV_FFMPEG_PATH");
if(ffmpeg_path != NULL) {
prog = stringToBytes(env, ffmpeg_path);
}
}
return orig_ProcessImpl_forkAndExec(env, process, mode, helperpath, prog, argBlock, argc, envBlock, envc, dir, std_fds, redirectErrorStream);
}

void hookExec() {
Expand Down

0 comments on commit 4885012

Please sign in to comment.