/*****************************************************************************
* medialib.c: Player/Media Library interractions
*****************************************************************************
* Copyright © 2018-2019 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include "player.h"
#include "misc/variables.h"
void
vlc_player_input_RestoreMlStates(struct vlc_player_input* input, bool force_pos)
{
vlc_player_t* player = input->player;
vlc_player_assert_locked(player);
int restore_pos;
if (force_pos)
restore_pos = VLC_PLAYER_RESTORE_PLAYBACK_POS_ALWAYS;
else
restore_pos = var_InheritInteger(input->thread, "restore-playback-pos");
const bool restore_states = var_InheritBool(input->thread, "restore-playback-states");
vlc_medialibrary_t* ml = vlc_ml_instance_get(input->player);
if (!ml)
return;
input_item_t* item = input_GetItem(input->thread);
vlc_ml_media_t* media = vlc_ml_get_media_by_mrl( ml, item->psz_uri);
if (!media)
return;
if (media->i_type != VLC_ML_MEDIA_TYPE_VIDEO ||
vlc_ml_media_get_all_playback_pref(ml, media->i_id,
&input->ml.states) != VLC_SUCCESS)
{
vlc_ml_release(media);
return;
}
input->ml.restore = (restore_pos == VLC_PLAYER_RESTORE_PLAYBACK_POS_ALWAYS) ?
VLC_RESTOREPOINT_TITLE : VLC_RESTOREPOINT_NONE;
input->ml.restore_states = restore_states;
/* If we are aiming at a specific title, wait for it to be added, and
* only then select it & set the position.
* If we're not aiming at a specific title, just set the position now.
*/
if (restore_pos == VLC_PLAYER_RESTORE_PLAYBACK_POS_ALWAYS &&
input->ml.states.current_title == -1 &&
media->f_progress > .0f)
input_SetPosition(input->thread, media->f_progress, false);
else if (restore_pos == VLC_PLAYER_RESTORE_PLAYBACK_POS_ASK &&
media->f_progress > .0f)
{
input->ml.delay_restore = true;
input->ml.pos = media->f_progress;
}
vlc_ml_release(media);
if (!restore_states)
return;
if (input->ml.states.rate != .0f)
vlc_player_ChangeRate(player, input->ml.states.rate);
const char *video_track_ids = input->ml.states.current_video_track;
const char *audio_track_ids = input->ml.states.current_audio_track;
const char *subtitle_track_ids = input->ml.states.current_subtitle_track;
if (video_track_ids)
vlc_player_input_SelectTracksByStringIds(input, VIDEO_ES,
video_track_ids);
if (audio_track_ids)
vlc_player_input_SelectTracksByStringIds(input, AUDIO_ES,
audio_track_ids);
if (subtitle_track_ids)
vlc_player_input_SelectTracksByStringIds(input, SPU_ES,
subtitle_track_ids);
vout_thread_t* vout = vlc_player_vout_Hold(player);
if (vout != NULL)
{
if (input->ml.states.zoom >= .0f)
var_SetFloat(vout, "zoom", input->ml.states.zoom);
else
var_SetFloat(vout, "zoom", 1.f);
if (input->ml.states.aspect_ratio)
var_SetString(vout, "aspect-ratio", input->ml.states.aspect_ratio);
else
var_SetString(vout, "aspect-ratio", NULL);
if (input->ml.states.deinterlace)
{
var_SetString(vout, "deinterlace-mode", input->ml.states.deinterlace);
var_SetInteger(vout, "deinterlace", 1);
}
else
{
var_SetString(vout, "deinterlace-mode", NULL);
var_SetInteger(vout, "deinterlace", 0);
}
if (input->ml.states.video_filter)
var_SetString(vout, "video-filter", input->ml.states.video_filter);
else
var_SetString(vout, "video-filter", NULL);
vout_Release(vout);
}
}
static bool
vlc_player_UpdateMediaType(const struct vlc_player_input* input,
vlc_medialibrary_t* ml, vlc_ml_media_t* media)
{
assert(media->i_type == VLC_ML_MEDIA_TYPE_UNKNOWN);
vlc_ml_media_type_t media_type;
if (input->ml.has_video_tracks)
media_type = VLC_ML_MEDIA_TYPE_VIDEO;
else if (input->ml.has_audio_tracks)
media_type = VLC_ML_MEDIA_TYPE_AUDIO;
else
return false;
if (vlc_ml_media_set_type(ml, media->i_id, media_type) != VLC_SUCCESS)
return false;
media->i_type = media_type;
return true;
}
static void
vlc_player_CompareAssignState(char **target_ptr, char **input_ptr)
{
/* We only want to save these states if they are different, and not the
* default values (NULL), so this means that either one is NULL and the
* other isn't, or they are both non null and differ lexicographically */
char *target = *target_ptr;
char *input = *input_ptr;
if ( ( input != NULL && target != NULL &&
strcmp(input, target ) ) ||
( input == NULL && target != NULL ) ||
( input != NULL && target == NULL ) )
{
free(target);
*target_ptr = input;
*input_ptr = NULL;
}
else
{
free(target);
*target_ptr = NULL;
}
}
void
vlc_player_UpdateMLStates(vlc_player_t *player, struct vlc_player_input* input)
{
/* Do not save states for any secondary player. If this player's parent is
the main vlc object, then it's the main player */
if (player->obj.priv->parent != (vlc_object_t*)vlc_object_instance(player))
return;
vlc_medialibrary_t* ml = vlc_ml_instance_get(player);
if (!ml)
return;
input_item_t* item = input_GetItem(input->thread);
if (!item)
return;
vlc_ml_media_t* media = vlc_ml_get_media_by_mrl(ml, item->psz_uri);
if (!media)
{
/* We don't know this media yet, let's add it as an external media so
* we can still store its playback preferences
*/
media = vlc_ml_new_external_media(ml, item->psz_uri);
if (media == NULL)
return;
}
if (media->i_type == VLC_ML_MEDIA_TYPE_UNKNOWN)
{
if (!vlc_player_UpdateMediaType(input, ml, media))
{
vlc_ml_release( media );
return;
}
}
assert(media->i_type != VLC_ML_MEDIA_TYPE_UNKNOWN);
if ( var_GetBool( input->thread, "save-recentplay" ) )
vlc_ml_media_update_progress( ml, media->i_id, input->position );
/* If the value changed during the playback, update it in the medialibrary.
* If not, set each state to their "unset" values, so that they aren't saved
* in database */
if ((input->ml.states.current_title == -1 && input->title_selected != 0) ||
(input->ml.states.current_title != -1 &&
input->ml.states.current_title != (int)input->title_selected))
{
input->ml.states.current_title = input->title_selected;
}
else
input->ml.states.current_title = -1;
/* We use .0f to signal an unsaved rate. We want to save it to the ml if it
* changed, and if it's not the player's default value when the value was
* never saved in the ML */
if (input->rate != input->ml.states.rate &&
(input->rate != 1.f || input->ml.states.rate != .0f))
input->ml.states.rate = input->rate;
else
input->ml.states.rate = -1.f;
struct vlc_player_track_priv* t;
vout_thread_t* vout = NULL;
vlc_vector_foreach(t, &input->video_track_vector)
{
if (!t->t.selected)
continue;
enum vlc_vout_order order;
vout = vlc_player_GetEsIdVout(player, t->t.es_id, &order);
if (vout != NULL && order == VLC_VOUT_ORDER_PRIMARY)
break;
vout = NULL;
}
if (vout != NULL)
{
char* aspect_ratio = var_GetNonEmptyString(vout, "aspect-ratio");
char* crop = var_GetNonEmptyString(vout, "crop");
char* deinterlace = var_GetNonEmptyString(vout, "deinterlace-mode");
char* video_filter = var_GetNonEmptyString(vout, "video-filter");
vlc_player_CompareAssignState(&input->ml.states.aspect_ratio, &aspect_ratio);
vlc_player_CompareAssignState(&input->ml.states.crop, &crop);
vlc_player_CompareAssignState(&input->ml.states.deinterlace, &deinterlace);
vlc_player_CompareAssignState(&input->ml.states.video_filter, &video_filter);
free(video_filter);
free(deinterlace);
free(crop);
free(aspect_ratio);
if (input->ml.states.deinterlace != NULL &&
!strcmp(input->ml.states.deinterlace, "auto"))
{
free(input->ml.states.deinterlace);
input->ml.states.deinterlace = NULL;
}
float zoom = var_GetFloat(vout, "zoom");
if (zoom != input->ml.states.zoom &&
(zoom != 1.f && input->ml.states.zoom >= .0f))
input->ml.states.zoom = zoom;
else
input->ml.states.zoom = -1.f;
}
char *video_track_ids =
vlc_player_input_GetSelectedTrackStringIds(input, VIDEO_ES);
char *audio_track_ids =
vlc_player_input_GetSelectedTrackStringIds(input, AUDIO_ES);
char *subtitle_track_ids =
vlc_player_input_GetSelectedTrackStringIds(input, SPU_ES);
vlc_player_CompareAssignState(&input->ml.states.current_video_track, &video_track_ids);
vlc_player_CompareAssignState(&input->ml.states.current_audio_track, &audio_track_ids);
vlc_player_CompareAssignState(&input->ml.states.current_subtitle_track, &subtitle_track_ids);
free(video_track_ids);
free(audio_track_ids);
free(subtitle_track_ids);
vlc_ml_media_set_all_playback_states(ml, media->i_id, &input->ml.states);
vlc_ml_release(&input->ml.states);
vlc_ml_release(media);
}
void
vlc_player_RestorePlaybackPos(vlc_player_t *player)
{
vlc_player_input_RestoreMlStates(player->input, true);
}
¤ Dauer der Verarbeitung: 0.4 Sekunden
¤
*© Formatika GbR, Deutschland
|
|