jobjectArray Java_org_videolan_libvlc_LibVLC_readTracksInfo(JNIEnv *env, jobject thiz, jlong instance, jstring mrl) { /* Create a new item and assign it to the media player. */ libvlc_media_t *p_m = new_media(instance, env, thiz, mrl, false, false); if (p_m == NULL) { LOGE("Could not create the media!"); return NULL; } libvlc_media_parse(p_m); jobjectArray jar = read_track_info_internal(env, thiz, p_m); libvlc_media_release(p_m); return jar; }
jboolean Java_org_videolan_libvlc_LibVLC_hasVideoTrack(JNIEnv *env, jobject thiz, jlong i_instance, jstring fileLocation) { /* Create a new item and assign it to the media player. */ libvlc_media_t *p_m = new_media(i_instance, env, thiz, fileLocation, false, false); if (p_m == NULL) { LOGE("Could not create the media!"); return JNI_FALSE; } /* Get the tracks information of the media. */ libvlc_media_parse(p_m); libvlc_media_player_t* p_mp = libvlc_media_player_new_from_media(p_m); libvlc_media_player_set_video_title_display(p_mp, libvlc_position_disable, 0); struct length_change_monitor* monitor; monitor = malloc(sizeof(struct length_change_monitor)); if (!monitor) return 0; /* Initialize pthread variables. */ pthread_mutex_init(&monitor->doneMutex, NULL); pthread_cond_init(&monitor->doneCondVar, NULL); monitor->length_changed = false; libvlc_event_manager_t *ev = libvlc_media_player_event_manager(p_mp); libvlc_event_attach(ev, libvlc_MediaPlayerLengthChanged, length_changed_callback, monitor); libvlc_media_player_play( p_mp ); pthread_mutex_lock(&monitor->doneMutex); struct timespec deadline; clock_gettime(CLOCK_REALTIME, &deadline); deadline.tv_sec += 2; /* If "VLC can't open the file", return */ int mp_alive = 1; while( !monitor->length_changed && mp_alive ) { pthread_cond_timedwait(&monitor->doneCondVar, &monitor->doneMutex, &deadline); mp_alive = libvlc_media_player_will_play(p_mp); } pthread_mutex_unlock(&monitor->doneMutex); int i_nbTracks; if( mp_alive ) i_nbTracks = libvlc_video_get_track_count(p_mp); else i_nbTracks = -1; LOGI("Number of video tracks: %d",i_nbTracks); libvlc_event_detach(ev, libvlc_MediaPlayerLengthChanged, length_changed_callback, monitor); libvlc_media_player_stop(p_mp); libvlc_media_player_release(p_mp); libvlc_media_release(p_m); pthread_mutex_destroy(&monitor->doneMutex); pthread_cond_destroy(&monitor->doneCondVar); free(monitor); if(i_nbTracks > 0) return JNI_TRUE; else if(i_nbTracks < 0) (*env)->ThrowNew(env, (*env)->FindClass(env, "java/io/IOException"), "VLC can't open the file"); else return JNI_FALSE; }
/** * Thumbnailer main function. * return null if the thumbail generation failed. **/ jbyteArray Java_org_videolan_vlc_LibVLC_getThumbnail(JNIEnv *env, jobject thiz, jint instance, jstring filePath, jint width, jint height) { libvlc_instance_t *libvlc = (libvlc_instance_t *)instance; jbyteArray byteArray = NULL; /* Create the thumbnailer data structure */ thumbnailer_sys_t *sys = calloc(1, sizeof(thumbnailer_sys_t)); if (sys == NULL) { LOGE("Couldn't create the thumbnailer data structure!"); return NULL; } /* Initialize the barrier. */ pthread_mutex_init(&sys->doneMutex, NULL); pthread_cond_init(&sys->doneCondVar, NULL); /* Create a media player playing environment */ sys->mp = libvlc_media_player_new(libvlc); libvlc_media_t *m = new_media(instance, env, thiz, filePath); if (m == NULL) { LOGE("Couldn't create the media to play!"); goto end; } libvlc_media_add_option( m, ":no-audio" ); libvlc_media_player_set_media(sys->mp, m); libvlc_media_release(m); /* Get the size of the video with the tracks information of the media. */ libvlc_media_track_info_t *tracks; libvlc_media_parse(m); int nbTracks = libvlc_media_get_tracks_info(m, &tracks); unsigned i, videoWidth, videoHeight; bool hasVideoTrack = false; for (i = 0; i < nbTracks; ++i) if (tracks[i].i_type == libvlc_track_video) { videoWidth = tracks[i].u.video.i_width; videoHeight = tracks[i].u.video.i_height; hasVideoTrack = true; break; } free(tracks); /* Abord if we have not found a video track. */ if (!hasVideoTrack) { LOGE("Could not find a video track in this file.\n"); goto end; } /* Compute the size parameters of the frame to generate. */ unsigned picWidth = width; unsigned picHeight = height; float videoAR = (float)videoWidth / videoHeight; float screenAR = (float)width / height; if (screenAR < videoAR) { picHeight = (float)width / videoAR; sys->thumbnailOffset = (height - picHeight) / 2 * width * PIXEL_SIZE; } else { picWidth = (float)height * videoAR; sys->thumbnailOffset = (width - picWidth) / 2 * PIXEL_SIZE; } sys->picPitch = picWidth * PIXEL_SIZE; sys->lineSize = width * PIXEL_SIZE; sys->nbLines = picHeight; /* Allocate the memory to store the frames. */ unsigned picSize = sys->picPitch * picHeight; sys->frameData = malloc(picSize); if (sys->frameData == NULL) { LOGE("Couldn't allocate the memory to store the frame!"); goto end; } /* Allocate the memory to store the thumbnail. */ unsigned thumbnailSize = width * height * PIXEL_SIZE; sys->thumbnail = calloc(thumbnailSize, 1); if (sys->thumbnail == NULL) { LOGE("Couldn't allocate the memory to store the thumbnail!"); goto end; } /* Set the video format and the callbacks. */ libvlc_video_set_format(sys->mp, "RGBA", picWidth, picHeight, sys->picPitch); libvlc_video_set_callbacks(sys->mp, thumbnailer_lock, thumbnailer_unlock, NULL, (void*)sys); /* Play the media. */ libvlc_media_player_play(sys->mp); libvlc_media_player_set_position(sys->mp, THUMBNAIL_POSITION); /* Wait for the thumbnail to be generated. */ pthread_mutex_lock(&sys->doneMutex); while (!sys->hasThumb) pthread_cond_wait(&sys->doneCondVar, &sys->doneMutex); pthread_mutex_unlock(&sys->doneMutex); /* Stop and realease the media player. */ libvlc_media_player_stop(sys->mp); libvlc_media_player_release(sys->mp); /* Create the Java byte array to return the create thumbnail. */ byteArray = (*env)->NewByteArray(env, thumbnailSize); if (byteArray == NULL) { LOGE("Couldn't allocate the Java byte array to store the frame!"); goto end; } (*env)->SetByteArrayRegion(env, byteArray, 0, thumbnailSize, (jbyte *)sys->thumbnail); (*env)->DeleteLocalRef(env, byteArray); end: pthread_mutex_destroy(&sys->doneMutex); pthread_cond_destroy(&sys->doneCondVar); free(sys->thumbnail); free(sys->frameData); free(sys); return byteArray; }
SCSI_MEDIA new_scsi_media(void) { return (SCSI_MEDIA) new_media(sizeof(struct SCSI_media)); }
/** * Thumbnailer main function. * return null if the thumbail generation failed. **/ jbyteArray Java_org_videolan_libvlc_LibVLC_getThumbnail(JNIEnv *env, jobject thiz, jlong instance, jstring filePath, const jint frameWidth, const jint frameHeight) { libvlc_instance_t *libvlc = (libvlc_instance_t *)(intptr_t)instance; jbyteArray byteArray = NULL; /* Create the thumbnailer data structure */ thumbnailer_sys_t *sys = calloc(1, sizeof(thumbnailer_sys_t)); if (sys == NULL) { LOGE("Could not create the thumbnailer data structure!"); goto enomem; } /* Initialize the barrier. */ pthread_mutex_init(&sys->doneMutex, NULL); pthread_cond_init(&sys->doneCondVar, NULL); /* Create a media player playing environment */ libvlc_media_player_t *mp = libvlc_media_player_new(libvlc); libvlc_media_player_set_video_title_display(mp, libvlc_position_disable, 0); libvlc_media_t *m = new_media(instance, env, thiz, filePath, true, false); if (m == NULL) { LOGE("Could not create the media to play!"); goto end; } /* Fast and no options */ libvlc_media_add_option( m, ":no-audio" ); libvlc_media_add_option( m, ":no-spu" ); libvlc_media_add_option( m, ":no-osd" ); libvlc_media_player_set_media(mp, m); /* Get the size of the video with the tracks information of the media. */ libvlc_media_track_t **tracks; libvlc_media_parse(m); int nbTracks = libvlc_media_tracks_get(m, &tracks); libvlc_media_release(m); /* Parse the results */ unsigned videoWidth = 0, videoHeight = 0; bool hasVideoTrack = false; for (unsigned i = 0; i < nbTracks; ++i) if (tracks[i]->i_type == libvlc_track_video) { videoWidth = tracks[i]->video->i_width; videoHeight = tracks[i]->video->i_height; hasVideoTrack = true; break; } libvlc_media_tracks_release(tracks, nbTracks); /* Abort if we have not found a video track. */ if (!hasVideoTrack) { LOGE("Could not find any video track in this file.\n"); goto end; } LOGD("Video dimensions: %ix%i.\n", videoWidth, videoHeight ); /* VLC could not tell us the size */ if( videoWidth == 0 || videoHeight == 0 ) { LOGE("Could not find the video dimensions.\n"); goto end; } if( videoWidth < THUMBNAIL_MIN_WIDTH || videoHeight < THUMBNAIL_MIN_HEIGHT || videoWidth > THUMBNAIL_MAX_WIDTH || videoHeight > THUMBNAIL_MAX_HEIGHT ) { LOGE("Wrong video dimensions.\n"); goto end; } /* Compute the size parameters of the frame to generate. */ unsigned thumbWidth = frameWidth; unsigned thumbHeight = frameHeight; const float inputAR = (float)videoWidth / videoHeight; const float screenAR = (float)frameWidth / frameHeight; /* Most of the cases, video is wider than tall */ if (screenAR < inputAR) { thumbHeight = (float)frameWidth / inputAR + 1; sys->blackBorders = ( (frameHeight - thumbHeight) / 2 ) * frameWidth; } else { LOGD("Weird aspect Ratio.\n"); thumbWidth = (float)frameHeight * inputAR; sys->blackBorders = (frameWidth - thumbWidth) / 2; } sys->thumbPitch = thumbWidth * PIXEL_SIZE; sys->thumbHeight = thumbHeight; sys->frameWidth = frameWidth; /* Allocate the memory to store the frames. */ size_t thumbSize = sys->thumbPitch * (sys->thumbHeight+1); sys->thumbData = malloc(thumbSize); if (sys->thumbData == NULL) { LOGE("Could not allocate the memory to store the frame!"); goto end; } /* Allocate the memory to store the thumbnail. */ unsigned frameSize = frameWidth * frameHeight * PIXEL_SIZE; sys->frameData = calloc(frameSize, 1); if (sys->frameData == NULL) { LOGE("Could not allocate the memory to store the thumbnail!"); goto end; } /* Set the video format and the callbacks. */ libvlc_video_set_format(mp, "RGBA", thumbWidth, thumbHeight, sys->thumbPitch); libvlc_video_set_callbacks(mp, thumbnailer_lock, thumbnailer_unlock, NULL, (void*)sys); sys->state = THUMB_SEEKING; /* Play the media. */ libvlc_media_player_play(mp); libvlc_media_player_set_position(mp, THUMBNAIL_POSITION); const int wait_time = 50000; const int max_attempts = 100; for (int i = 0; i < max_attempts; ++i) { if (libvlc_media_player_is_playing(mp) && libvlc_media_player_get_position(mp) >= THUMBNAIL_POSITION) break; usleep(wait_time); } /* Wait for the thumbnail to be generated. */ pthread_mutex_lock(&sys->doneMutex); sys->state = THUMB_SEEKED; struct timespec deadline; clock_gettime(CLOCK_REALTIME, &deadline); deadline.tv_sec += 10; /* amount of seconds before we abort thumbnailer */ do { int ret = pthread_cond_timedwait(&sys->doneCondVar, &sys->doneMutex, &deadline); if (ret == ETIMEDOUT) break; } while (sys->state != THUMB_DONE); pthread_mutex_unlock(&sys->doneMutex); /* Stop and release the media player. */ libvlc_media_player_stop(mp); libvlc_media_player_release(mp); if (sys->state == THUMB_DONE) { /* Create the Java byte array to return the create thumbnail. */ byteArray = (*env)->NewByteArray(env, frameSize); if (byteArray == NULL) { LOGE("Could not allocate the Java byte array to store the frame!"); goto end; } (*env)->SetByteArrayRegion(env, byteArray, 0, frameSize, (jbyte *)sys->frameData); } end: pthread_mutex_destroy(&sys->doneMutex); pthread_cond_destroy(&sys->doneCondVar); free(sys->frameData); free(sys->thumbData); free(sys); enomem: return byteArray; }
DEBLOCK_MEDIA new_deblock_media(void) { return (DEBLOCK_MEDIA) new_media(sizeof(struct deblock_media)); }