{
char *source_path = (char *) (*env)->GetStringUTFChars(env, path, 0);
const char *mime = "video/avc";
int width = 1920;
int height = 1080;
bool b_direct_renderer = true;
if ((p_sys = calloc(1, sizeof(*p_sys))) == NULL)
return -1;
///Find Class and Get Method/Field
for (int i = 0; classes[i].name; i++) {
*(jclass*)((uint8_t*)p_sys + classes[i].offset) = (*env)->FindClass(env, classes[i].name);
if ((*env)->ExceptionOccurred(env)) {
printf("Unable to find class %s", classes[i].name);
(*env)->ExceptionClear(env);
goto error;
}
}
jclass last_class;
for (int i = 0; members[i].name; i++) {
if (i == 0 || strcmp(members[i].class, members[i - 1].class))
last_class = (*env)->FindClass(env, members[i].class);
if ((*env)->ExceptionOccurred(env)) {
printf("Unable to find class %s", members[i].class);
(*env)->ExceptionClear(env);
goto error;
}
switch (members[i].type) {
case METHOD:
*(jmethodID*)((uint8_t*)p_sys + members[i].offset) =
(*env)->GetMethodID(env, last_class, members[i].name, members[i].sig);
break;
case STATIC_METHOD:
*(jmethodID*)((uint8_t*)p_sys + members[i].offset) =
(*env)->GetStaticMethodID(env, last_class, members[i].name, members[i].sig);
break;
case FIELD:
*(jfieldID*)((uint8_t*)p_sys + members[i].offset) =
(*env)->GetFieldID(env, last_class, members[i].name, members[i].sig);
break;
}
if ((*env)->ExceptionOccurred(env)) {
printf("Unable to find the member %s in %s",
members[i].name, members[i].class);
(*env)->ExceptionClear(env);
goto error;
}
}
printf("// MEDIACODEC LIST\n");
int num_codecs = (*env)->CallStaticIntMethod(env, p_sys->media_codec_list_class,
p_sys->get_codec_count);
jobject codec_name = NULL;
for (int i = 0; i < num_codecs; i++) {
jobject info = NULL;
jobject name = NULL;
jobject types = NULL;
jsize name_len = 0;
const char *name_ptr = NULL;
int profile_levels_len = 0, num_types = 0;
bool found = false;
info = (*env)->CallStaticObjectMethod(env, p_sys->media_codec_list_class,
p_sys->get_codec_info_at, i);
if ((*env)->CallBooleanMethod(env, info, p_sys->is_encoder))
goto loopclean;
types = (*env)->CallObjectMethod(env, info, p_sys->get_supported_types);
num_types = (*env)->GetArrayLength(env, types);
name = (*env)->CallObjectMethod(env, info, p_sys->get_name);
name_len = (*env)->GetStringUTFLength(env, name);
name_ptr = (*env)->GetStringUTFChars(env, name, NULL);
found = false;
printf("MEDIACODEC::LIST#%s\n", name_ptr);
if (!strncmp(name_ptr, "OMX.google.", __MIN(11, name_len)))
goto loopclean;
for (int j = 0; j < num_types && !found; j++) {
jobject type = (*env)->GetObjectArrayElement(env, types, j);
if (!jstrcmp(env, type, mime)) {
found = true;
}
(*env)->DeleteLocalRef(env, type);
}
if (found) {
printf("using %.*s", name_len, name_ptr);
p_sys->name = malloc(name_len + 1);
memcpy(p_sys->name, name_ptr, name_len);
p_sys->name[name_len] = '\0';
codec_name = name;
}
loopclean:
if (name)
(*env)->ReleaseStringUTFChars(env, name, name_ptr);
if (types)
(*env)->DeleteLocalRef(env, types);
if (info)
(*env)->DeleteLocalRef(env, info);
if (found)
break;
}
printf("// MEDIACODEC\n");
if (!codec_name) {
printf("No suitable codec matching %s was found", mime);
goto error;
}
printf("// MEDIACODEC Create\n");
p_sys->codec = (*env)->CallStaticObjectMethod(env, p_sys->media_codec_class,
p_sys->create_by_codec_name, codec_name);
if ((*env)->ExceptionOccurred(env)) {
printf("Exception occurred in MediaCodec.createByCodecName.");
(*env)->ExceptionClear(env);
goto error;
}
p_sys->allocated = true;
p_sys->codec = (*env)->NewGlobalRef(env, p_sys->codec);
jobject format = (*env)->CallStaticObjectMethod(env, p_sys->media_format_class,
p_sys->create_video_format, (*env)->NewStringUTF(env, mime),
width, height);
printf("// MEDIACODEC Configure\n");
p_sys->direct_rendering = b_direct_renderer;
if (p_sys->direct_rendering) {
jobject surf = surface;
if (surf) {
(*env)->CallVoidMethod(env, p_sys->codec, p_sys->configure, format, surf, NULL, 0);
if ((*env)->ExceptionOccurred(env)) {
printf("Exception occurred in MediaCodec.configure");
(*env)->ExceptionClear(env);
goto error;
}
} else {
printf("Failed to get the Android Surface, disabling direct rendering.");
p_sys->direct_rendering = false;
}
}
if (!p_sys->direct_rendering) {
(*env)->CallVoidMethod(env, p_sys->codec, p_sys->configure, format, NULL, NULL, 0);
if ((*env)->ExceptionOccurred(env)) {
printf("Exception occurred in MediaCodec.configure");
(*env)->ExceptionClear(env);
goto error;
}
}
printf("// MEDIACODEC Start\n");
(*env)->CallVoidMethod(env, p_sys->codec, p_sys->start);
if ((*env)->ExceptionOccurred(env)) {
printf("Exception occurred in MediaCodec.start");
(*env)->ExceptionClear(env);
goto error;
}
p_sys->started = true;
p_sys->input_buffers = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->get_input_buffers);
p_sys->output_buffers = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->get_output_buffers);
p_sys->buffer_info = (*env)->NewObject(env, p_sys->buffer_info_class, p_sys->buffer_info_ctor);
p_sys->input_buffers = (*env)->NewGlobalRef(env, p_sys->input_buffers);
p_sys->output_buffers = (*env)->NewGlobalRef(env, p_sys->output_buffers);
p_sys->buffer_info = (*env)->NewGlobalRef(env, p_sys->buffer_info);
p_sys->i_output_buffers = (*env)->GetArrayLength(env, p_sys->output_buffers);
VideoDecoderStart(p_sys);
//receiver_start(source_path, 2);
return 0;
error:
if(p_sys != NULL)
{
free(p_sys);
p_sys = NULL;
}
return -1;
}