mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-11-04 00:33:55 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			134 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <gst/gst.h>
 | 
						|
 | 
						|
#include <jni.h>
 | 
						|
#include <android/log.h>
 | 
						|
 | 
						|
static int transcode(const char *infile, const char *outfile,
 | 
						|
        const char *profile, jobject cb_obj, JNIEnv *env)
 | 
						|
{
 | 
						|
    GstElement *pipeline;
 | 
						|
    GstBus *bus;
 | 
						|
    GstMessage *msg;
 | 
						|
    gchar pipeline_str[1024];
 | 
						|
    int ret = 0;
 | 
						|
 | 
						|
    snprintf(pipeline_str, 1024,
 | 
						|
            "filesrc location=\"%s\" ! "
 | 
						|
            "progressreport silent=true format=percent update-freq=1 ! "
 | 
						|
            "decodebin2 ! audioconvert ! vorbisenc ! oggmux ! "
 | 
						|
            "filesink location=\"%s\"",
 | 
						|
            infile, outfile);
 | 
						|
 | 
						|
    pipeline = gst_parse_launch(pipeline_str, NULL);
 | 
						|
 | 
						|
    gst_element_set_state (pipeline, GST_STATE_PLAYING);
 | 
						|
 | 
						|
    bus = gst_element_get_bus(pipeline);
 | 
						|
 | 
						|
    for (;;) {
 | 
						|
        msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
 | 
						|
                GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_ELEMENT);
 | 
						|
 | 
						|
        switch (GST_MESSAGE_TYPE(msg)) {
 | 
						|
            case GST_MESSAGE_ELEMENT: {
 | 
						|
                const GstStructure *s = gst_message_get_structure(msg);
 | 
						|
                int percent;
 | 
						|
                jclass cb_class;
 | 
						|
                jmethodID cb_id;
 | 
						|
 | 
						|
                if (!cb_obj)
 | 
						|
                    break;
 | 
						|
 | 
						|
                if (!g_str_equal(gst_structure_get_name(s), "progress"))
 | 
						|
                    break;
 | 
						|
 | 
						|
                gst_structure_get_int(s, "percent", &percent);
 | 
						|
 | 
						|
                cb_class = (*env)->FindClass(env, "fr/free/nrw/commons/Transcoder$TranscoderProgressCallback");
 | 
						|
                if ((*env)->ExceptionCheck(env)) {
 | 
						|
                    __android_log_print(ANDROID_LOG_ERROR, "GStreamer", "Class not found");
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                cb_id = (*env)->GetMethodID(env, cb_class, "transcodeProgressCb", "(I)V");
 | 
						|
                if ((*env)->ExceptionCheck(env)) {
 | 
						|
                    __android_log_print(ANDROID_LOG_ERROR, "GStreamer", "Method not found");
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                (*env)->CallVoidMethod(env, cb_obj, cb_id, percent);
 | 
						|
                if ((*env)->ExceptionCheck(env)) {
 | 
						|
                    __android_log_print(ANDROID_LOG_ERROR, "GStreamer", "Method call failed");
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                break;
 | 
						|
            }
 | 
						|
 | 
						|
            case GST_MESSAGE_ERROR: {
 | 
						|
                GError *err = NULL;
 | 
						|
                gchar *debug_info = NULL;
 | 
						|
 | 
						|
                gst_message_parse_error(msg, &err, &debug_info);
 | 
						|
 | 
						|
                GST_ERROR_OBJECT(pipeline, "%s -- %s", err->message,
 | 
						|
                        debug_info ? debug_info : "no debug info");
 | 
						|
 | 
						|
                g_error_free(err);
 | 
						|
                g_free(debug_info);
 | 
						|
 | 
						|
                ret = -1;
 | 
						|
                goto done;
 | 
						|
            }
 | 
						|
 | 
						|
            case GST_MESSAGE_EOS:
 | 
						|
                goto done;
 | 
						|
 | 
						|
            default:
 | 
						|
                break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
done:
 | 
						|
    if (msg != NULL)
 | 
						|
        gst_message_unref (msg);
 | 
						|
 | 
						|
    gst_object_unref (bus);
 | 
						|
    gst_element_set_state (pipeline, GST_STATE_NULL);
 | 
						|
    gst_object_unref (pipeline);
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
jint Java_fr_free_nrw_commons_Transcoder_transcode(JNIEnv* env,
 | 
						|
        jclass *klass, jstring infile, jstring outfile, jstring profile,
 | 
						|
        jobject cb_obj)
 | 
						|
{
 | 
						|
    const char *in;
 | 
						|
    const char *out;
 | 
						|
    const char *prof = NULL;
 | 
						|
 | 
						|
    if (!infile || !outfile)
 | 
						|
        return -1;
 | 
						|
 | 
						|
    in = (*env)->GetStringUTFChars(env, infile, 0);
 | 
						|
    out = (*env)->GetStringUTFChars(env, outfile, 0);
 | 
						|
 | 
						|
    if (profile)
 | 
						|
        prof = (*env)->GetStringUTFChars(env, profile, 0);
 | 
						|
 | 
						|
    return transcode(in, out, prof, cb_obj, env);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#ifdef TEST
 | 
						|
int main(int argc, char **argv)
 | 
						|
{
 | 
						|
    if (argc != 3)
 | 
						|
        return -1;
 | 
						|
 | 
						|
    transcode(argv[1], argv[2], NULL);
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
#endif
 |