[vlc-devel] [PATCH 09/12] player: Save & restore playback states
Hugo Beauzée-Luyssen
hugo at beauzee.fr
Wed Jul 31 11:20:38 CEST 2019
Refs #22524
---
src/input/player.c | 171 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 171 insertions(+)
diff --git a/src/input/player.c b/src/input/player.c
index e53849dc21..411456dfd8 100644
--- a/src/input/player.c
+++ b/src/input/player.c
@@ -35,6 +35,7 @@
#include <vlc_tick.h>
#include <vlc_decoder.h>
#include <vlc_memstream.h>
+#include <vlc_media_library.h>
#include "libvlc.h"
#include "input_internal.h"
@@ -145,6 +146,8 @@ struct vlc_player_input
float pos;
bool set;
} abloop_state[2];
+
+ vlc_ml_playback_states_all prefs;
};
struct vlc_player_t
@@ -649,6 +652,43 @@ vlc_player_title_list_GetCount(struct vlc_player_title_list *titles)
return titles->count;
}
+static void
+vlc_player_input_restore_ml_prefs(struct vlc_player_input* input,
+ const input_item_t* item)
+{
+ vlc_player_t* player = input->player;
+ vlc_player_assert_locked(player);
+
+ vlc_medialibrary_t* ml = vlc_ml_instance_get(input->player);
+ if (!ml)
+ return;
+ vlc_ml_media_t* media = vlc_ml_get_media_by_mrl( ml, item->psz_uri);
+ if (!media)
+ return;
+ if (vlc_ml_media_get_all_playback_pref(ml, media->i_id, &input->prefs) != VLC_SUCCESS)
+ return;
+ if (input->prefs.current_title >= 0)
+ {
+ /* 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 title, just set the position.
+ */
+ if (input->prefs.progress > .0f)
+ input_SetPosition(input->thread, input->prefs.progress, false);
+ }
+ if (input->prefs.rate != .0f)
+ vlc_player_ChangeRate(player, input->prefs.rate);
+ if (input->prefs.aspect_ratio)
+ var_SetString(input->thread, "aspect-ratio", input->prefs.aspect_ratio);
+ if (input->prefs.zoom)
+ var_SetString(input->thread, "zoom", input->prefs.zoom);
+ if (input->prefs.zoom)
+ var_SetString(input->thread, "deinterlace", input->prefs.zoom);
+ if (input->prefs.video_filter)
+ var_SetString(input->thread, "video-filter", input->prefs.video_filter);
+ vlc_ml_release(media);
+}
+
static struct vlc_player_input *
vlc_player_input_New(vlc_player_t *player, input_item_t *item)
{
@@ -687,6 +727,14 @@ vlc_player_input_New(vlc_player_t *player, input_item_t *item)
input->abloop_state[0].set = input->abloop_state[1].set = false;
+ memset(&input->prefs, 0, sizeof(input->prefs));
+ input->prefs.aspect_ratio = input->prefs.zoom = input->prefs.crop =
+ input->prefs.deinterlace = input->prefs.video_filter = NULL;
+ input->prefs.current_title = input->prefs.current_video_track =
+ input->prefs.current_audio_track =
+ input->prefs.current_subtitle_track = -1;
+ input->prefs.progress = -1.f;
+
input->thread = input_Create(player, input_thread_Events, input, item,
player->resource, player->renderer);
if (!input->thread)
@@ -695,6 +743,8 @@ vlc_player_input_New(vlc_player_t *player, input_item_t *item)
return NULL;
}
+ vlc_player_input_restore_ml_prefs(input, item);
+
/* Initial sub/audio delay */
const vlc_tick_t cat_delays[DATA_ES] = {
[AUDIO_ES] =
@@ -892,6 +942,87 @@ static int vlc_player_selected_track( const vlc_player_track_vector* tracks )
return 0;
}
+static void vlc_player_UpdateML(vlc_player_t *player,
+ struct vlc_player_input* input)
+{
+ 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;
+ }
+
+ input->prefs.progress = input->position;
+ input->prefs.current_title = input->title_selected;
+ if (input->rate != input->prefs.rate)
+ input->prefs.rate = input->rate;
+ else
+ input->prefs.rate = -1.f;
+
+#define COMPARE_ASSIGN_STR(field, var) \
+ char* field = var_GetNonEmptyString(player, var); \
+ if ( ( field != NULL && input->prefs.field != NULL && strcmp(field, input->prefs.field)) || \
+ ( field == NULL && input->prefs.field != NULL ) || \
+ ( field != NULL && input->prefs.field == NULL ) ) \
+ { \
+ free(input->prefs.field); \
+ input->prefs.field = field; \
+ field = NULL; \
+ } \
+ else \
+ { \
+ free(input->prefs.field); \
+ input->prefs.field = NULL; \
+ }
+
+ COMPARE_ASSIGN_STR(aspect_ratio, "aspect-ratio" );
+ COMPARE_ASSIGN_STR(zoom, "zoom");
+ COMPARE_ASSIGN_STR(crop, "crop");
+ COMPARE_ASSIGN_STR(deinterlace, "deinterlace");
+ COMPARE_ASSIGN_STR(video_filter, "video-filter");
+
+#undef COMPARE_ASSIGN_STR
+
+ int current_video_track = vlc_player_selected_track(&input->video_track_vector);
+ int current_audio_track = vlc_player_selected_track(&input->audio_track_vector);
+ int current_subtitle_track = vlc_player_selected_track(&input->spu_track_vector);
+
+ if (input->prefs.current_video_track != current_video_track)
+ input->prefs.current_video_track = current_video_track;
+ else
+ input->prefs.current_video_track = -1;
+
+ if (input->prefs.current_audio_track != current_audio_track)
+ input->prefs.current_audio_track = current_audio_track;
+ else
+ input->prefs.current_audio_track = -1;
+
+ if (input->prefs.current_subtitle_track != current_subtitle_track)
+ input->prefs.current_subtitle_track = current_subtitle_track;
+ else
+ input->prefs.current_subtitle_track = -1;
+
+ vlc_ml_media_set_all_playback_states(ml, media->i_id, &input->prefs);
+ vlc_ml_release(&input->prefs);
+ vlc_ml_release(media);
+
+ free(video_filter);
+ free(deinterlace);
+ free(crop);
+ free(zoom);
+ free(aspect_ratio);
+}
+
static void *
vlc_player_destructor_Thread(void *data)
{
@@ -916,6 +1047,7 @@ vlc_player_destructor_Thread(void *data)
vlc_player_input_HandleState(input, VLC_PLAYER_STATE_STOPPING);
vlc_player_destructor_AddStoppingInput(player, input);
+ vlc_player_UpdateML(player, input);
input_Stop(input->thread);
}
@@ -1840,6 +1972,28 @@ vlc_player_input_HandleEsEvent(struct vlc_player_input *input,
}
vlc_player_SendEvent(player, on_track_list_changed,
VLC_PLAYER_LIST_ADDED, &trackpriv->t);
+ switch(ev->fmt->i_cat)
+ {
+ case VIDEO_ES:
+ if (input->prefs.current_video_track != -1 &&
+ input->prefs.current_video_track == ev->fmt->i_id)
+ vlc_player_SelectTrack(input->player, &trackpriv->t,
+ VLC_PLAYER_SELECT_EXCLUSIVE);
+ break;
+ case AUDIO_ES:
+ if (input->prefs.current_audio_track != -1 &&
+ input->prefs.current_audio_track == ev->fmt->i_id)
+ vlc_player_SelectTrack(input->player, &trackpriv->t,
+ VLC_PLAYER_SELECT_EXCLUSIVE);
+ break;
+ case SPU_ES:
+ if (input->prefs.current_subtitle_track != -1 &&
+ input->prefs.current_subtitle_track == ev->fmt->i_id)
+ vlc_player_SelectTrack(input->player, &trackpriv->t,
+ VLC_PLAYER_SELECT_EXCLUSIVE);
+ default:
+ break;
+ }
break;
case VLC_INPUT_ES_DELETED:
{
@@ -1907,8 +2061,15 @@ vlc_player_input_HandleTitleEvent(struct vlc_player_input *input,
title_offset, chapter_offset);
vlc_player_SendEvent(player, on_titles_changed, input->titles);
if (input->titles)
+ {
vlc_player_SendEvent(player, on_title_selection_changed,
&input->titles->array[0], 0);
+ if (input->prefs.current_title >= 0 &&
+ (size_t)input->prefs.current_title < ev->list.count)
+ {
+ vlc_player_SelectTitleIdx(player, input->prefs.current_title);
+ }
+ }
break;
}
case VLC_INPUT_TITLE_SELECTED:
@@ -1919,6 +2080,16 @@ vlc_player_input_HandleTitleEvent(struct vlc_player_input *input,
vlc_player_SendEvent(player, on_title_selection_changed,
&input->titles->array[input->title_selected],
input->title_selected);
+ if (input->prefs.current_title >= 0 &&
+ (size_t)input->prefs.current_title == ev->selected_idx &&
+ input->prefs.progress > .0f)
+ {
+ input_SetPosition(input->thread, input->prefs.progress, false);
+ /* Reset the wanted title to avoid forcing it or the position
+ * again during the next title change
+ */
+ input->prefs.current_title = 0;
+ }
break;
default:
vlc_assert_unreachable();
--
2.20.1
More information about the vlc-devel
mailing list