Commit 06a0ca67 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Update video view through a video controller

parent 7125203f
......@@ -79,8 +79,8 @@ app_create(void *data)
goto error;
/* Now that the UI is ready to receive potential updates, start the ML */
if ( !media_library_start( app->p_mediaLibrary, &intf_ml_file_changed, app->p_intf ) )
goto error;
if ( !media_library_start( app->p_mediaLibrary ) )
goto error;
media_library_discover( app->p_mediaLibrary, application_get_media_path( app, MEDIA_DIRECTORY_VIDEOS ) );
media_library_discover( app->p_mediaLibrary, application_get_media_path( app, MEDIA_DIRECTORY_MUSIC ) );
......
......@@ -38,6 +38,7 @@ typedef struct playback_service playback_service;
typedef struct media_storage media_storage;
typedef struct media_item media_item;
typedef struct media_list media_list;
typedef struct video_controller video_controller;
#include "system_storage.h"
......
/*****************************************************************************
* Copyright © 2015 VideoLAN, VideoLabs SAS
*****************************************************************************
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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.
*****************************************************************************/
/*
* By committing to this project, you allow VideoLAN and VideoLabs to relicense
* the code to a different OSI approved license, in case it is required for
* compatibility with the Store
*****************************************************************************/
#include "common.h"
#include "video_controller.h"
#include "application.h"
#include "media/media_library.hpp"
#include "ui/views/video_view.h"
#include "ui/interface.h"
struct video_controller
{
application* p_app;
video_view* p_view;
Eina_List* p_content;
};
/* Called by the Media Library with updated video list
* Guaranteed to be called from the main loop
*/
void
video_controller_content_update_cb(Eina_List* p_content, void* p_data)
{
video_controller* ctrl = (video_controller*)p_data;
ctrl->p_content = p_content;
video_view_update( ctrl->p_view, p_content );
}
/* Queries the media library for the updated video list */
void
video_controller_content_refresh(video_controller* ctrl)
{
// If we already have some content, simply send it to the view
if (ctrl->p_content != NULL)
{
video_view_update( ctrl->p_view, ctrl->p_content );
return;
}
// otherwise, update from media library
const media_library* p_ml = application_get_media_library( ctrl->p_app );
media_library_get_video_files(p_ml, &video_controller_content_update_cb, ctrl);
}
/* Called when media library signals a content change */
void
video_controller_content_changed_cb(void* p_data)
{
video_controller* ctrl = (video_controller*)p_data;
// Discard previous content if any, and ask ML for the
// new content
if (ctrl->p_content != NULL)
{
eina_list_free(ctrl->p_content);
ctrl->p_content = NULL;
}
video_controller_content_refresh(ctrl);
}
video_controller*
video_controller_create( application* p_app, video_view* p_view )
{
video_controller* ctrl = calloc(1, sizeof(*ctrl));
if ( ctrl == NULL )
return NULL;
ctrl->p_app = p_app;
ctrl->p_view = p_view;
/* Populate it */
media_library* p_ml = application_get_media_library(p_app);
media_library_register_on_change(p_ml, video_controller_content_changed_cb, ctrl);
return ctrl;
}
/*****************************************************************************
* Copyright © 2015 VideoLAN, VideoLabs SAS
*****************************************************************************
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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.
*****************************************************************************/
/*
* By committing to this project, you allow VideoLAN and VideoLabs to relicense
* the code to a different OSI approved license, in case it is required for
* compatibility with the Store
*****************************************************************************/
#ifndef VIDEO_CONTROLLER_H_
#define VIDEO_CONTROLLER_H_
#include "application.h"
typedef struct video_view video_view;
video_controller*
video_controller_create( application* p_app, video_view* p_view );
#endif /* VIDEO_CONTROLLER_H_ */
......@@ -70,11 +70,15 @@ public:
virtual void onDiscoveryStarted( const std::string& entryPoint ) override;
virtual void onDiscoveryCompleted( const std::string& entryPoint ) override;
void registerOnChange(media_library_file_list_changed_cb cb, void* cbUserData);
void unregisterOnChange(media_library_file_list_changed_cb cb, void* cbUserData);
public:
std::unique_ptr<IMediaLibrary> ml;
std::unique_ptr<TizenLogger> logger;
media_library_file_list_changed_cb fileListChangedCb;
void* cbUserData;
private:
void onChange();
private:
// Holds the number of discoveries ongoing
......@@ -85,12 +89,11 @@ private:
// This can be accessed from both the discovery & metadata threads
int m_nbElemChanged;
std::mutex m_mutex;
std::vector<std::pair<media_library_file_list_changed_cb, void*>> m_onChangeCb;
};
media_library::media_library()
: ml( MediaLibraryFactory::create() )
, fileListChangedCb( nullptr )
, cbUserData( nullptr )
, m_nbDiscovery( 0 )
, m_nbElemChanged( 0 )
{
......@@ -103,12 +106,11 @@ media_library::onFileAdded( FilePtr file )
{
//FIXME: This seems fishy if no discovery is in progress and some media gets updated.
//This is very unlikely to happen for a while though.
std::unique_lock<std::mutex> lock( m_mutex );
if ( ++m_nbElemChanged >= 50 )
{
LOGI("Enough changes to trigger an update.");
ecore_main_loop_thread_safe_call_async( fileListChangedCb, cbUserData );
onChange();
m_nbElemChanged = 0;
}
}
......@@ -140,12 +142,41 @@ media_library::onDiscoveryCompleted( const std::string& entryPoint )
{
m_nbElemChanged = 0;
LOGI("Changes detected, sending update to listeners");
ecore_main_loop_thread_safe_call_async( fileListChangedCb, cbUserData );
onChange();
}
LOGI( "Completed all active discovery operations" );
}
}
void
media_library::registerOnChange(media_library_file_list_changed_cb cb, void* cbUserData)
{
m_onChangeCb.emplace_back(cb, cbUserData);
}
void
media_library::unregisterOnChange(media_library_file_list_changed_cb cb, void* cbUserData)
{
auto ite = end(m_onChangeCb);
for (auto it = begin(m_onChangeCb); it != ite; ++it)
{
if ((*it).first == cb && (*it).second == cb)
{
m_onChangeCb.erase(it);
return;
}
}
}
void
media_library::onChange()
{
for (auto &p : m_onChangeCb)
{
ecore_main_loop_thread_safe_call_async( p.first, p.second );
}
}
media_library *
media_library_create(application *p_app)
{
......@@ -161,7 +192,7 @@ media_library_create(application *p_app)
}
bool
media_library_start( media_library* p_media_library, media_library_file_list_changed_cb cb, void* p_user_data )
media_library_start( media_library* p_media_library)
{
auto appDataCStr = std::unique_ptr<char, void(*)(void*)>( system_storage_appdata_get(), &free );
std::string appData( appDataCStr.get() );
......@@ -170,8 +201,6 @@ media_library_start( media_library* p_media_library, media_library_file_list_cha
LOGE( "Failed to fetch application data directory" );
return false;
}
p_media_library->fileListChangedCb = cb;
p_media_library->cbUserData = p_user_data;
p_media_library->logger.reset( new TizenLogger );
p_media_library->ml->setLogger( p_media_library->logger.get() );
return p_media_library->ml->initialize( appData + "vlc.db", appData + "/snapshots", p_media_library );
......@@ -291,7 +320,6 @@ media_library_get_video_files( media_library* p_ml, media_library_list_cb cb, vo
ecore_thread_run( [](void* data, Ecore_Thread* ) {
auto ctx = reinterpret_cast<ml_callback_context*>( data );
auto files = ctx->p_ml->ml->videoFiles();
LOGE( "Got %d files", files.size() );
Eina_List *list = nullptr;
for ( auto& f : files )
{
......@@ -304,3 +332,15 @@ media_library_get_video_files( media_library* p_ml, media_library_list_cb cb, vo
ecore_main_loop_thread_safe_call_async( intermediate_list_callback, ctx );
}, nullptr, nullptr, ctx );
}
void
media_library_register_on_change(media_library* ml, media_library_file_list_changed_cb cb, void* p_data)
{
ml->registerOnChange(cb, p_data);
}
void
media_library_unregister_on_change(media_library* ml, media_library_file_list_changed_cb cb, void* p_data)
{
ml->unregisterOnChange(cb, p_data);
}
......@@ -27,20 +27,20 @@
#ifndef MEDIALIBRARY_H_
#define MEDIALIBRARY_H_
#include "application.h"
#include "media_item.h"
#include <Elementary.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include "application.h"
typedef void (*media_library_file_list_changed_cb)( void* p_user_data );
typedef void (*media_library_list_cb)( Eina_List*, void *p_user_data );
media_library* media_library_create(application* p_app);
bool media_library_start( media_library* p_media_library, media_library_file_list_changed_cb cb, void* p_user_data );
bool media_library_start(media_library* p_media_library);
void media_library_delete(media_library* p_media_library);
void media_library_discover( media_library* p_ml, const char* psz_location );
......@@ -50,6 +50,14 @@ media_library_get_video_files( media_library* p_ml, media_library_list_cb cb, vo
void
media_library_get_audio_files( media_library* p_ml, media_library_list_cb cb, void* p_user_data );
void
media_library_register_on_change(media_library* ml, media_library_file_list_changed_cb cb, void* p_data);
void
media_library_unregister_on_change(media_library* ml, media_library_file_list_changed_cb cb, void* p_data);
#ifdef __cplusplus
}
#endif
......
......@@ -63,12 +63,6 @@ struct interface {
mini_player *p_mini_player;
application *p_app;
struct
{
media_library_file_list_changed_cb cb;
void* user_data;
} pp_file_changed_cb[VIEW_MAX];
};
/* TODO : A lot of size hints are Hard Coded with pixel values (using a Samsung Z1 phone) */
......@@ -173,26 +167,6 @@ intf_update_mini_player(interface *intf)
}
}
void
intf_register_file_changed(interface *intf, view_e type,
media_library_file_list_changed_cb cb, void* p_user_data)
{
intf->pp_file_changed_cb[type].cb = cb;
intf->pp_file_changed_cb[type].user_data = p_user_data;
}
void
intf_ml_file_changed( void* p_user_data )
{
LOGI("Updating file listing due to MediaLibrary changes");
interface* intf = (interface*)p_user_data;
for ( int i = 0; i < VIEW_MAX; ++i )
{
if ( intf->pp_file_changed_cb[i].cb != NULL )
intf->pp_file_changed_cb[i].cb( intf->pp_file_changed_cb[i].user_data );
}
}
/* GETTERS */
application *
intf_get_application(interface *p_intf)
......
/*****************************************************************************
* Copyright © 2015 VideoLAN, VideoLabs SAS
*****************************************************************************
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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.
*****************************************************************************/
/*
* By committing to this project, you allow VideoLAN and VideoLabs to relicense
* the code to a different OSI approved license, in case it is required for
* compatibility with the Store
*****************************************************************************/
/*
* video_controller.h
*
* Created on: Oct 1, 2015
* Author: chouquette
*/
#ifndef VIDEO_CONTROLLER_H_
#define VIDEO_CONTROLLER_H_
#endif /* VIDEO_CONTROLLER_H_ */
......@@ -26,6 +26,7 @@
#include "common.h"
#include "controller/video_controller.h"
#include "ui/interface.h"
#include "video_view.h"
#include "video_player.h"
......@@ -33,7 +34,6 @@
#include "ui/utils.h"
#include "media/media_item.h"
#include "media/media_library.hpp"
#include <Elementary.h>
......@@ -43,6 +43,7 @@ typedef struct video_view
Evas_Object *p_parent;
Evas_Object *p_genlist;
video_controller* p_controller;
} video_view;
typedef struct video_list_item
......@@ -189,7 +190,6 @@ genlist_item_create(video_view *videoview, media_item* p_item, Elm_Genlist_Item_
/* Item instantiation */
vli->p_media_item = p_item;
/* Set and append new item in the genlist */
Elm_Object_Item *it = elm_genlist_item_append(videoview->p_genlist,
itc, /* genlist item class */
......@@ -205,9 +205,9 @@ genlist_item_create(video_view *videoview, media_item* p_item, Elm_Genlist_Item_
}
void
generate_video_list(Eina_List* p_list, void* p_data)
video_view_update(video_view* vv, Eina_List* p_content)
{
if ( p_list == NULL )
if ( p_content == NULL )
{
LOGI("Empty video list");
return;
......@@ -219,25 +219,14 @@ generate_video_list(Eina_List* p_list, void* p_data)
itc->func.text_get = genlist_text_get_cb;
itc->func.content_get = genlist_content_get_cb;
video_view* vv = (video_view*)p_data;
Eina_List* it = NULL;
media_item* p_item;
EINA_LIST_FOREACH( p_list, it, p_item )
EINA_LIST_FOREACH( p_content, it, p_item )
{
genlist_item_create(vv, p_item, itc);
}
elm_genlist_item_class_free(itc);
eina_list_free( p_list );
}
static void
video_view_refresh(void* p_user_data)
{
video_view* vv = (video_view*)p_user_data;
application* p_app = intf_get_application( vv->p_intf );
const media_library* p_ml = application_get_media_library( p_app );
media_library_get_video_files( p_ml, &generate_video_list, vv );
}
Evas_Object*
......@@ -246,6 +235,7 @@ create_video_view(interface *intf, Evas_Object *parent)
video_view *vv = malloc(sizeof(*vv));
vv->p_intf = intf;
vv->p_parent = parent;
vv->p_controller = video_controller_create( intf_get_application(intf), vv );
/* Set then create the Genlist object */
Evas_Object *genlist = vv->p_genlist = elm_genlist_add(parent);
......@@ -261,9 +251,6 @@ create_video_view(interface *intf, Evas_Object *parent)
evas_object_smart_callback_add(genlist, "longpressed", genlist_longpressed_cb, NULL);
evas_object_smart_callback_add(genlist, "contracted", genlist_contracted_cb, NULL);
/* Populate it */
intf_register_file_changed( intf, VIEW_VIDEO, video_view_refresh, vv );
/* */
return genlist;
}
......@@ -24,10 +24,17 @@
* compatibility with the Store
*****************************************************************************/
#ifndef FILES_H_
#define FILES_H_
#ifndef VIDEO_VIEW_H_
#define VIDEO_VIEW_H_
#include <Elementary.h>
typedef struct video_view video_view;
Evas_Object*
create_video_view(interface *intf, Evas_Object *parent);
#endif /* FILES_H_ */
void
video_view_update(video_view* vv, Eina_List* p_content);
#endif /* VIDEO_VIEW_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment