Commit 12535c3e authored by Olivier Aubert's avatar Olivier Aubert
Browse files

CORBA module update:

- the VLC-specific code has been isolated in mediacontrol-core.c so that
  corba.c only has to glue CORBA calls to C calls.
- the IDL has been modified:
  - snapshot support
  - text display support
  - access to stream information
  - access to volume information
parent 00048eb9
/* Cf
http://www.cs.rpi.edu/~musser/dsc/idl/idl-overview.html
pour une intro à la syntaxe */
/*
Module inspired by the MediaControl IDL
*/
module VLC {
enum PositionOrigin {
AbsolutePosition, RelativePosition, ModuloPosition
};
enum PositionKey {
ByteCount, SampleCount, MediaTime
};
struct Position {
PositionOrigin origin;
PositionKey key;
long value;
};
exception PositionKeyNotSupported { PositionKey key;};
exception InvalidPosition { PositionKey key;};
typedef sequence<string> PlaylistSeq;
const float VERSION = 0.1;
enum PositionOrigin {
AbsolutePosition, RelativePosition, ModuloPosition
};
enum PositionKey {
ByteCount, SampleCount, MediaTime
};
struct Position {
PositionOrigin origin;
PositionKey key;
long long value;
};
exception PositionKeyNotSupported { string message; };
exception PositionOriginNotSupported { string message; };
exception InvalidPosition { string message; };
exception PlaylistException { string message; };
exception InternalException { string message; };
typedef sequence<string> PlaylistSeq;
typedef sequence<octet> ByteSeq;
struct RGBPicture {
short width;
short height;
long type;
ByteSeq data;
long long date;
};
typedef sequence<RGBPicture> RGBPictureSeq;
/* Cf stream_control.h */
enum PlayerStatus { PlayingStatus, PauseStatus, ForwardStatus, BackwardStatus, InitStatus, EndStatus, UndefinedStatus };
struct StreamInformation {
PlayerStatus streamstatus;
string url; /* The URL of the current media stream */
long long position; /* actual location in the stream (in ms) */
long long length; /* total length of the stream (in ms) */
};
// MediaControl interface is similar to
// ControlledStream interface in MSS.
// It can be inherited by flow endpoints or
// FlowConnection interfaces.
interface MediaControl
{
exception PositionKeyNotSupported { PositionKey key;};
Position get_media_position(
in PositionOrigin an_origin,
Position get_media_position(in PositionOrigin an_origin,
in PositionKey a_key)
raises (PositionKeyNotSupported);
raises (InternalException, PositionKeyNotSupported);
void set_media_position(in Position a_position)
raises (PositionKeyNotSupported, InvalidPosition);
raises (InternalException, PositionKeyNotSupported, InvalidPosition);
void start(in Position a_position)
raises(InvalidPosition);
raises (InternalException, InvalidPosition, PlaylistException);
void pause(in Position a_position)
raises(InvalidPosition);
raises (InternalException, InvalidPosition);
void resume(in Position a_position)
raises(InvalidPosition);
raises (InternalException, InvalidPosition);
void stop(in Position a_position)
raises(InvalidPosition);
void exit (); // Exits the player (not in the original spec)
void add_to_playlist (in string a_file);
raises (InternalException, InvalidPosition);
oneway void exit (); // Exits the player (not in the original spec)
void playlist_add_item (in string a_file)
raises (PlaylistException);
void playlist_clear ()
raises (PlaylistException);
// Returns the list of files in playlist
PlaylistSeq get_playlist ();
PlaylistSeq playlist_get_list ()
raises (PlaylistException);
// Returns a snapshot of the currently displayed picture
RGBPicture snapshot (in Position a_position)
raises (InternalException);
RGBPictureSeq all_snapshots ()
raises (InternalException);
// Displays the message string, between "begin" and "end" positions
void display_text (in string message, in Position begin, in Position end)
raises (InternalException);
StreamInformation get_stream_information ()
raises (InternalException);
unsigned short sound_get_volume()
raises (InternalException);
void sound_set_volume(in unsigned short volume)
raises (InternalException);
};
};
## corba module declaration
SOURCES_corba = corba.c
SOURCES_corba = corba.c mediacontrol-core.c mediacontrol-plugin.c
EXTRA_DIST = MediaControl.so
nodist_SOURCES_corba = \
mediacontrol-common.c \
mediacontrol-skels.c \
mediacontrol.h \
MediaControl-common.c \
MediaControl-skels.c \
MediaControl.h \
$(NULL)
ORBITIDL = orbit-idl-2
mediacontrol-common.c mediacontrol-skels.c mediacontrol-stubs.c mediacontrol.h:
$(ORBITIDL) --skeleton-impl mediacontrol.idl
GENERATEDFILES=MediaControl-common.c MediaControl-skels.c MediaControl.h MediaControl-imodule.c
corba.c: MediaControl.h MediaControl-common.c
$(GENERATEDFILES): MediaControl.idl
$(ORBITIDL) --skeleton-impl MediaControl.idl
mediacontrol-imodule.c:
$(ORBITIDL) --imodule mediacontrol.idl
MediaControl-imodule.c:
$(ORBITIDL) --imodule MediaControl.idl
mediacontrol.so: mediacontrol-imodule.c
gcc -fPIC -o mediacontrol-imodule.o -c mediacontrol-imodule.c `pkg-config --cflags ORBit-2.0`
gcc -shared -o $@ mediacontrol-imodule.o `pkg-config --libs ORBit-2.0`
MediaControl.so: MediaControl-imodule.c
$(CC) -fPIC -o MediaControl-imodule.o -c MediaControl-imodule.c `pkg-config --cflags ORBit-2.0`
$(CC) -shared -o $@ MediaControl-imodule.o `pkg-config --libs ORBit-2.0`
clean:
rm -f mediacontrol-stubs.c mediacontrol-imodule.c mediacontrol-skelimpl.c
$(RM) -f $(GENERATEDFILES)
$Id: README,v 1.2 2004/01/25 16:17:03 anil Exp $
* Module (server) side
* Corba module (server) side
** Dependencies
To compile the CORBA module, you need the orbit2 developpement files
(for Debian, install the package liborbi2-dev)
To compile the CORBA plugin, you need the orbit2 developpement files
(for Debian, install the package liborbit2-dev)
** How to run it ?
......@@ -13,24 +13,27 @@ vlc --intf corba
The CORBA module is initialized and saves its IOR into the file
/tmp/vlc-ior.ref
(it will soon move to $HOME/.vlc-ior.ref)
** Code architecture
The binding between VLC and the MediaControl API (at C-level) is done
through the mediacontrol-core.c file. This file implements an
object-oriented layer API accessible in C.
The corba.c itself only translates calls from CORBA to this C API,
which makes the code clearer overall. Moreover, the same
mediacontrol-core.c file is used by the vlc-python module to implement the
same API.
* Client side
A sample client application is provided, using python-orbit
A sample client code can be found at http://liris.cnrs.fr/advene/
** Dependencies
The python client uses the pyorbit library developped by James
Henstridge <james at daa dot com dot au> (source:
http://ftp.gnome.org/pub/GNOME/sources/pyorbit/1.99/pyorbit-1.99.3.tar.gz).
To interoperate with gtk, the original pyorbit-1.99.3 needs a patch to
implement the bindings to OR_work_pending and ORB_perform_work (see
pyorbit-1.99.3.patch)
The gtk simpleplayer example uses the python-glade module by James
Henstridge.
Henstridge <james@daa.com.au>
** Typelib information
......@@ -40,12 +43,6 @@ use the structures defined in the IDL (Position, Origin, ...), you
need to use the IDL information, and compile a dynamic lib
(MediaControl.so) from the IDL.
To build the library, you can use the Makefile :
make corba-generate-typelib
which will generate MediaControl.so
* Interesting pointers
- GLib reference manual
......@@ -54,11 +51,3 @@ http://developer.gnome.org/doc/API/glib/
- IDL quickref :
http://www.cs.rpi.edu/~musser/dsc/idl/idl-overview.html
- Python-Bonobo
http://www.pycage.de/howto_bonobo.html
* How to add the module to the original sources (vlc-0.5.x) :
- copy the directory modules/control/corba
- add configuration lines relative to corba in configure.ac.in
- add a reference to control/corba/Modules.am in
modules/Makefile.am
/*****************************************************************************
* corba.c : CORBA (ORBit) remote control module for vlc
* corba.c : CORBA (ORBit) remote control plugin for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: corba.c,v 1.4 2004/01/25 16:17:03 anil Exp $
* $Id$
*
* Authors: Olivier Aubert <oaubert at lisi dot univ-lyon1 dot fr>
* Authors: Olivier Aubert <oaubert@lisi.univ-lyon1.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
......@@ -25,9 +25,33 @@
* Preamble
*****************************************************************************/
/* For CORBA */
#include "mediacontrol.h"
#include "MediaControl.h"
#include "orbit/poa/portableserver-poa-type.h"
#include "mediacontrol-core.h"
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include <vlc/aout.h>
#include <errno.h>
#include <unistd.h>
/* FIXME: replace this to ~/.vlc/vlc-ior.ref thanks to
config_GetHomeDir() */
#ifndef __WIN32__
#define VLC_IOR_FILE "/tmp/vlc-ior.ref"
#else
#define VLC_IOR_FILE "vlc-ior-ref"
#endif
#define MC_TRY exception=mediacontrol_exception_init(exception)
#define MC_EXCEPT(return_value) \
if (exception->code) { \
corba_raise(ev, exception); \
mediacontrol_exception_free(exception); \
return return_value; \
} else { mediacontrol_exception_free(exception); }
#define handle_exception(m) if(ev->_major != CORBA_NO_EXCEPTION) \
{ \
......@@ -35,130 +59,81 @@
return; \
}
#define handle_exception_no_servant(p,m) if(ev->_major != CORBA_NO_EXCEPTION) \
{ \
msg_Err (p, m); \
return; \
}
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include <vlc/aout.h>
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
#include <errno.h> /* ENOMEM */
#include <stdio.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>
/*****************************************************************************
* intf_sys_t: description and status of corba interface
*****************************************************************************/
struct intf_sys_t
{
CORBA_ORB orb;
VLC_MediaControl mc;
PortableServer_POA root_poa;
PortableServer_POAManager root_poa_manager;
GMainLoop* corbaloop;
vlc_bool_t b_playing;
input_thread_t * p_input; /* The input thread */
msg_subscription_t* p_sub; /* message bank subscription */
};
/* Convert an offset into seconds. Taken from input_ext-intf.c.
The 50 hardcoded constant comes from the definition of i_mux_rate :
i_mux_rate : the rate we read the stream (in units of 50 bytes/s) ;
0 if undef */
long long offsetToSeconds (input_thread_t *p_input, off_t l_offset)
{
long long l_res;
l_res = -1;
if (p_input != NULL && p_input->stream.i_mux_rate != 0)
{
l_res = (long long) l_offset / 50 / p_input->stream.i_mux_rate;
}
return l_res;
}
/* Convert an offset into milliseconds */
long long offsetToMilliseconds (input_thread_t *p_input, off_t l_offset)
static void corba_raise(CORBA_Environment *ev, mediacontrol_Exception *exception)
{
long long l_res;
l_res = -1;
if (p_input != NULL && p_input->stream.i_mux_rate != 0)
char *corba_exception=NULL;
char* i_type = NULL;
switch (exception->code)
{
l_res = (long long) 1000 * l_offset / 50 / p_input->stream.i_mux_rate;
case mediacontrol_InternalException:
corba_exception = (char*)VLC_InternalException__alloc ();
i_type = ex_VLC_InternalException;
break;
case mediacontrol_PlaylistException:
corba_exception = (char*)VLC_PlaylistException__alloc ();
i_type = ex_VLC_PlaylistException;
break;
case mediacontrol_InvalidPosition:
corba_exception = (char*)VLC_InvalidPosition__alloc ();
i_type = ex_VLC_InvalidPosition;
break;
case mediacontrol_PositionKeyNotSupported:
corba_exception = (char*)VLC_PositionKeyNotSupported__alloc ();
i_type = ex_VLC_PositionKeyNotSupported;
break;
case mediacontrol_PositionOriginNotSupported:
corba_exception = (char*)VLC_PositionOriginNotSupported__alloc ();
i_type = ex_VLC_PositionOriginNotSupported;
break;
}
return l_res;
((VLC_InternalException*)corba_exception)->message = CORBA_string_dup(exception->message);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION, i_type, corba_exception);
return;
}
/* Convert seconds to an offset */
off_t secondsToOffset (input_thread_t *p_input, long long l_seconds)
static mediacontrol_Position* corba_position_corba_to_c (const VLC_Position* position)
{
off_t l_res;
l_res = -1;
if (p_input != NULL)
{
l_res = (off_t) l_seconds * 50 * p_input->stream.i_mux_rate;
}
return l_res;
mediacontrol_Position* retval;
retval = (mediacontrol_Position*)malloc(sizeof(mediacontrol_Position));
if (! retval)
return NULL;
retval->origin = position->origin;
retval->key = position->key;
retval->value = position->value;
return retval;
}
/* Convert milliseconds to an offset */
off_t millisecondsToOffset (input_thread_t *p_input, long long l_milliseconds)
static VLC_Position* corba_position_c_to_corba(const mediacontrol_Position* position)
{
off_t l_res;
l_res = -1;
if (p_input != NULL)
{
l_res = (off_t) l_milliseconds * 50 * p_input->stream.i_mux_rate / 1000;
}
return l_res;
VLC_Position* retval;
retval = (VLC_Position*)malloc(sizeof(VLC_Position));
if (! retval)
return NULL;
retval->origin = position->origin;
retval->key = position->key;
retval->value = position->value;
return retval;
}
/* Returns the current offset. */
off_t currentOffset (input_thread_t *p_input)
/*****************************************************************************
* intf_sys_t: description and status of corba interface
*****************************************************************************/
struct intf_sys_t
{
off_t l_offset;
if( p_input == NULL )
{
return -1;
}
/* offset contient la valeur en units arbitraires (cf
include/input_ext-intf.h) */
vlc_mutex_lock( &p_input->stream.stream_lock );
#define A p_input->stream.p_selected_area
l_offset = A->i_tell + A->i_start;
#undef A
vlc_mutex_unlock( &p_input->stream.stream_lock );
return l_offset;
}
CORBA_ORB orb;
GMainLoop* corbaloop;
mediacontrol_Instance *mc;
msg_subscription_t* p_sub; /* message bank subscription */
};
/*** App-specific servant structures ***/
......@@ -171,71 +146,104 @@ typedef struct
POA_VLC_MediaControl servant;
PortableServer_POA poa;
/* Ajouter ici les attributs utiles */
intf_thread_t *p_intf;
}
impl_POA_VLC_MediaControl;
mediacontrol_Instance *mc;
intf_thread_t *p_intf;
} impl_POA_VLC_MediaControl;
/* Beginning of the CORBA code generated in Mediacontrol-skelimpl.c */
/* BEGIN INSERT */
/*** Implementation stub prototypes ***/
static void impl_VLC_MediaControl__destroy(impl_POA_VLC_MediaControl *
servant, CORBA_Environment * ev);
servant, CORBA_Environment * ev);
static VLC_Position
impl_VLC_MediaControl_get_media_position(impl_POA_VLC_MediaControl * servant,
const VLC_PositionOrigin an_origin,
const VLC_PositionKey a_key,
CORBA_Environment * ev);
const VLC_PositionOrigin an_origin,
const VLC_PositionKey a_key,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_set_media_position(impl_POA_VLC_MediaControl * servant,
const VLC_Position * a_position,
CORBA_Environment * ev);
const VLC_Position * a_position,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_start(impl_POA_VLC_MediaControl * servant,
const VLC_Position * a_position,
CORBA_Environment * ev);
const VLC_Position * a_position,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_pause(impl_POA_VLC_MediaControl * servant,
const VLC_Position * a_position,
CORBA_Environment * ev);
const VLC_Position * a_position,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_resume(impl_POA_VLC_MediaControl * servant,
const VLC_Position * a_position,
CORBA_Environment * ev);
const VLC_Position * a_position,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_stop(impl_POA_VLC_MediaControl * servant,
const VLC_Position * a_position,
CORBA_Environment * ev);
const VLC_Position * a_position,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_exit(impl_POA_VLC_MediaControl * servant,
CORBA_Environment * ev);
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_playlist_add_item(impl_POA_VLC_MediaControl * servant,
const CORBA_char * a_file,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_add_to_playlist(impl_POA_VLC_MediaControl * servant,
const CORBA_char * a_file,
CORBA_Environment * ev);
impl_VLC_MediaControl_playlist_clear(impl_POA_VLC_MediaControl * servant,
CORBA_Environment * ev);
static VLC_PlaylistSeq
*impl_VLC_MediaControl_get_playlist(impl_POA_VLC_MediaControl * servant,
CORBA_Environment * ev);
*impl_VLC_MediaControl_playlist_get_list(impl_POA_VLC_MediaControl *
servant, CORBA_Environment * ev);
static VLC_RGBPicture
*impl_VLC_MediaControl_snapshot(impl_POA_VLC_MediaControl * servant,
const VLC_Position * a_position,
CORBA_Environment * ev);
static VLC_RGBPictureSeq
*impl_VLC_MediaControl_all_snapshots(impl_POA_VLC_MediaControl * servant,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_display_text(impl_POA_VLC_MediaControl * servant,
const CORBA_char * message,
const VLC_Position * begin,
const VLC_Position * end,
CORBA_Environment * ev);
static VLC_StreamInformation
*impl_VLC_MediaControl_get_stream_information(impl_POA_VLC_MediaControl *
servant,
CORBA_Environment * ev);
static CORBA_unsigned_short
impl_VLC_MediaControl_sound_get_volume(impl_POA_VLC_MediaControl * servant,
CORBA_Environment * ev);
static void
impl_VLC_MediaControl_sound_set_volume(impl_POA_VLC_MediaControl * servant,
const CORBA_unsigned_short volume,
CORBA_Environment * ev);
/*** epv structures ***/