You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
862 lines
27 KiB
862 lines
27 KiB
15 years ago
|
Valerie API Documentation
|
||
|
|
||
|
Copyright (C) 2004 Ushodaya Enterprised Limited
|
||
|
Author: Charles Yates <charles.yates@pandora.be>
|
||
|
Last Revision: 2004-03-20
|
||
|
|
||
|
|
||
|
TABLE OF CONTENTS
|
||
|
-----------------
|
||
|
|
||
|
0. Overview
|
||
|
0.1. Intended Audience
|
||
|
0.2. Terminology
|
||
|
1. Definition of a Parser
|
||
|
1.1. Construction of a Local Parser
|
||
|
1.2. Construction of a Remote Parser
|
||
|
1.3. Using the Parser
|
||
|
1.4. Closing the Parser
|
||
|
2. The High Level Parser Wrapper
|
||
|
2.1. Connecting
|
||
|
2.2. valerie_error_code
|
||
|
2.3. Using the High Level Wrapper
|
||
|
2.4. Obtaining Directory Contents
|
||
|
2.5. Obtaining the Node List
|
||
|
2.6. Obtaining the Unit List
|
||
|
2.7. Unit Status Information
|
||
|
2.8. Server Side Queuing APIs
|
||
|
2.9. Accessing the Low Level Parser Directly
|
||
|
2.10. Cleaning up
|
||
|
2.11. Examples
|
||
|
3. The Low Level Parser API
|
||
|
3.1. Executing a Command
|
||
|
3.2. Interpreting valerie_response
|
||
|
3.3. Accessing Unit Status
|
||
|
APPENDIX A - COMPILATION AND LINKING
|
||
|
APPENDIX B - COMPLETE HIGH LEVEL PARSER WRAPPER API LISTING
|
||
|
APPENDIX C - COMPLETE LOW LEVEL PARSER API LISTING
|
||
|
APPENDIX D - REFERENCES
|
||
|
|
||
|
|
||
|
0. Overview
|
||
|
-----------
|
||
|
|
||
|
This document details how applications interface to DVCP functionality.
|
||
|
|
||
|
|
||
|
0.1. Intended Audience
|
||
|
----------------------
|
||
|
|
||
|
This document draws heavily upon the DVCP design (1) and assumes a basic
|
||
|
knowledge of the functionality provided by the DVCP core.
|
||
|
|
||
|
It is aimed at developers who wish to use or maintain the API.
|
||
|
|
||
|
|
||
|
0.2. Terminology
|
||
|
----------------
|
||
|
|
||
|
The API is designed to allow client applications the ability to communicate
|
||
|
to a standalone miracle server or entirely embed the DVCP core in an
|
||
|
instance of a client application.
|
||
|
|
||
|
The distinction between the two is defined by the construction of the
|
||
|
'parser'.
|
||
|
|
||
|
This 'parser' can be used to issue DVCP commands and receive responses and
|
||
|
a 'high level parser wrapper' is provided to simplify the usage and
|
||
|
decouple the application from the DVCP command set.
|
||
|
|
||
|
|
||
|
1. Definition of a Parser
|
||
|
-------------------------
|
||
|
|
||
|
The parser provides a low level API which allows text DVCP commands to be
|
||
|
executed with responses being returned to the caller. Commands and
|
||
|
responses are ASCII formatted text.
|
||
|
|
||
|
Two parsers are provided - local and remote.
|
||
|
|
||
|
The local parser is the physical implementation which takes commands and
|
||
|
executes them.
|
||
|
|
||
|
The remote parser is a network abstraction that forwards commands to a
|
||
|
miracle instance that hosts a local parser.
|
||
|
|
||
|
|
||
|
1.1. Construction of a Local Parser
|
||
|
-----------------------------------
|
||
|
|
||
|
To construct a local parser you must have:
|
||
|
|
||
|
#include <miracle/miracle_local.h>
|
||
|
|
||
|
and code to initialise the parser is as follows:
|
||
|
|
||
|
valerie_parser parser = miracle_parser_init_local( );
|
||
|
|
||
|
See Appendix A for compilation and linking details.
|
||
|
|
||
|
|
||
|
1.2. Construction of a Remote Parser
|
||
|
------------------------------------
|
||
|
|
||
|
To construct a remote parser you must have:
|
||
|
|
||
|
#include <valerie/valerie_remote.h>
|
||
|
|
||
|
and code to initialise the parser is as follows:
|
||
|
|
||
|
valerie_parser parser = valerie_parser_init_remote( "server", port );
|
||
|
|
||
|
See Appendix A for compilation and linking details.
|
||
|
|
||
|
|
||
|
1.3. Using the Parser
|
||
|
---------------------
|
||
|
|
||
|
Although the parser can be used directly to send commands and receive
|
||
|
responses, this low level usage puts the onus on the developer to parse the
|
||
|
responses in a meaningful way.
|
||
|
|
||
|
Although this usage is not strictly forbidden by applications, it is
|
||
|
discouraged as construction of commands and meaningful parsing of responses
|
||
|
leads to the clients being unnecessarily dependent on the servers input and
|
||
|
output.
|
||
|
|
||
|
As a result, a higher level Parser Wrapper API is provided - this API
|
||
|
encapsulates the command construction and response parsing.
|
||
|
|
||
|
The following 2 sections provide details on these modes of access.
|
||
|
|
||
|
|
||
|
1.4. Closing the Parser
|
||
|
-----------------------
|
||
|
|
||
|
Regardless of use, it is the constructors responsibility to close the
|
||
|
parser before it goes out of scope. This is done via:
|
||
|
|
||
|
valerie_parser_close( parser );
|
||
|
|
||
|
|
||
|
2. The High Level Parser Wrapper
|
||
|
--------------------------------
|
||
|
|
||
|
The recommended way to access the parser, is via the valerie API. To use
|
||
|
this API, you must have:
|
||
|
|
||
|
#include <valerie/valerie.h>
|
||
|
|
||
|
and code to construct the wrapper is:
|
||
|
|
||
|
valerie dv = valerie_init( parser );
|
||
|
|
||
|
Note that either remote or local parsers can be used here and there is no
|
||
|
difference in usage, though some error returns will not be applicable to
|
||
|
both.
|
||
|
|
||
|
It is recommended that applications honour and deal with the error returns
|
||
|
of both as this allows applications to interchange parsers.
|
||
|
|
||
|
Also note that valerie is not threadsafe, so you should not use the same
|
||
|
structure in multiple threads. The correct solution to this is to create a
|
||
|
valerie per thread - you may safely use the same parser for each thread ie:
|
||
|
|
||
|
/* valerie for the application */
|
||
|
valerie dv = valerie_init( parser );
|
||
|
/* valerie for the status handling thread. */
|
||
|
valerie dv_status = valerie_init( parser );
|
||
|
|
||
|
For the purposes of simplification, the remainder of this section assumes
|
||
|
that a remote parser is in use.
|
||
|
|
||
|
|
||
|
2.1. Connecting
|
||
|
---------------
|
||
|
|
||
|
Once constructed, the next thing to do is 'connect':
|
||
|
|
||
|
valerie_error_code error = valerie_connect( dv );
|
||
|
|
||
|
This function call initialises the parser (ie: if it's remote, it
|
||
|
establishes a connection to the server, or if it's local, it initialises
|
||
|
the state of the units and supporting objects).
|
||
|
|
||
|
Note that if you have multiple valerie instances on the same parser you
|
||
|
should only connect one of the instances.
|
||
|
|
||
|
|
||
|
2.2. valerie_error_code
|
||
|
----------------------
|
||
|
|
||
|
All but a couple of the functions that make up the valerie API return a
|
||
|
valerie_error_code.
|
||
|
|
||
|
These are defined as follows:
|
||
|
|
||
|
valerie_ok = 0,
|
||
|
valerie_malloc_failed,
|
||
|
valerie_unknown_error,
|
||
|
valerie_no_response,
|
||
|
valerie_invalid_command,
|
||
|
valerie_server_timeout,
|
||
|
valerie_missing_argument,
|
||
|
valerie_server_unavailable,
|
||
|
valerie_unit_creation_failed,
|
||
|
valerie_unit_unavailable,
|
||
|
valerie_invalid_file,
|
||
|
valerie_invalid_position
|
||
|
|
||
|
In most cases, it is sufficient to check on a return of valerie_ok.
|
||
|
|
||
|
To obtain a textual description of a particular error, you can use:
|
||
|
|
||
|
char *valerie_error_description( valerie_error_code );
|
||
|
|
||
|
|
||
|
2.3. Using the High Level Wrapper
|
||
|
---------------------------------
|
||
|
|
||
|
The following code snippet assumes that dv is an initialised and connected
|
||
|
valerie structure:
|
||
|
|
||
|
valerie_error_code error = valerie_unit_play( dv, 0 );
|
||
|
if ( error == valerie_ok )
|
||
|
fprintf( stderr, "Unit 0 is now playing\n" );
|
||
|
else
|
||
|
fprintf( stderr, "Play on unit 0 failed: %s\n",
|
||
|
valerie_error_description( error ) );
|
||
|
|
||
|
The complete interface to valerie is listed in Appendix B of this document.
|
||
|
|
||
|
|
||
|
2.4. Obtaining Directory Contents
|
||
|
--------------------------------
|
||
|
|
||
|
To obtain a list of files and subdirectories in a given directory relative
|
||
|
to the ROOT property of the server, DVCP provides the CLS command.
|
||
|
|
||
|
A valid execution of CLS would be something like:
|
||
|
|
||
|
CLS "/Stuff"
|
||
|
|
||
|
would provide a response formatted as follows:
|
||
|
|
||
|
201 OK
|
||
|
"More Stuff/"
|
||
|
"file0001.dv" 15552000
|
||
|
"file0002.dv" 15552000
|
||
|
|
||
|
with a trailing empty line.
|
||
|
|
||
|
The first line indicates the error value, the second line shows an example
|
||
|
of a subdirectory and the 3rd and 4th line lists two files that happen to
|
||
|
exist in the directory.
|
||
|
|
||
|
valerie provides a high level view on this which automatically parses the
|
||
|
response from the server correctly via the valerie_dir structures and
|
||
|
related functions.
|
||
|
|
||
|
An example of use is as follows:
|
||
|
|
||
|
valerie_dir dir = valerie_dir_init( dv, "/Stuff" );
|
||
|
valerie_error_code error = valerie_dir_get_error_code( dir );
|
||
|
if ( error == valerie_ok )
|
||
|
{
|
||
|
if ( valerie_dir_count( dir ) > 0 )
|
||
|
{
|
||
|
valerie_dir_entry_t entry;
|
||
|
int index = 0;
|
||
|
for ( index = 0; index < valerie_dir_count( dir ); index ++ )
|
||
|
{
|
||
|
valerie_dir_get( dir, index, &entry );
|
||
|
if ( entry.dir )
|
||
|
printf( "<%s>\n", entry.name );
|
||
|
else
|
||
|
printf( "%30s %8d", entry.name, entry.size );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf( stderr, "Directory is empty\n" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf( stderr, "Directory listing failed: %s\n",
|
||
|
valerie_error_description( error ) );
|
||
|
}
|
||
|
valerie_dir_close( dir );
|
||
|
|
||
|
Note that entry.name provides the name of the file or directory without the
|
||
|
directory prefix. As a convenience, entry.full provides the prefixed name,
|
||
|
so you could subsequently use:
|
||
|
|
||
|
error = valerie_unit_load( dv, 0, entry.full );
|
||
|
|
||
|
to load unit 0 with an entry.
|
||
|
|
||
|
|
||
|
2.5. Obtaining the Node List
|
||
|
----------------------------
|
||
|
|
||
|
Currently not defined by miracle.
|
||
|
|
||
|
2.6. Obtaining the Unit List
|
||
|
----------------------------
|
||
|
|
||
|
To obtain a list of defined units, DVCP provides the ULS command.
|
||
|
|
||
|
A valid execution of ULS would be:
|
||
|
|
||
|
ULS
|
||
|
|
||
|
and would provide a response formatted as follows:
|
||
|
|
||
|
201 OK
|
||
|
U0 00 sdl:360x288 1
|
||
|
|
||
|
with a trailing empty line.
|
||
|
|
||
|
The fields of each record in the response dictate unit, node, mlt consumer and
|
||
|
online status respectively.
|
||
|
|
||
|
valerie provides a high level view on this which automatically parses the
|
||
|
response from the server correctly via the valerie_units structures and
|
||
|
related functions.
|
||
|
|
||
|
An example of use is as follows:
|
||
|
|
||
|
valerie_units units = valerie_units_init( dv );
|
||
|
valerie_error_code error = valerie_units_get_error_code( units );
|
||
|
if ( error == valerie_ok )
|
||
|
{
|
||
|
if ( valerie_units_count( units ) > 0 )
|
||
|
{
|
||
|
valerie_unit_entry_t entry;
|
||
|
int index = 0;
|
||
|
for ( index = 0; index < valerie_units_count( units ); index ++ )
|
||
|
{
|
||
|
valerie_units_get( units, index, &entry );
|
||
|
printf( "U%d %02d %s %s\n",
|
||
|
entry.unit,
|
||
|
entry.node,
|
||
|
entry.guid,
|
||
|
entry.online ? "online" : "offline" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf( stderr, "Unit list is empty\n" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf( stderr, "Unit listing failed: %s\n",
|
||
|
valerie_error_description( error ) );
|
||
|
}
|
||
|
valerie_units_close( units );
|
||
|
|
||
|
|
||
|
2.7. Unit Status Information
|
||
|
----------------------------
|
||
|
|
||
|
There are two methods for a client to obtain unit status information.
|
||
|
|
||
|
The first is via the DVCP USTA command, which would normally be accessed
|
||
|
via:
|
||
|
|
||
|
USTA U0
|
||
|
|
||
|
and would provide a response formated as follows:
|
||
|
|
||
|
202 OK
|
||
|
0 playing "a.dv" 58 1000 25.00 0 6999 7000 "a.dv" 157 0 6999 7000 1 4 0
|
||
|
|
||
|
with no trailing empty line.
|
||
|
|
||
|
The entries in the record are:
|
||
|
|
||
|
* Unit
|
||
|
* State (undefined, offline, not_loaded, stopped, playing,
|
||
|
paused, disconnected [when server dies])
|
||
|
* Name of Clip
|
||
|
* Position in clip
|
||
|
* Speed * 1000
|
||
|
* Frames per second
|
||
|
* Start of clip (in point)
|
||
|
* End of clip (out point)
|
||
|
* Length of clip
|
||
|
* Read ahead clip
|
||
|
* Read ahead position
|
||
|
* Read ahead clip in
|
||
|
* Read ahead clip out
|
||
|
* Read ahead clip length
|
||
|
* Seekable flag
|
||
|
* Playlist generation
|
||
|
* Clip index
|
||
|
|
||
|
Again, valerie provides a high level means for obtaining this via the
|
||
|
valerie_unit_status function and valerie_status structures:
|
||
|
|
||
|
valerie_status_t status;
|
||
|
valerie_error_code error = valerie_unit_status( dv, 0, &status );
|
||
|
if ( error == valerie_ok )
|
||
|
{
|
||
|
switch( status.status )
|
||
|
{
|
||
|
case unit_offline:
|
||
|
printf( "offline " );
|
||
|
break;
|
||
|
case unit_undefined:
|
||
|
printf( "undefined " );
|
||
|
break;
|
||
|
case unit_not_loaded:
|
||
|
printf( "unloaded " );
|
||
|
break;
|
||
|
case unit_stopped:
|
||
|
printf( "stopped " );
|
||
|
break;
|
||
|
case unit_playing:
|
||
|
printf( "playing " );
|
||
|
break;
|
||
|
default:
|
||
|
printf( "unknown " );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
printf( "%06lld %06lld %06lld %s\n", status.in,
|
||
|
status.position,
|
||
|
status.out,
|
||
|
status.clip );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf( stderr, "Unit status failed: %s\n",
|
||
|
valerie_error_description( error ) );
|
||
|
}
|
||
|
|
||
|
The second approach for obtaining a units status is via automatic
|
||
|
notification.
|
||
|
|
||
|
This is done via the valerie_notifier API. To obtain the notifier from the
|
||
|
high level API, you can use:
|
||
|
|
||
|
valerie_notifier notifier = valerie_get_notifier( dv );
|
||
|
|
||
|
To obtain the last status associated to a unit, you can use:
|
||
|
|
||
|
int unit = 1;
|
||
|
valerie_status_t status;
|
||
|
valerie_notifier_get( notifier, &status, unit );
|
||
|
|
||
|
To wait for the next status from any unit, you can use:
|
||
|
|
||
|
valerie_notifier_wait( notifier, &status );
|
||
|
|
||
|
If you wish to trigger the action associated to your applications wait
|
||
|
handling of a particular unit, you can use:
|
||
|
|
||
|
valerie_notifier_get( notifier, &status, unit );
|
||
|
valerie_notifier_put( notifier, &status );
|
||
|
|
||
|
See Examples below for details on this.
|
||
|
|
||
|
The complete list of fields in the status structure are:
|
||
|
|
||
|
int unit;
|
||
|
unit_status status;
|
||
|
char clip[ 2048 ];
|
||
|
int64_t position;
|
||
|
int speed;
|
||
|
double fps;
|
||
|
int64_t in;
|
||
|
int64_t out;
|
||
|
int64_t length;
|
||
|
char tail_clip[ 2048 ];
|
||
|
int64_t tail_position;
|
||
|
int64_t tail_in;
|
||
|
int64_t tail_out;
|
||
|
int64_t tail_length;
|
||
|
int seekable;
|
||
|
int generation;
|
||
|
int clip_index;
|
||
|
|
||
|
You will always receive a status record for every frame output.
|
||
|
|
||
|
The read ahead information is provided for client side queuing. Client side
|
||
|
queuing assumes that uset eof=pause is applied to the unit. A client can
|
||
|
detect when the previously scheduled clip is played out by using the read
|
||
|
ahead information and schedule the next clip. While this mode of operation
|
||
|
is still supported, it is recommended that new clients use the server side
|
||
|
queuing mechanism which is described in the following section.
|
||
|
|
||
|
|
||
|
2.8. Server Side Queueing APIs
|
||
|
------------------------------
|
||
|
|
||
|
This section describes the APIs available to provide server side queueing.
|
||
|
|
||
|
The concept is that each unit maintains its own playlist, containing multiple
|
||
|
clips. Associated to the playlist is a generation number which is incremented
|
||
|
on each modification to the playlist. The current playlist generation is
|
||
|
provided in the status record in order for a client to know when to refresh
|
||
|
its presentation of the list. The status record also indicates which clip is
|
||
|
currently active.
|
||
|
|
||
|
Actions that can be carried out on the playlist are summarised as:
|
||
|
|
||
|
* list - list all the clips and associated in/out points and size
|
||
|
* loading a clip - a load will wipe the current list and replace it with the
|
||
|
specified clip
|
||
|
* appending a clip - append will always place the specified clip at the end
|
||
|
of the playlist
|
||
|
* inserting a clip - insert will place a new clip at the specified position
|
||
|
in the playlist
|
||
|
* moving a clip - move will allow clips can be moved in the playlist
|
||
|
* removing a clip - remove will remove the specified clip from the playlist
|
||
|
* clean - clean will remove all but the playing clip from the playlist
|
||
|
|
||
|
Additionally, the following existing actions are clip aware:
|
||
|
|
||
|
* goto allows you to move the current play position to a specific clip position
|
||
|
* set in/out points allows you to modify clip in and out points
|
||
|
|
||
|
Backward compatability has been maintained by the addition of a clip-aware
|
||
|
family of APIs which have the naming convention of valerie_unit_clip_*.
|
||
|
|
||
|
These are listed in Appendix B.
|
||
|
|
||
|
The following shows an example of obtaining the clips queued on unit 0:
|
||
|
|
||
|
valerie_list list = valerie_list_init( dv, 0 );
|
||
|
valerie_list_entry_t entry;
|
||
|
int index;
|
||
|
|
||
|
printf( "Generation = %d\n", list->generation );
|
||
|
for ( index = 0; index < valerie_list_count( list ); index ++ )
|
||
|
{
|
||
|
valerie_list_get( list, index, &entry );
|
||
|
printf( "%d %s %d %d %d %d\n",
|
||
|
entry.clip,
|
||
|
entry.full,
|
||
|
entry.in,
|
||
|
entry.out,
|
||
|
entry.max,
|
||
|
entry.size );
|
||
|
}
|
||
|
valerie_list_close( list );
|
||
|
|
||
|
To load a clip on unit 0:
|
||
|
|
||
|
valerie_unit_load( dv, 0, "/path/clip.dv" );
|
||
|
|
||
|
To append a clip on unit 0:
|
||
|
|
||
|
valerie_unit_append( dv, 0, "/path/clip.dv", -1, -1 );
|
||
|
|
||
|
Note that the last two arguments specify the in and out points of the clip
|
||
|
with -1 denoting dfaults of the entirety of the file.
|
||
|
|
||
|
To insert a clip at position 0 on unit 0, we can use the following:
|
||
|
|
||
|
valerie_unit_clip_insert( dv, 0, clip_absolute, 0, "/path/clip.dv", -1, -1 );
|
||
|
|
||
|
The 3rd and 4th arguments here are common to all the valerie_unit_clip functions.
|
||
|
They take the form of either [clip_absolute, n] to indicate an absolute clip
|
||
|
index, or [clip_relative, n] to indicate a clip index relative to the
|
||
|
currently playing clip.
|
||
|
|
||
|
So, to insert a clip immediately before the currently playing clip, we can
|
||
|
use:
|
||
|
|
||
|
valerie_unit_clip_insert( dv, 0, clip_relative, -1, "/path/clip.dv", -1, -1 );
|
||
|
|
||
|
To move the current clip to the next position in the list:
|
||
|
|
||
|
valerie_unit_clip_move( dv, 0, clip_relative, 0, clip_relative, 1 );
|
||
|
|
||
|
To remove a specific clip:
|
||
|
|
||
|
valerie_unit_clip_remove( dv, 0, clip_absolute, index );
|
||
|
|
||
|
To remove all but the currently playing clip:
|
||
|
|
||
|
valerie_unit_clean( dv, 0 );
|
||
|
|
||
|
To goto the first frame in the first clip, you can use:
|
||
|
|
||
|
valerie_unit_clip_goto( dv, 0, clip_absolute, 0, 0 );
|
||
|
|
||
|
To set the in and out points on the current clip:
|
||
|
|
||
|
valerie_unit_clip_set_in( dv, 0, clip_relative, 0, 0 );
|
||
|
valerie_unit_clip_set_out( dv, 0, clip_relative, 0, 1000 );
|
||
|
|
||
|
A more complete example of use of the server side can queuing can be found
|
||
|
at:
|
||
|
|
||
|
http://users.pandora.be/acp/rugen
|
||
|
|
||
|
The demo client provided with valerie is used for retaining backward
|
||
|
compatability with the client side queuing API.
|
||
|
|
||
|
|
||
|
2.9. Accessing the Low Level Parser Directly
|
||
|
--------------------------------------------
|
||
|
|
||
|
The low level parser and its associated structures can be accessed directly
|
||
|
from the high level API, but is very occasionally actually needed.
|
||
|
|
||
|
The methods are provided via a pair of high level methods:
|
||
|
|
||
|
valerie_error_code error = valerie_execute( dv, 1024, "USTA U%d", unit );
|
||
|
valerie_response response = valerie_get_last_response( dv );
|
||
|
int index = 0;
|
||
|
for ( index = 0; index < valerie_response_count( response ); index ++ )
|
||
|
printf( "%d: %s\n", index, valerie_response_get_line( response,index ) );
|
||
|
|
||
|
More details on the valerie_response structure can be found in section 3 of this
|
||
|
document.
|
||
|
|
||
|
|
||
|
2.10. Cleaning up
|
||
|
-----------------
|
||
|
|
||
|
Before the valerie and parser go out of scope, you need to run:
|
||
|
|
||
|
valerie_close( dv );
|
||
|
valerie_parser_close( parser );
|
||
|
|
||
|
Note that you should close all valerie instances before closing the parser.
|
||
|
|
||
|
|
||
|
2.11. Examples
|
||
|
--------------
|
||
|
|
||
|
Please refer to albino and humperdink source for examples provided with
|
||
|
the project. Additional examples can be found via google with gdv1394 and
|
||
|
poldo.
|
||
|
|
||
|
|
||
|
3. The Low Level Parser API
|
||
|
---------------------------
|
||
|
|
||
|
The low level parser API provides a very simple mechanism for constructing
|
||
|
commands and receiving responses.
|
||
|
|
||
|
As described in section 2, a parser is constructed as local or remote and
|
||
|
this is sufficient for constructing the low level parser.
|
||
|
|
||
|
|
||
|
3.1. Executing a Command
|
||
|
------------------------
|
||
|
|
||
|
All commands can be executed via the single variable argument function
|
||
|
valerie_parser_executef and this function returns a valerie_response, ie:
|
||
|
|
||
|
valerie_response response = valerie_parser_executef( parser, "CLS \"%s\"", dir );
|
||
|
|
||
|
Note that no carriage return/line feed is required (adding this is
|
||
|
erroneous).
|
||
|
|
||
|
It is the receiver of the response who is responsible for closing it.
|
||
|
|
||
|
valerie_response_close( response );
|
||
|
|
||
|
|
||
|
3.2. Interpreting valerie_response
|
||
|
-----------------------------
|
||
|
|
||
|
The response received can be NULL, but it is safe to call:
|
||
|
|
||
|
int error = valerie_response_get_error_code( response );
|
||
|
|
||
|
which will return:
|
||
|
|
||
|
* -1 if response is NULL,
|
||
|
* -2 if there is no content to the response,
|
||
|
* 0 if the responses first line does not correspond to a valid DVCP response
|
||
|
* or the DVCP protocol error code returned on the first line of the response
|
||
|
|
||
|
A simple use of a valerie_response structure is as follows:
|
||
|
|
||
|
valerie_response response = valerie_parser_executef( parser, "CLS \"%s\"", dir );
|
||
|
int error = valerie_response_get_error_code( response );
|
||
|
if ( error >= 0 )
|
||
|
{
|
||
|
int index = 0;
|
||
|
for ( index = 0; index < valerie_response_count( response ); index ++ )
|
||
|
printf( "%3d: %s\n", index, valerie_response_get_line( response, index ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* interpret error */
|
||
|
}
|
||
|
valerie_response_close( response );
|
||
|
|
||
|
Note that it is safe to call valerie_response_close regardless of the error
|
||
|
condition indicated.
|
||
|
|
||
|
|
||
|
3.3. Accessing Unit Status
|
||
|
--------------------------
|
||
|
|
||
|
As with the high level parser, there are two alternatives to obtain unit
|
||
|
status information - either via the USTA DVCP command or via the
|
||
|
valerie1394_notifier.
|
||
|
|
||
|
The latter is the recommended way for any applications which wish to extract
|
||
|
meaningful information from the status while avoiding the requirement to
|
||
|
duplicate the parsing process in a specific client.
|
||
|
|
||
|
The notifier can be obtained by:
|
||
|
|
||
|
valerie_notifier notifier = valerie_parser_get_notifier( parser );
|
||
|
|
||
|
The use of the notifier with the low level parser is identical to that
|
||
|
dictated in Section 2 - to obtain the last status associated to a unit,
|
||
|
you can use:
|
||
|
|
||
|
int unit = 1;
|
||
|
valerie_status_t status;
|
||
|
valerie_notifier_get( notifier, &status, unit );
|
||
|
|
||
|
To wait for the next status from any unit, you can use:
|
||
|
|
||
|
valerie_notifier_wait( notifier, &status );
|
||
|
|
||
|
|
||
|
APPENDIX A - COMPILATION AND LINKING
|
||
|
------------------------------------
|
||
|
|
||
|
Compilation flags are:
|
||
|
|
||
|
-I <prefix>/include
|
||
|
|
||
|
where prefix defaults to /usr/local.
|
||
|
|
||
|
Linking flags for a client are:
|
||
|
|
||
|
-L <prefix>/lib/ -lvalerie
|
||
|
|
||
|
Or for a local parser:
|
||
|
|
||
|
-L <prefix>/lib/ -lmiracle
|
||
|
|
||
|
Note that you never need both libs.
|
||
|
|
||
|
|
||
|
APPENDIX B - COMPLETE HIGH LEVEL PARSER WRAPPER API LISTING
|
||
|
-----------------------------------------------------------
|
||
|
|
||
|
valerie valerie_init( valerie_parser );
|
||
|
|
||
|
valerie_error_code valerie_connect( valerie );
|
||
|
|
||
|
valerie_error_code valerie_set( valerie, char *, char * );
|
||
|
valerie_error_code valerie_get( valerie, char *, char *, int );
|
||
|
|
||
|
valerie_error_code valerie_unit_add( valerie, char * );
|
||
|
valerie_error_code valerie_unit_load( valerie, int, char * );
|
||
|
valerie_error_code valerie_unit_load_clipped( valerie,int,char *,long,long );
|
||
|
valerie_error_code valerie_unit_load_back( valerie, int, char * );
|
||
|
valerie_error_code valerie_unit_load_back_clipped(valerie,int,char *,long,long)
|
||
|
valerie_error_code valerie_unit_play( valerie, int );
|
||
|
valerie_error_code valerie_unit_play_at_speed( valerie, int, int );
|
||
|
valerie_error_code valerie_unit_stop( valerie, int );
|
||
|
valerie_error_code valerie_unit_pause( valerie, int );
|
||
|
valerie_error_code valerie_unit_rewind( valerie, int );
|
||
|
valerie_error_code valerie_unit_fast_forward( valerie, int );
|
||
|
valerie_error_code valerie_unit_step( valerie, int, int );
|
||
|
valerie_error_code valerie_unit_goto( valerie, int, int );
|
||
|
valerie_error_code valerie_unit_set_in( valerie, int, int );
|
||
|
valerie_error_code valerie_unit_set_out( valerie, int, int );
|
||
|
valerie_error_code valerie_unit_clear_in( valerie, int );
|
||
|
valerie_error_code valerie_unit_clear_out( valerie, int );
|
||
|
valerie_error_code valerie_unit_clear_in_out( valerie, int );
|
||
|
valerie_error_code valerie_unit_set( valerie, int, char *, char * );
|
||
|
valerie_error_code valerie_unit_get( valerie, int, char * );
|
||
|
|
||
|
valerie_error_code valerie_unit_status( valerie, int, valerie_status );
|
||
|
valerie_notifier valerie_get_notifier( valerie );
|
||
|
|
||
|
valerie_dir valerie_dir_init( valerie, char * );
|
||
|
valerie_error_code valerie_dir_get( valerie_dir, int, valerie_dir_entry );
|
||
|
int valerie_dir_count( valerie_dir );
|
||
|
void valerie_dir_close( valerie_dir );
|
||
|
|
||
|
valerie_nodes valerie_nodes_init( valerie );
|
||
|
valerie_error_code valerie_nodes_get(valerie_nodes,int,valerie_node_entry);
|
||
|
int valerie_nodes_count( valerie_nodes );
|
||
|
void valerie_nodes_close( valerie_nodes );
|
||
|
|
||
|
valerie_units valerie_units_init( valerie );
|
||
|
valerie_error_code valerie_units_get(valerie_units,int,valerie_unit_entry);
|
||
|
int valerie_units_count( valerie_units );
|
||
|
void valerie_units_close( valerie_units );
|
||
|
|
||
|
valerie_response valerie_get_last_response( valerie );
|
||
|
|
||
|
valerie_error_code valerie_execute( valerie, size_t, char *, ... );
|
||
|
|
||
|
void valerie_close( valerie );
|
||
|
|
||
|
Notifier Functions
|
||
|
------------------
|
||
|
|
||
|
void valerie_notifier_get( valerie_notifier, valerie_status, int );
|
||
|
void valerie_notifier_put( valerie_notifier, valerie_status );
|
||
|
int valerie_notifier_wait( valerie_notifier, valerie_status );
|
||
|
void valerie_notifier_close( valerie_notifier );
|
||
|
|
||
|
Server Side Queuing
|
||
|
-------------------
|
||
|
|
||
|
valerie_list valerie_list_init( valerie, int )
|
||
|
valerie_error_code valerie_list_get_error_code( valerie_list )
|
||
|
valerie_error_code valerie_list_get( valerie_list, int, valerie_list_entry )
|
||
|
int valerie_list_count( valerie_list )
|
||
|
void valerie_list_close( valerie_list )
|
||
|
|
||
|
valerie_error_code valerie_unit_clean( valerie dv, int unit )
|
||
|
valerie_error_code valerie_unit_append( valerie dv, int unit, char *file, int in, int out )
|
||
|
valerie_error_code valerie_unit_remove_current_clip( valerie dv, int unit )
|
||
|
|
||
|
valerie_error_code valerie_unit_clip_goto( valerie dv, int unit, valerie_clip_offset offset, int clip, int position )
|
||
|
valerie_error_code valerie_unit_clip_set_in( valerie dv, int unit, valerie_clip_offset offset, int clip, int in )
|
||
|
valerie_error_code valerie_unit_clip_set_out( valerie dv, int unit, valerie_clip_offset offset, int clip, int in )
|
||
|
valerie_error_code valerie_unit_clip_move( valerie dv, int unit, valerie_clip_offset offset, int src, valerie_clip_offset offset, int dest )
|
||
|
valerie_error_code valerie_unit_clip_remove( valerie dv, int unit, valerie_clip_offset offset, int clip )
|
||
|
valerie_error_code valerie_unit_clip_insert( valerie dv, int unit, valerie_clip_offset offset, int clip, char *file, int in, int out )
|
||
|
|
||
|
|
||
|
|
||
|
APPENDIX C - COMPLETE LOW LEVEL PARSER API LISTING
|
||
|
--------------------------------------------------
|
||
|
|
||
|
valerie_response valerie_parser_connect( valerie_parser );
|
||
|
valerie_response valerie_parser_execute( valerie_parser, char * );
|
||
|
valerie_response valerie_parser_executef( valerie_parser, char *, ... );
|
||
|
valerie_response valerie_parser_run( valerie_parser, char * );
|
||
|
valerie_notifier valerie_parser_get_notifier( valerie_parser );
|
||
|
void valerie_parser_close( valerie_parser );
|
||
|
|
||
|
valerie_response valerie_response_init( );
|
||
|
valerie_response valerie_response_clone( valerie_response );
|
||
|
int valerie_response_get_error_code( valerie_response );
|
||
|
char *valerie_response_get_error_string( valerie_response );
|
||
|
char *valerie_response_get_line( valerie_response, int );
|
||
|
int valerie_response_count( valerie_response );
|
||
|
void valerie_response_set_error( valerie_response, int, char * );
|
||
|
int valerie_response_printf( valerie_response, size_t, char *, ... );
|
||
|
int valerie_response_write( valerie_response, char *, int );
|
||
|
void valerie_response_close( valerie_response );
|
||
|
|
||
|
|
||
|
APPENDIX D - REFERENCES
|
||
|
-----------------------
|
||
|
|
||
|
(1) doc/dvcp.txt - DVCP protocol
|
||
|
(2) doc/testing.txt - Test procedures
|