]> git.sesse.net Git - mlt/blob - docs/valerie.txt
Doc formating
[mlt] / docs / valerie.txt
1 Valerie API Documentation 
2
3 Copyright (C) 2004 Ushodaya Enterprised Limited 
4 Author: Charles Yates <charles.yates@pandora.be> 
5 Last Revision: 2004-03-20
6
7
8 TABLE OF CONTENTS
9 -----------------
10
11         0. Overview 
12         0.1. Intended Audience
13         0.2. Terminology
14         1. Definition of a Parser 
15         1.1. Construction of a Local Parser 
16         1.2. Construction of a Remote Parser
17         1.3. Using the Parser
18         1.4. Closing the Parser
19         2. The High Level Parser Wrapper
20         2.1. Connecting
21         2.2. valerie_error_code
22         2.3. Using the High Level Wrapper
23         2.4. Obtaining Directory Contents
24         2.5. Obtaining the Node List
25         2.6. Obtaining the Unit List
26         2.7. Unit Status Information
27         2.8. Server Side Queuing APIs
28         2.9. Accessing the Low Level Parser Directly
29         2.10. Cleaning up
30         2.11. Examples
31         3. The Low Level Parser API
32         3.1. Executing a Command
33         3.2. Interpreting valerie_response
34         3.3. Accessing Unit Status
35         APPENDIX A - COMPILATION AND LINKING
36         APPENDIX B - COMPLETE HIGH LEVEL PARSER WRAPPER API LISTING
37         APPENDIX C - COMPLETE LOW LEVEL PARSER API LISTING
38         APPENDIX D - REFERENCES
39         
40
41 0. Overview 
42 -----------
43
44         This document details how applications interface to DVCP functionality. 
45
46
47 0.1. Intended Audience
48 ----------------------
49
50         This document draws heavily upon the DVCP design (1) and assumes a basic 
51         knowledge of the functionality provided by the DVCP core. 
52
53         It is aimed at developers who wish to use or maintain the API.
54
55
56 0.2. Terminology
57 ----------------
58
59         The API is designed to allow client applications the ability to communicate
60         to a standalone miracle server or entirely embed the DVCP core in an 
61         instance of a client application. 
62
63         The distinction between the two is defined by the construction of the 
64         'parser'. 
65
66         This 'parser' can be used to issue DVCP commands and receive responses and 
67         a 'high level parser wrapper' is provided to simplify the usage and 
68         decouple the application from the DVCP command set.
69
70
71 1. Definition of a Parser 
72 ------------------------- 
73
74         The parser provides a low level API which allows text DVCP commands to be 
75         executed with responses being returned to the caller. Commands and 
76         responses are ASCII formatted text. 
77
78         Two parsers are provided - local and remote. 
79
80         The local parser is the physical implementation which takes commands and 
81         executes them. 
82
83         The remote parser is a network abstraction that forwards commands to a 
84         miracle instance that hosts a local parser. 
85
86
87 1.1. Construction of a Local Parser 
88 ----------------------------------- 
89
90         To construct a local parser you must have:
91
92             #include <miracle/miracle_local.h>
93
94         and code to initialise the parser is as follows:
95
96             valerie_parser parser = miracle_parser_init_local( );
97
98         See Appendix A for compilation and linking details.
99
100
101 1.2. Construction of a Remote Parser
102 ------------------------------------
103
104         To construct a remote parser you must have:
105
106             #include <valerie/valerie_remote.h>
107
108         and code to initialise the parser is as follows:
109
110             valerie_parser parser = valerie_parser_init_remote( "server", port );
111
112         See Appendix A for compilation and linking details.
113
114
115 1.3. Using the Parser
116 ---------------------
117
118         Although the parser can be used directly to send commands and receive 
119         responses, this low level usage puts the onus on the developer to parse the 
120         responses in a meaningful way. 
121
122         Although this usage is not strictly forbidden by applications, it is 
123         discouraged as construction of commands and meaningful parsing of responses 
124         leads to the clients being unnecessarily dependent on the servers input and 
125         output. 
126
127         As a result, a higher level Parser Wrapper API is provided - this API 
128         encapsulates the command construction and response parsing.
129
130         The following 2 sections provide details on these modes of access.
131
132
133 1.4. Closing the Parser
134 -----------------------
135
136         Regardless of use, it is the constructors responsibility to close the 
137         parser before it goes out of scope. This is done via:
138
139             valerie_parser_close( parser );
140
141
142 2. The High Level Parser Wrapper
143 --------------------------------
144
145         The recommended way to access the parser, is via the valerie API. To use 
146         this API, you must have:
147
148             #include <valerie/valerie.h>
149
150         and code to construct the wrapper is:
151
152             valerie dv = valerie_init( parser );
153
154         Note that either remote or local parsers can be used here and there is no 
155         difference in usage, though some error returns will not be applicable to 
156         both. 
157
158         It is recommended that applications honour and deal with the error returns 
159         of both as this allows applications to interchange parsers.
160
161         Also note that valerie is not threadsafe, so you should not use the same 
162         structure in multiple threads. The correct solution to this is to create a
163         valerie per thread - you may safely use the same parser for each thread ie:
164
165             /* valerie for the application */
166             valerie dv = valerie_init( parser );
167             /* valerie for the status handling thread. */
168             valerie dv_status = valerie_init( parser );
169
170         For the purposes of simplification, the remainder of this section assumes 
171         that a remote parser is in use. 
172
173
174 2.1. Connecting
175 ---------------
176
177         Once constructed, the next thing to do is 'connect':
178
179             valerie_error_code error = valerie_connect( dv );
180
181         This function call initialises the parser (ie: if it's remote, it 
182         establishes a connection to the server, or if it's local, it initialises 
183         the state of the units and supporting objects).
184
185         Note that if you have multiple valerie instances on the same parser you 
186         should only connect one of the instances.
187
188
189 2.2. valerie_error_code
190 ----------------------
191
192         All but a couple of the functions that make up the valerie API return a 
193         valerie_error_code.
194
195         These are defined as follows:
196
197             valerie_ok = 0,
198             valerie_malloc_failed,
199             valerie_unknown_error,
200             valerie_no_response,
201             valerie_invalid_command,
202             valerie_server_timeout,
203             valerie_missing_argument,
204             valerie_server_unavailable,
205             valerie_unit_creation_failed,
206             valerie_unit_unavailable,
207             valerie_invalid_file,
208             valerie_invalid_position
209
210         In most cases, it is sufficient to check on a return of valerie_ok.
211
212         To obtain a textual description of a particular error, you can use:
213
214             char *valerie_error_description( valerie_error_code );
215
216
217 2.3. Using the High Level Wrapper
218 ---------------------------------
219
220         The following code snippet assumes that dv is an initialised and connected 
221         valerie structure:
222
223             valerie_error_code error = valerie_unit_play( dv, 0 );
224             if ( error == valerie_ok )
225                 fprintf( stderr, "Unit 0 is now playing\n" );
226             else
227                 fprintf( stderr, "Play on unit 0 failed: %s\n",
228                              valerie_error_description( error ) );
229
230         The complete interface to valerie is listed in Appendix B of this document.
231
232
233 2.4. Obtaining Directory Contents
234 --------------------------------
235
236         To obtain a list of files and subdirectories in a given directory relative 
237         to the ROOT property of the server, DVCP provides the CLS command. 
238
239         A valid execution of CLS would be something like:
240
241             CLS "/Stuff"
242
243         would provide a response formatted as follows:
244
245             201 OK
246             "More Stuff/"
247             "file0001.dv" 15552000
248             "file0002.dv" 15552000
249
250         with a trailing empty line.
251
252         The first line indicates the error value, the second line shows an example 
253         of a subdirectory and the 3rd and 4th line lists two files that happen to 
254         exist in the directory.
255
256         valerie provides a high level view on this which automatically parses the 
257         response from the server correctly via the valerie_dir structures and 
258         related functions. 
259
260         An example of use is as follows:
261         
262             valerie_dir dir = valerie_dir_init( dv, "/Stuff" );
263             valerie_error_code error = valerie_dir_get_error_code( dir );
264             if ( error == valerie_ok )
265             {
266                 if ( valerie_dir_count( dir ) > 0 )
267                 {
268                     valerie_dir_entry_t entry;
269                     int index = 0;
270                     for ( index = 0; index < valerie_dir_count( dir ); index ++ )
271                     {
272                         valerie_dir_get( dir, index, &entry );
273                         if ( entry.dir )
274                             printf( "<%s>\n", entry.name );
275                         else
276                             printf( "%30s %8d", entry.name, entry.size );
277                     }
278                 }
279                 else
280                 {
281                     fprintf( stderr, "Directory is empty\n" );
282                 }
283             }
284             else
285             {
286                 fprintf( stderr, "Directory listing failed: %s\n",
287                                  valerie_error_description( error ) );
288             }
289             valerie_dir_close( dir );
290
291         Note that entry.name provides the name of the file or directory without the 
292         directory prefix. As a convenience, entry.full provides the prefixed name, 
293         so you could subsequently use:
294
295             error = valerie_unit_load( dv, 0, entry.full );
296
297         to load unit 0 with an entry.
298
299
300 2.5. Obtaining the Node List
301 ----------------------------
302
303         Currently not defined by miracle.
304
305 2.6. Obtaining the Unit List
306 ----------------------------
307
308         To obtain a list of defined units, DVCP provides the ULS command.
309         
310         A valid execution of ULS would be:
311         
312             ULS
313         
314         and would provide a response formatted as follows:
315         
316             201 OK
317             U0 00 sdl:360x288 1
318         
319         with a trailing empty line.
320         
321         The fields of each record in the response dictate unit, node, mlt consumer and 
322         online status respectively.
323         
324         valerie provides a high level view on this which automatically parses the 
325         response from the server correctly via the valerie_units structures and 
326         related functions. 
327         
328         An example of use is as follows:
329         
330             valerie_units units = valerie_units_init( dv );
331             valerie_error_code error = valerie_units_get_error_code( units );
332             if ( error == valerie_ok )
333             {
334                 if ( valerie_units_count( units ) > 0 )
335                 {
336                     valerie_unit_entry_t entry;
337                     int index = 0;
338                     for ( index = 0; index < valerie_units_count( units ); index ++ )
339                     {
340                         valerie_units_get( units, index, &entry );
341                         printf( "U%d %02d %s %s\n", 
342                                 entry.unit,
343                                 entry.node,
344                                 entry.guid,
345                                 entry.online ? "online" : "offline" );
346                     }
347                 }
348                 else
349                 {
350                     fprintf( stderr, "Unit list is empty\n" );
351                 }
352             }
353             else
354             {
355                 fprintf( stderr, "Unit listing failed: %s\n",
356                                  valerie_error_description( error ) );
357             }
358             valerie_units_close( units );
359         
360
361 2.7. Unit Status Information
362 ----------------------------
363
364         There are two methods for a client to obtain unit status information.
365         
366         The first is via the DVCP USTA command, which would normally be accessed 
367         via: 
368
369             USTA U0
370         
371         and would provide a response formated as follows:
372         
373             202 OK
374             0 playing "a.dv" 58 1000 25.00 0 6999 7000 "a.dv" 157 0 6999 7000 1 4 0
375         
376         with no trailing empty line.
377         
378         The entries in the record are:
379         
380         * Unit
381         * State (undefined, offline, not_loaded, stopped, playing, 
382                  paused, disconnected [when server dies])
383         * Name of Clip
384         * Position in clip
385         * Speed * 1000
386         * Frames per second
387         * Start of clip (in point)
388         * End of clip (out point)
389         * Length of clip
390         * Read ahead clip
391         * Read ahead position 
392         * Read ahead clip in
393         * Read ahead clip out
394         * Read ahead clip length
395         * Seekable flag
396         * Playlist generation
397         * Clip index
398         
399         Again, valerie provides a high level means for obtaining this via the 
400         valerie_unit_status function and valerie_status structures:
401         
402             valerie_status_t status;
403             valerie_error_code error = valerie_unit_status( dv, 0, &status );
404             if ( error == valerie_ok )
405             {
406                 switch( status.status )
407                 {
408                     case unit_offline:
409                         printf( "offline   " );
410                         break;
411                     case unit_undefined:
412                         printf( "undefined " );
413                         break;
414                     case unit_not_loaded:
415                         printf( "unloaded  " );
416                         break;
417                     case unit_stopped:
418                         printf( "stopped   " );
419                         break;
420                     case unit_playing:
421                         printf( "playing   " );
422                         break;
423                     default:
424                         printf( "unknown   " );
425                         break;
426                 }
427         
428                 printf( "%06lld %06lld %06lld %s\n", status.in,
429                                                      status.position,
430                                                      status.out,
431                                                      status.clip );
432             }
433             else
434             {
435                 fprintf( stderr, "Unit status failed: %s\n",
436                                  valerie_error_description( error ) );
437             }
438         
439         The second approach for obtaining a units status is via automatic 
440         notification.
441         
442         This is done via the valerie_notifier API. To obtain the notifier from the 
443         high level API, you can use:
444         
445             valerie_notifier notifier = valerie_get_notifier( dv );
446         
447         To obtain the last status associated to a unit, you can use:
448         
449             int unit = 1;
450             valerie_status_t status;
451             valerie_notifier_get( notifier, &status, unit );
452         
453         To wait for the next status from any unit, you can use:
454         
455             valerie_notifier_wait( notifier, &status );
456         
457         If you wish to trigger the action associated to your applications wait 
458         handling of a particular unit, you can use:
459         
460             valerie_notifier_get( notifier, &status, unit );
461             valerie_notifier_put( notifier, &status );
462         
463         See Examples below for details on this.
464
465         The complete list of fields in the status structure are:
466
467             int unit;
468             unit_status status;
469             char clip[ 2048 ];
470             int64_t position;
471             int speed;
472             double fps;
473             int64_t in;
474             int64_t out;
475             int64_t length;
476             char tail_clip[ 2048 ];
477             int64_t tail_position;
478             int64_t tail_in;
479             int64_t tail_out;
480             int64_t tail_length;
481             int seekable;
482             int generation;
483             int clip_index;
484         
485         You will always receive a status record for every frame output.
486
487         The read ahead information is provided for client side queuing. Client side
488         queuing assumes that uset eof=pause is applied to the unit. A client can 
489         detect when the previously scheduled clip is played out by using the read 
490         ahead information and schedule the next clip. While this mode of operation
491         is still supported, it is recommended that new clients use the server side
492         queuing mechanism which is described in the following section.
493         
494
495 2.8. Server Side Queueing APIs
496 ------------------------------
497
498         This section describes the APIs available to provide server side queueing. 
499         
500         The concept is that each unit maintains its own playlist, containing multiple
501         clips. Associated to the playlist is a generation number which is incremented 
502         on each modification to the playlist. The current playlist generation is
503         provided in the status record in order for a client to know when to refresh
504         its presentation of the list. The status record also indicates which clip is 
505         currently active.
506         
507         Actions that can be carried out on the playlist are summarised as:
508         
509         * list - list all the clips and associated in/out points and size
510         * loading a clip - a load will wipe the current list and replace it with the
511           specified clip
512         * appending a clip - append will always place the specified clip at the end 
513           of the playlist
514         * inserting a clip - insert will place a new clip at the specified position 
515           in the playlist
516         * moving a clip - move will allow clips can be moved in the playlist
517         * removing a clip - remove will remove the specified clip from the playlist
518         * clean - clean will remove all but the playing clip from the playlist
519         
520         Additionally, the following existing actions are clip aware:
521         
522         * goto allows you to move the current play position to a specific clip position
523         * set in/out points allows you to modify clip in and out points
524         
525         Backward compatability has been maintained by the addition of a clip-aware 
526         family of APIs which have the naming convention of valerie_unit_clip_*.
527         
528         These are listed in Appendix B.
529         
530         The following shows an example of obtaining the clips queued on unit 0:
531         
532             valerie_list list = valerie_list_init( dv, 0 );
533             valerie_list_entry_t entry;
534             int index;
535             
536             printf( "Generation = %d\n", list->generation );
537             for ( index = 0; index < valerie_list_count( list ); index ++ )
538             {
539                 valerie_list_get( list, index, &entry );
540                 printf( "%d %s %d %d %d %d\n", 
541                         entry.clip, 
542                         entry.full,
543                         entry.in,
544                         entry.out,
545                         entry.max,
546                         entry.size );
547             }
548             valerie_list_close( list );
549             
550         To load a clip on unit 0:
551         
552             valerie_unit_load( dv, 0, "/path/clip.dv" );
553             
554         To append a clip on unit 0:
555         
556             valerie_unit_append( dv, 0, "/path/clip.dv", -1, -1 );
557             
558         Note that the last two arguments specify the in and out points of the clip
559         with -1 denoting dfaults of the entirety of the file.
560         
561         To insert a clip at position 0 on unit 0, we can use the following:
562         
563             valerie_unit_clip_insert( dv, 0, clip_absolute, 0, "/path/clip.dv", -1, -1 );
564             
565         The 3rd and 4th arguments here are common to all the valerie_unit_clip functions.
566         They take the form of either [clip_absolute, n] to indicate an absolute clip
567         index, or [clip_relative, n] to indicate a clip index relative to the 
568         currently playing clip.
569         
570         So, to insert a clip immediately before the currently playing clip, we can
571         use:
572         
573             valerie_unit_clip_insert( dv, 0, clip_relative, -1, "/path/clip.dv", -1, -1 );
574             
575         To move the current clip to the next position in the list:
576         
577             valerie_unit_clip_move( dv, 0, clip_relative, 0, clip_relative, 1 );
578             
579         To remove a specific clip:
580         
581             valerie_unit_clip_remove( dv, 0, clip_absolute, index );
582             
583         To remove all but the currently playing clip:
584         
585             valerie_unit_clean( dv, 0 );
586             
587         To goto the first frame in the first clip, you can use:
588         
589             valerie_unit_clip_goto( dv, 0, clip_absolute, 0, 0 );
590             
591         To set the in and out points on the current clip:
592         
593             valerie_unit_clip_set_in( dv, 0, clip_relative, 0, 0 );
594             valerie_unit_clip_set_out( dv, 0, clip_relative, 0, 1000 );
595             
596         A more complete example of use of the server side can queuing can be found
597         at:
598         
599             http://users.pandora.be/acp/rugen
600             
601         The demo client provided with valerie is used for retaining backward 
602         compatability with the client side queuing API.
603
604         
605 2.9. Accessing the Low Level Parser Directly
606 --------------------------------------------
607
608         The low level parser and its associated structures can be accessed directly 
609         from the high level API, but is very occasionally actually needed.
610         
611         The methods are provided via a pair of high level methods:
612         
613             valerie_error_code error = valerie_execute( dv, 1024, "USTA U%d", unit );
614             valerie_response response = valerie_get_last_response( dv );
615             int index = 0;
616             for ( index = 0; index < valerie_response_count( response ); index ++ )
617                 printf( "%d: %s\n", index, valerie_response_get_line( response,index ) );
618         
619         More details on the valerie_response structure can be found in section 3 of this
620         document.
621         
622
623 2.10. Cleaning up
624 -----------------
625
626         Before the valerie and parser go out of scope, you need to run:
627         
628             valerie_close( dv );
629             valerie_parser_close( parser );
630         
631         Note that you should close all valerie instances before closing the parser.
632         
633
634 2.11. Examples
635 --------------
636
637         Please refer to albino and humperdink source for examples provided with
638         the project. Additional examples can be found via google with gdv1394 and
639         poldo.
640
641
642 3. The Low Level Parser API
643 ---------------------------
644
645         The low level parser API provides a very simple mechanism for constructing 
646         commands and receiving responses.
647         
648         As described in section 2, a parser is constructed as local or remote and 
649         this is sufficient for constructing the low level parser.
650         
651
652 3.1. Executing a Command
653 ------------------------
654
655         All commands can be executed via the single variable argument function
656         valerie_parser_executef and this function returns a valerie_response, ie:
657         
658             valerie_response response = valerie_parser_executef( parser, "CLS \"%s\"", dir );
659         
660         Note that no carriage return/line feed is required (adding this is 
661         erroneous).
662         
663         It is the receiver of the response who is responsible for closing it.
664         
665             valerie_response_close( response );
666         
667
668 3.2. Interpreting valerie_response
669 -----------------------------
670
671         The response received can be NULL, but it is safe to call:
672         
673             int error = valerie_response_get_error_code( response );
674         
675         which will return:
676         
677         * -1 if response is NULL, 
678         * -2 if there is no content to the response, 
679         * 0 if the responses first line does not correspond to a valid DVCP response
680         * or the DVCP protocol error code returned on the first line of the response
681         
682         A simple use of a valerie_response structure is as follows:
683         
684             valerie_response response = valerie_parser_executef( parser, "CLS \"%s\"", dir );
685             int error = valerie_response_get_error_code( response );
686             if ( error >= 0 )
687             {
688                 int index = 0;
689                 for ( index = 0; index < valerie_response_count( response ); index ++ )
690                     printf( "%3d: %s\n", index, valerie_response_get_line( response, index ) );
691             }
692             else
693             {
694                 /* interpret error */
695             }
696             valerie_response_close( response );
697         
698         Note that it is safe to call valerie_response_close regardless of the error 
699         condition indicated.
700         
701
702 3.3. Accessing Unit Status
703 --------------------------
704
705         As with the high level parser, there are two alternatives to obtain unit 
706         status information - either via the USTA DVCP command or via the 
707         valerie1394_notifier.
708         
709         The latter is the recommended way for any applications which wish to extract
710         meaningful information from the status while avoiding the requirement to 
711         duplicate the parsing process in a specific client.
712         
713         The notifier can be obtained by:
714         
715         valerie_notifier notifier = valerie_parser_get_notifier( parser );
716         
717         The use of the notifier with the low level parser is identical to that 
718         dictated in Section 2 - to obtain the last status associated to a unit, 
719         you can use: 
720
721             int unit = 1;
722             valerie_status_t status;
723             valerie_notifier_get( notifier, &status, unit );
724             
725         To wait for the next status from any unit, you can use:
726         
727             valerie_notifier_wait( notifier, &status );
728         
729
730 APPENDIX A - COMPILATION AND LINKING
731 ------------------------------------
732
733         Compilation flags are:
734
735             -I <prefix>/include
736
737         where prefix defaults to /usr/local.
738
739         Linking flags for a client are:
740
741             -L <prefix>/lib/ -lvalerie
742
743         Or for a local parser:
744
745             -L <prefix>/lib/ -lmiracle
746
747         Note that you never need both libs.
748
749
750 APPENDIX B - COMPLETE HIGH LEVEL PARSER WRAPPER API LISTING
751 -----------------------------------------------------------
752
753         valerie valerie_init( valerie_parser );
754         
755         valerie_error_code valerie_connect( valerie );
756         
757         valerie_error_code valerie_set( valerie, char *, char * );
758         valerie_error_code valerie_get( valerie, char *, char *, int );
759         
760         valerie_error_code valerie_unit_add( valerie, char * );
761         valerie_error_code valerie_unit_load( valerie, int, char * );
762         valerie_error_code valerie_unit_load_clipped( valerie,int,char *,long,long );
763         valerie_error_code valerie_unit_load_back( valerie, int, char * );
764         valerie_error_code valerie_unit_load_back_clipped(valerie,int,char *,long,long)
765         valerie_error_code valerie_unit_play( valerie, int );
766         valerie_error_code valerie_unit_play_at_speed( valerie, int, int );
767         valerie_error_code valerie_unit_stop( valerie, int );
768         valerie_error_code valerie_unit_pause( valerie, int );
769         valerie_error_code valerie_unit_rewind( valerie, int );
770         valerie_error_code valerie_unit_fast_forward( valerie, int );
771         valerie_error_code valerie_unit_step( valerie, int, int );
772         valerie_error_code valerie_unit_goto( valerie, int, int );
773         valerie_error_code valerie_unit_set_in( valerie, int, int );
774         valerie_error_code valerie_unit_set_out( valerie, int, int );
775         valerie_error_code valerie_unit_clear_in( valerie, int );
776         valerie_error_code valerie_unit_clear_out( valerie, int );
777         valerie_error_code valerie_unit_clear_in_out( valerie, int );
778         valerie_error_code valerie_unit_set( valerie, int, char *, char * );
779         valerie_error_code valerie_unit_get( valerie, int, char * );
780         
781         valerie_error_code valerie_unit_status( valerie, int, valerie_status );
782         valerie_notifier valerie_get_notifier( valerie );
783         
784         valerie_dir valerie_dir_init( valerie, char * );
785         valerie_error_code valerie_dir_get( valerie_dir, int, valerie_dir_entry );
786         int valerie_dir_count( valerie_dir );
787         void valerie_dir_close( valerie_dir );
788         
789         valerie_nodes valerie_nodes_init( valerie );
790         valerie_error_code valerie_nodes_get(valerie_nodes,int,valerie_node_entry);
791         int valerie_nodes_count( valerie_nodes );
792         void valerie_nodes_close( valerie_nodes );
793         
794         valerie_units valerie_units_init( valerie );
795         valerie_error_code valerie_units_get(valerie_units,int,valerie_unit_entry);
796         int valerie_units_count( valerie_units );
797         void valerie_units_close( valerie_units );
798         
799         valerie_response valerie_get_last_response( valerie );
800         
801         valerie_error_code valerie_execute( valerie, size_t, char *, ... );
802         
803         void valerie_close( valerie );
804         
805         Notifier Functions
806         ------------------
807         
808         void valerie_notifier_get( valerie_notifier, valerie_status, int );
809         void valerie_notifier_put( valerie_notifier, valerie_status );
810         int valerie_notifier_wait( valerie_notifier, valerie_status );
811         void valerie_notifier_close( valerie_notifier );
812         
813         Server Side Queuing
814         -------------------
815
816         valerie_list valerie_list_init( valerie, int )
817         valerie_error_code valerie_list_get_error_code( valerie_list )
818         valerie_error_code valerie_list_get( valerie_list, int, valerie_list_entry )
819         int valerie_list_count( valerie_list )
820         void valerie_list_close( valerie_list )
821         
822         valerie_error_code valerie_unit_clean( valerie dv, int unit )
823         valerie_error_code valerie_unit_append( valerie dv, int unit, char *file, int in, int out )
824         valerie_error_code valerie_unit_remove_current_clip( valerie dv, int unit )
825         
826         valerie_error_code valerie_unit_clip_goto( valerie dv, int unit, valerie_clip_offset offset, int clip, int position )
827         valerie_error_code valerie_unit_clip_set_in( valerie dv, int unit, valerie_clip_offset offset, int clip, int in )
828         valerie_error_code valerie_unit_clip_set_out( valerie dv, int unit, valerie_clip_offset offset, int clip, int in )
829         valerie_error_code valerie_unit_clip_move( valerie dv, int unit, valerie_clip_offset offset, int src, valerie_clip_offset offset, int dest )
830         valerie_error_code valerie_unit_clip_remove( valerie dv, int unit, valerie_clip_offset offset, int clip )
831         valerie_error_code valerie_unit_clip_insert( valerie dv, int unit, valerie_clip_offset offset, int clip, char *file, int in, int out )
832
833         
834
835 APPENDIX C - COMPLETE LOW LEVEL PARSER API LISTING
836 --------------------------------------------------
837
838         valerie_response valerie_parser_connect( valerie_parser );
839         valerie_response valerie_parser_execute( valerie_parser, char * );
840         valerie_response valerie_parser_executef( valerie_parser, char *, ... );
841         valerie_response valerie_parser_run( valerie_parser, char * );
842         valerie_notifier valerie_parser_get_notifier( valerie_parser );
843         void valerie_parser_close( valerie_parser );
844         
845         valerie_response valerie_response_init( );
846         valerie_response valerie_response_clone( valerie_response );
847         int valerie_response_get_error_code( valerie_response );
848         char *valerie_response_get_error_string( valerie_response );
849         char *valerie_response_get_line( valerie_response, int );
850         int valerie_response_count( valerie_response );
851         void valerie_response_set_error( valerie_response, int, char * );
852         int valerie_response_printf( valerie_response, size_t, char *, ... );
853         int valerie_response_write( valerie_response, char *, int );
854         void valerie_response_close( valerie_response );
855         
856
857 APPENDIX D - REFERENCES
858 -----------------------
859
860         (1) doc/dvcp.txt - DVCP protocol
861         (2) doc/testing.txt - Test procedures