LiVES OMC messages
------------------
This is my current thinking regarding how messaging will be implemented in LiVES.
I'm still updating it, so any suggestions are welcome.




INCOMING MESSAGES
-----------------
There will be a separate thread using gtk_input to provide asynchronous handling of incoming messages.

However, a /LIVES/RENDER... should not be sent to LiVES until you have first sent RECORD and have received a SYNC message from LiVES.






STATUS ::
------
return a status.

STATUS will be one of:

EMPTY|LAST_MESSAGE
READY|HANDLE|LAST_MESSAGE
WAIT|HANDLE|LAST_MESSAGE
HOLD|HANDLE|LAST_MESSAGE

PLAYING|HANDLE|FRAME_NUMBER|FPS|IMG_HSIZE|IMG_VSIZE|WIN_HSIZE|WIN_VSIZE|WID|LAST_MESSAGE

HANDLE is a (pseudo) random unique int for a LiVES session. You should read a HANDLE after opening a new asset to get it's handle.

LAST_MESSAGE is the message number of the last message received from APP. 


COMMANDS :: 
--------
will return a list of commands for LiVES.




OPEN_COMMAND_SOCKET (STRING)TRANSPORT (INT)PORT (BOOLEAN)DOES_BLOCK::
---------------------------------
Invite LiVES to open a command socket using protocol and port. Only works if LiVES has no already open command socket. So you send this down the status channel.


TELL_WINDOW :: Ask LiVES to send a CHANGE_WINDOW and RESIZE_WINDOW command whenever the X WIN ID of the playback window changes. This is to allow other apps to play in the LiVES GUI. You should somehow reparent your playback window when asked. If you get a CHANGE_WINDOW 0 command you must unparent your X11 window and hide it. This is only if you want to use your own playback engine. See below for an example.

Other options are to let LiVES use whatever playback engine the user has selected, or to send a STREAM command to LiVES to get frames from it, or send a RECORD command to pipe frames to it.



SET_EXTERNAL_SYNC 1|0  :: If set to ON, ask LiVES to wait for a SYNC message before sending a frame. LiVES will also send SYNC messages when it is recording and is ready for the next frame. Currently, if your app returns SET_SYNC as a possible command, LiVES will try to set this ON in your app when you connect. 



SET_STREAM 1|0 ::
------
If ON, Ask LiVES to stream frames down its command socket (SYNC ON) or its data socket (SYNC OFF) when it plays. For sync, LiVES will send /APP/RENDER/...commands down its command socket. (See below, outgoing commands). It will not currently implement an asychronous data stream, except maybe for audio.





NOSHOW 1|0 ::
---------------
If ON, LiVES will not show frames in its GUI when playing or recording.



IS_VALID_HANDLE (INT)HANDLE  :: returns TRUE if HANDLE is a valid clip number, or FALSE otherwise.


GET_CLIPS_AVAILABLE  ::
returns number of clips loaded. Could be used to determine if a user has loaded or closed additional clips.


LIST_AVAILABLE_CLIPS  ::
Ask LiVES to return a list of HANDLE's. It is best not to use it during playback.



GET_CLIP_DETAILS (INT)HANDLE  ::
-----------------------
Returns the following for clip HANDLE -
FRAMES|FPS|HSIZE|VSIZE|BPP
You should exercise caution if BPP!=24



SWITCH_TO_CLIP (INT)HANDLE  ::
---------------------
Switch clips. If the HANDLE is invalid, no switch will occur. You will not be able to switch clips if the status is HOLD.


 


OPEN_FILE_SELECTION FILENAME START_TIME NUMBER_OF_FRAMES ::
--------------------------------------------------------
Opens an audio or video file. Set START and NUMBER_OF_FRAMES to 0 to load a whole file/directory. Sets the status for this clip to WAIT, until loading is complete.



RESTORE_BACKUP BACKUP_FILE_NAME  ::
------------------------
Restore a LiVES (.lv1) backup file. LiVES cannot currently play or switch clips whilst restoring. Sets the status to HOLD.



PLAY ::
----
Only works if the status is READY. Begin playing/streaming the current clip.



CLOSE_CURRENT_CLIP ::
------------------



SET_LOOP_CONTINUOUS (BOOLEAN)



SET_LOOP_PING_PONG (BOOLEAN)::
-------------


RECORD  ::  Make LiVES start recording your /LiVES/RENDER messages.


SET_SELECTION_START FRAME


SET_SELECTION_END FRAME


GET_SELECTION_START


GET_SELECTION_END


PLAY_SELECTION :: play from selection_start to selection_end

PLAY_PREVIEW :: preview an effect with a long render time

USE_LAYER :: Tell LiVES to use LAYER (INT)LAYER if you support layers.
USE_STREAM :: A synonym for USE_LAYER

RENDER_EFFECT... :: send frames to LiVES for effects with long processing times.
                 By sending such frames to LiVES you can continue playing while 
		 LiVES performs the render.


SAVE_START_FRAME FILENAME

SAVE_END_FRAME FILENAME


SAVE_CLIP FILENAME


BACKUP_CLIP FILENAME.LV1


COPY_SELECTION

INSERT_SELECTION TIMES

REVERSE_CLIPBOARD

PASTE_AS_NEW

DELETE_SELECTION

LOAD_AUDIO

LOAD_CD_TRACK TRACK


RELOAD_SET SETNAME

FULLSCREEN ON|OFF


DOUBLESIZE ON|OFF


SEPARATE_WINDOW ON|OFF

RESIZE_ALL :: sets STATUS to HOLD.

CANCEL  :: If the status is HOLD or WAIT, you can send a CANCEL. You should keep checking until the status is READY. 


ENOUGH :: If the status is HOLD or WAIT you can send an ENOUGH message. You should keep checking until the status is READY. The exception is for RESTORE_BACKUP messages, which will ignore ENOUGH requests.


// The next only work during playback:
SET_FPS

PLAY_REVERSE

SKIP_FORWARDS

SKIP_BACK

FREEZE ON|OFF

SLOWER

FASTER






Real Time Effects
-----------------

The effects will be set by the user through a menu (eg 5==posterize). You can access them like:

/EFFECT/PIXELS/1  :: pixel effect 1 on
/EFFECT/PIXELS/2
/EFFECT/PIXELS/3
/EFFECT/PIXELS/4
/EFFECT/PIXELS/5  :: pixel effect 5 on
/EFFECT/6
/EFFECT/7
/EFFECT/8
/EFFECT/9

/EFFECT/0  :: switch effects off

Note you can currently only set one pixel effect at a time. If you set a pixel effect, the old pixel effect will be switched off.



/EFFECT/FRAMES/NERVOUS  ON|OFF  ::  frame effect nervous
/TOY/MAD_FRAMES ON|OFF  ::  mad frames toy




/EFFECT_RENDER/NEGATE  ::  Stream frames to LiVES, then LiVES will set status to HOLD until processing is complete.




OUTGOING COMMANDS
-----------------
For now, LiVES will send outgoing commands synchronously. Frame data will be sent asnychronously down a data pipe, but will be triggered synchronously by the system clock frame headers 



Queries
-------
/
/APP/
/APP/COMMANDS/


If APP returns /APP/EFFECTS after /APP

/APP/EFFECTS/

etc.


LiVES will then send /APP/EFFECT...commands

followed by:


/APP/RENDER/HANDLE/FRAME/FPS/PALETTE/HSIZE/VSIZE/PIXEL_DATA

Palette will currently always be ARGB.
Pixel_data will be a 32 bit ARGB buffer. LiVES will not currently send audio.

There needs to be some mechanism for LiVES to retrieve the changed frame if an effect is applied.



YUV will be implemented soon.


Before LiVES sends a PLAY command, it will try to set SYNC_ON in your app. If this is succesful, an outgoing PLAY message will be shortly followed by a SYNC command. LiVES will then wait for a /LIVES/RENDER...message.



-------------------------------------------------------------------






Examples
--------


Restoring and playing a clip:



/LIVES/RESTORE/"/usr/local/backup.lv1"/MESSAGE_NUMBER
/LIVES/STATUS/
                                                   HOLD|12345678|MESSAGE_NUMBER


loop :
   /LIVES/STATUS/ 
   (do something entertaining)
until status is:                                    READY|12345678|MESSAGE_NUMBER


/LIVES/SET_STREAM/ON/MESSAGE_NUMBER
						  READY|MESSAGE_NUMBER

/LIVES/SET_EXTERNAL_SYNC/0/MESSAGE_NUMBER
						  READY|MESSAGE_NUMBER
/LIVES/PLAY/MESSAGE_NUMBER

					         /APP/RENDER/....
					         /APP/RENDER/....


/LIVES/STOP/MESSAGE_NUMBER
/LIVES/STATUS/                                    READY|MESSAGE_NUMBER



/LIVES/SET_EXTERNAL_SYNC/1/MESSAGE_NUMBER
						  READY|MESSAGE_NUMBER


/LIVES/PLAY

Loop:
/LIVES/SYNC
					         /APP/RENDER/....

   Now for some fun...
/LIVES/SWITCH_CLIP/987654321
/LIVES/SET_FPS/37.62
/LIVES/EFFECTS/PIXELS/1
/LIVES/SKIP_FORWARD
/LIVES/SKIP_BACK
/LIVES/SLOWER

/LIVES/SYNC
                                                 /APP/RENDER....

until play end.


/LIVES/STOP/MESSAGE_NUMBER
/LIVES/STATUS/                                    READY|xxxxxxxxx













						
LiVES initiating playback in your app
-------------------------------------

If your app returned ADD_LAYERS as part of its description, when the user begins playback, LiVES will send /APP/ADD_LAYER/MESSAGE_NUMBER.

(or /APP/ADD_STREAM/MESSAGE_NUMBER (if you support ADD_STREAMS), unless you previously sent USE_LAYER or USE_STREAM to LiVES.)

LiVES will then wait for status READY|MESSAGE_NUMBER or ERROR|ERROR_NUMBER|MESSAGE_NUMBER in your app.

If your app returned SET_SYNC as a command, LiVES will send:
/APP/(LAYER)/SET_SYNC/ON/MESSAGE_NUMBER

LiVES will wait for a READY|MESSAGE_NUMBER before continuing.


/APP/(LAYER)/RECORD/MESSAGE_NUMBER

is sent next.


If SET_SYNC was succesful, LiVES waits for a SYNC|MESSAGE_NUMBER, sends a RENDER, and then may retrieve a changed frame from your app. Otherwise LiVES will start to stream asynchronously to your app.









Example:

/LIVES/RESIZE_ALL/NN
/LIVES/STATUS/
						  HOLD|HANDLE|NN
						  READY|HANDLE|NN

Errors:
/LIVES/STATUS/
						  ERROR|HANDLE|ERROR_NUMBER|NN





Recording:

/LIVES/SET_SYNC/ON/NN
                                              READY|NN
/LIVES/RECORD/NN
                                                       


                                      SYNC|NN
/LIVES/RENDER...
				      SYNC|NN
/LIVES/RENDER...

/LIVES/STOP/NN
/LIVES/STATUS/
                                      READY|HANDLE|NN
/LIVES/BACKUP/"/usr/local/new_backup.lv1"/NN
/LIVES/STATUS/
                                      HOLD|HANDLE|NN
                                      READY|HANDLE|NN




TELL_WINDOW example (if you want to play in LiVES GUI):


/LIVES/TELL_WINDOW/MESSAGE_NUMBER
/LIVES/STATUS
					   EMPTY|MESSAGE_NUMBER
or
                                           READY|HANDLE|MESSAGE_NUMBER



/LIVES/PLAY

LiVES creates Xwindow

                                     /APP/CHANGE_WINDOW nnnn
                                    /APP/RESIZE_WINDOW/HSIZE/VSIZE/MESSAGE_NUMBER

LiVES waits for status to show MESSAGE_NUMBER as the LAST_MESSAGE before sending any more frames.


during playback you could receive:

/APP/CHANGE_WINDOW/0/MESSAGE_NUMBER

LiVES waits for aknowledgement...

/APP/CHANGE_WINDOW/nnnn/MESSAGE_NUMBER
/APP/RESIZE_WINDOW/HSIZE/SIZE/MESSAGE_NUMBER

at any time. LiVES will wait again for aknowledgement until sending any more frames.


Before a window change or a stop, you always will receive:

/APP/CHANGE_WINDOW 0/MESSAGE_NUMBER

LiVES will wait for LAST_MESSAGE to show MESSAGE_NUMBER, before destroying the old window.

You will then receive either another CHANGE_WINDOW/RESIZE_WINDOW pair, or a STOP.

















