home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 7
/
AU_CD7.iso
/
_movies
/
_armovie
/
documents
/
fetchers
< prev
next >
Wrap
Text File
|
1997-12-01
|
10KB
|
207 lines
Introduction
------------
Fetchers are a section of the Replay architecture which allows the rest of the
system to ignore the details of the way the data is stored in the file.
Different formats of file can be accomodated by writing appropriate fetchers.
There must always be an ARMovie header in order to start the system up - for
formats where this is not natural, the ARMovie header is put into an image file
view of the original file. (see RISC OS PRM for details of Image files -
briefly, the original file is made to masquerade as a directory which holds
another view of the file some of which is created on the spot when accessed)
Jargon
Because there is so much overloading of words like Codec and file, let alone
names like Replay, QuickTime and Video for Windows, the following new jargon
word is introduced:
Container: a file structure for holding multimedia data. The ARMovie format
definition (minus any specific details of video and audio codecs) is an example
of a container: a QuickTime "MOV" and a Video for Windows "AVI" file format are
two other examples which are similar to ARMovie files; an MPEG transport stream
is another container of a very different type.
General
-------
To rephrase the opening paragraph: Fetchers are a section of the Replay
architecture dealing with specific containers. In order to play a particular
file, Replay needs to have:
* a program to generate the ARMovie header (usually as an Image file)
* a fetcher suitable for that container
* a video decompressor suitable for decompressing the video data
* an audio decompressor suitable for playing the sound data
For the specific case of ARMovie files, the first two sections are very easy
(no header needs to be generated and the standard ARMovie release understands
that container). A fetcher may be needed if the ARMovie file has to be played
from some abnormal medium (the standard code draws the file from the file
system) - for example from a streaming video server - and this can be done by
setting the ARMovie$Fetcher variable to describe a fetcher for ARMovie files.
Important header data
---------------------
The ARMovie header is used by many programs to handle ARMovie files. All the
details in the header must be present with the exception of the pointer to the
catalogue - a pointer must exist, but it becomes a parameter to the fetcher
rather than anything which is inspected by Replay programs. See the document
"AE7doc".
A fetcher is signalled by including the text "Fetcher [<name of fetcher>]" on
the catalogue line. Fetchers are stored within the directory
<ARMovie$Dir>.MovingLine.Fetchers.
Fetcher interface
-----------------
Fetchers have considerably more freedom in data structure than the chunk format
of ARMovie files. Video data and audio data may be in any order within the data
returned on fetching a chunk - the fetcher also returns indexes to the video
and audio for interesting values.
A fetcher is represented as a self-contained, position independant piece of
code which is dynamically loaded to a quad word aligned address. The first four
words contain the entry points Open, Close, Fetch, ReleaseBuffer - in that
order.
Open:
On Entry: R0=file handle
R1=catalogue offset
R2=access parameter (see document ProgIf)
R3=track number for audio OR -1 for no sound required
On Exit: R0=sound buffer size
R1-R13 preserved
Returns via MOV PC, R14
Does what ever it needs to in readiness for calls to Fetch. Free to allocate
memory; may load a module; may open more files etc. The sound buffer size
parameter gives the number of bytes which are needed to hold the total
compressed sound data for any particular chunk (in the ARMovie format, sound
data is held in one contiguous chunk, but other containers do not do this): a
value of zero may be returned to indicate that the sound data will be in one
contiguous chunk and does not need to be copied. A fetcher may be reinitialised
for a different file without being reloaded. Note that when r2=0, the file is
in memory (see ProgIf) and that it no longer needs to be copied around.
Close:
On Entry: ---
On Exit: R0-R13 preserved
Returns via MOV PC, R14
Release all memory which may have been allocated. This call does not close
the file containing the header, but does close all other used resources.
Fetch:
On Entry: R0=chunk number
R1=address of buffer
OR R1=base address in memory of file (when access=0)
R2=access
R3=NOT(useable status bits)
On Exit: R0=Pointer to Video Frame Index
R1=Pointer to Sound Index
R2=????
R3=status:
bit 0: fetch did not happen, try again
bit 1: fetch returns an error: error pointer in R0
bit 2: fetch needs to set the play status to
(status AND r0 OR r1)
bits 3-31: reserved - set to zero
R4-R13 preserved
Returns via MOV PC, R14
Fills the buffer (when access<>0) and returns a description of the information
it has loaded (positions of frames and chunks of sound) and a status. Info may
not be valid until ReleaseBuffer has also been called. A chunk number is
defined as if the file were in ARMovie format and divided into equal temporal
periods containing identical numbers of frames. Chunks are numbered 0 upwards
to the maximum chunk number (in the header). Chunks will be read by the ARMovie
system in any order (potentially) but real time performance is only required
for a sequential reading order. The start position may not be chunk 0 (it
depends on the -startat value, for example). When access=0 there is no buffer
in the Player program and the pointers to video frame and sound indexes must be
held in memory allocated by the fetcher: this is to make playing from in RAM
more efficient. The input value of r3 is the NOT of the status bits that the
caller can handle at the moment - a set bit means that that status bit will not
be processed by the caller, a clear bit means that that status bit can be
processed by the caller. Status bit 1 works on all calls, other status bits at
the discretion of the caller (e.g. the standard player will not allow bit 2 for
its first call on Fetch). The input status is designed so that if the register
is preserved nothing happens and designed so that newer fetchers will work with
older players and vice versa.
The frame index has the form:
Offset: 0 Frame 1 start (absolute addresses, not offsets)
4 Frame 2 start
...
Any value in the frame address is valid - illegal or unlikely addresses may
well be being used to give the video codec additional instructions. If the
strictly sequential ordering of ARMovie files is required, then the Video Frame
Index Pointer should be returned as zero from Fetch. A frame start address of
-1 is recognised by Player as meaning that the data has not arrived for this
frame - Player sets the frame index list entry to -2 and does not proceed with
video decompression until this frame start address has become valid: this
allows the system to have less latency (the fetcher returns a valid list as
soon as it can, but fills in the data later on).
The sound index has the form:
Offset: 0 Number of sound blocks
4 Start of sound block 1 (absolute address)
8 Size of sound block 1
12 Start of sound block 2
16 Size of sound block 2
...
Playing programs may well collate the sound information into one buffer - the
size of the necessary buffer is given by the Open call. As noted above,
containers other than ARMovie often have non-sequential buffers for sound. A
single sound block would correspond to the ARMovie file's version of sound, and
is efficiently processed even if sound buffer size (from Open) was not zero. If
the sound buffer size is zero, then only one sound block will be processed.
CopyFromAndReleasePreviousBuffer: (aka ReleaseBuffer)
On Entry: R0=chunk number
R1=address of buffer (destination buffer)
OR R1=base address in memory of file
On Exit: R0-R12 preserved
Returns via MOV PC, R14
Copies across any needed data from the previously loaded buffer (or previously
referenced section of an in-memory file) and may fill in some of the values
referred to by the pointers returned by Fetch. ReleaseBuffer must be called for
every call to Fetch, even the first (when there is no last buffer). It can be
called just before Fetch, just after, or under interrupt at any time during.
A fetcher author may use both Fetch and ReleaseBuffer as possible methods to
fill a chunk buffer: to fill the buffer b with chunk n, both calls Fetch(n, b)
and ReleaseBuffer(n, b) are made. Fetch could get what is needed from disc;
ReleaseBuffer will get what is needed from buffer n-1 (thus releasing Player
from the obligation of keeping buffer n-1 around). ReleaseBuffer needs to know
which buffer was filled last. It and Fetch must also recognise when chunk n is
being loaded out of order: in that situation Fetch should load the entire chunk
and ReleaseBuffer will do nothing. ReleaseBuffer must be called when loading
chunk 0, even though it would seem that it can't be doing anything useful.
Since ReleaseBuffer may be called from interrupt routines, it should never do
any IO: if it needs to do any substantial work it should reenable interrupts if
called in interrupt mode.
The fetcher must be written so that the calls to Fetch and ReleaseBuffer can be
performed in either order, or concurrently; concurrently is recommended for the
sake of disc latency. Users of the fetcher interface (such as Player) should
not call ReleaseBuffer(n) so early that it is concurrent with Fetch(n-1) or so
late that it is concurrent with Fetch(n+1); they must avoid using the info
returned by Fetch(n) until ReleaseBuffer(n) has completed.