\section{Utilisation d'objets proxy}

Nous allons alors utiliser les différentes abstractions mises en place
précédemment pour la communication inter-processus, que ce soit pour le
transfert de données de contrôle pour les RPC ou des données applicatives avec
les blocs mémoires. C'est ici qu'intervient le découpage de l'application en
différents morceaux ainsi que les méthodes synchrones qu'on va utiliser pour
pouvoir les relier sans altérer le fonctionnement actuel. On va donc également
devoir définir quels seront les points d'entrées pour la sandbox, c'est-à-dire
la manière dont la sandbox va pouvoir s'injecter dans le code existant.

Le pattern utilisé ici sera principalement d'avoir un objet proxy pour tous les
objets qui seront utilisé entre processus.

Dans cette partie, nous allons majoritairement prendre en considération le cas
du découpage du décodeur, ainsi que des objets étant directement lié à son
fonctionnement.

% TODO: graphe d'interaction du décodeur

\section{Intégration des objets proxys dans l'architecture}

Le décodeur est dans notre cas créé via l'appel à \inltype{input_DecoderNew}. On
va donc stocker une nouvelle table de fonctions dans la libvlc, dont l'une
\inltype{pf_create_stage} indiquera comment créer un étage donné. On peut alors
surcharger \inltype{input_DecoderNew} poour appeler \inltype{pf_create_stage} et
initialiser cette dernière à des valeurs différentes selon si on démarre en
sandbox ou non. Cela justifie notamment les pointeurs \inltype{create_vlc} et
\inltype{delete_vlc} dans la configuration de lancement de la sandbox.

\begin{code}{c}{Création du décodeur}
decoder_t *input_DecoderNew( input_thread_t *p_input,
                             es_format_t *fmt, input_clock_t *p_clock,
                             sout_instance_t *p_sout  )
{
    return vlc_CreateStage( VLC_OBJECT(p_input), STAGE_DECODER,
                            p_input, fmt, p_clock, p_sout );
}
\end{code}

Le décodeur fonctionne dans son propre thread et subit des interactions
principalement depuis l'objet \inltype{input} via l'API de fonctions commençant
par \inltype{input_Decoder}. On va donc rajouter une table virtuelle dans
l'objet représentant le décodeur pour pouvoir changer de stratégie lors de sa
création.

Ce pattern va être présent pour tous les objets qui sont fonctionnellement liés
au décodeur. En particulier, on a par exemple l'input et le décodeur proxy dans
un processus, puis l'input proxy et le décodeur dans un autre, donnant lieu à la
situation suivante.

\begin{figure}[htbp]
    \centering
    \includesvg[width = 250pt]{schemas/decoder_proxy}
    \caption{Proxy input et décodeur avec le modèle}
\end{figure}

Les paragraphes précédents décrivent la création d'un décodeur depuis le
processus de l'input, mais on voit au graphe précédent qu'il faut également
pouvoir faire un proxy de l'input dans le processus du décodeur, c'est-à-dire
pouvoir \og{}transmettre\fg{} l'input d'un processus à l'autre. Nous allons donc
reprendre le concept de jeton d'accès et permettre l'envoi d'objet proxy à
travers une IPC.\@ Il faut alors détailler ces objets proxies du point de vue de
l'envoi de message.

\begin{code}{c}{Structure privée d'un objet proxy}
struct vlc_rpc_proxy_t
{
    vlc_process_interconn_t *interconn;
    uint32_t id;
    uint32_t stage_id;
    void    *p_this;
    vlc_rpc_proxy_cb call;
};
\end{code}

Chaque objet proxy dispose de cette structure. \inltype{interconn} indique la
méthode de communication pour rejoindre l'autre étage dans un autre processus.
\inltype{stage_id} indique au broker quel processus contacter pour l'envoi.
Enfin, tous les objets proxies disposent d'un identifiant unique au processus,
permettant d'envoyer ou recevoir des RPC.\@ En cas de réception, \inltype{call}
sera appelé.

\begin{code}{c}{Fonction de rappel pour les proxies}
typedef void (*vlc_rpc_proxy_cb)(vlc_rpc_proxy_t *p_proxy,
                                 uint32_t i_query,
                                 vlc_process_msg_t *p_msg);
\end{code}

Comme ces objets seront \og{}transmis\fg{}, il faut alors seulement définir des méthodes
pour créer un \inltype{vlc_rpc_proxy_t} depuis un objet existant, et créer un
objet proxy à partir d'un \inltype{vlc_rpc_proxy_t}.

\section{Avantages et limites}

Commençons par des désavantages liées à cette méthode par rapport à la
précédente. D'abord, bien qu'apportant l'isolation demandée au chapitre
précédent, elle demande bien plus de travail d'intégration. En plus de cela, on
voit avec la relation entre l'input et le décodeur que la méthode est beaucoup
soumise aux défauts ou aux difficultés d'architecture du projet et qu'il devient
nécessaire d'effectuer des réécritures de certaines parties.

Un exemple non présenté ici est celui de la réécriture de
l'\inltype{input_clock} en \inltype{vlc_clock}, pour des raisons différentes
mais apportant plus de flexibilité pour ce modèle.

De plus, beaucoup d'abstraction doit être apportée sous la forme de tables
virtuelles dans les différents objets de VLC.\@ Bien que pouvant apporter de la
flexibilité, cela demande beaucoup de transfor,ation sur la manière de
programmer dans l'application en général.

Enfin, comme expliqué dans le chapitre sur la boucle événementielle, toutes les
opérations, et en particulier les RPC dans des RPC ne sont pas possibles et
limmitent particulièrement la conception de ce modèle.

Néanmoins, ces défauts peuvent être considérés comme des incitations à améliorer
la conception générale de l'application en donnant une ligne directrice très
claire.
