NT4/private/windows/media/avi/avifile.16/usage.txt
2020-09-30 17:12:29 +02:00

193 lines
6.4 KiB
Plaintext

Using AVIFile.
Initializing the AVIFile DLL:
Before using any of the APIs in AVIFILE.DLL, be sure to
call AVIStreamInit. After using them, call AVIStreamExit.
If you don't, bad things will happen.
Using AVIFile to read some kind of file:
First, call AVIFileOpen with the OF_READ flag to open the file.
Then, you can call AVIFileInfo to find out how many streams are in
the file, and AVIFileGetStream to retrieve the streams you want.
Once you have a stream, you can can AVIStreamReadFormat to get the
bitmap format or wave format, and then call AVIStreamRead to actually
read the data you want.
AVIFile and the Component Object model:
The AVIFile APIs include two interfaces, IAVIFile and IAVIStream,
which work with the Component Object model which is part of OLE 2.0.
Class IDs
Each server or DLL that handles these interfaces needs to have a
Globally Unique ID (GUID), so that it can be distinguished from all
other handlers. OLE uses 16-byte identifiers for this purpose. If
you're making a new handler, you can run the UUIDGEN program to make
yourself a unique ID.
The Registration Database
The registration database is essentially just a replacement for .INI
files. To look at what's going on in it, run "regedit -v".
DLLs which implement the IAVIFile and IAVIStream interfaces all need
to be listed in the registration database so that they can be found
when necessary.
Each DLL must be listed in the registration database by class ID,
with entries of the form:
HKEY_CLASSES_ROOT\Clsid\{00020003-0000-0000-C000-000000000046} = Wave File reader/writer
HKEY_CLASSES_ROOT\Clsid\{00020003-0000-0000-C000-000000000046}\InprocServer = wavefile.dll
where HKEY_CLASSES_ROOT is the root of the entire registration
database. The InProcServer entry indicates that wavefile.dll can be
loaded within an application to implement the class in question.
The AVIFile library uses additional entries in the registration
database in order to know which handler to use by default to open a
given file. If the file is a RIFF file,
HKEY_CLASSES_ROOT\AVIFile\Extensions\WAV = {00020003-0000-0000-C000-000000000046}
HKEY_CLASSES_ROOT\AVIFile\RIFFHandlers\WAVE = {00020003-0000-0000-C000-000000000046}
You get a GUID by running the uuidgen.exe program that comes
with the SDK; it will spit out a 16-byte hex number for you. You then
make a file with a .REG extension that looks like:
REGEDIT
HKEY_CLASSES_ROOT\Clsid\{5C2B8200-E2C8-1068-B1CA-6066188C6002} = JFIF (JPEG) Files
HKEY_CLASSES_ROOT\Clsid\{5C2B8200-E2C8-1068-B1CA-6066188C6002}\InprocServer =jfiffile.dll
HKEY_CLASSES_ROOT\AVIFile\Extensions\JPG = {5C2B8200-E2C8-1068-B1CA-6066188C6002}
(Of course, use your GUID here.) Then, on a user's machine, they can run
regedit -s whatever.reg and these definitions will get added to the
registration database, allowing the system to find your DLL and know what
sorts of files it can load.
What are IAVIFile and IAVIStream?
(Note: you may just want to read the OLE 2 documentation here....)
These are examples of "interfaces". An interface is a collection of
"methods".
Implementing a handler DLL
IClassFactory
Obviously, it isn't enough for OLE to know the name of your DLL; some
standard entry point is required to establish communications. The
method through which COMPOBJ.DLL does this isn't exactly
straightforward. A handler DLL must export a DllGetClassObject
function; COMPOBJ calls that function to ask the DLL to return an
instance of the IClassFactory interface, which it then uses to
actually acquire an instance of the IAVIFile interface that we
actually care about.
Single-stream vs. Multi-stream
AVI files obviously support more than one stream of data in each
file. Wave files, for example, are much simpler, in that they only
can have exactly one stream of audio. This means that we only need
one stream object around, and we can make things even simpler by
having the same object support both the stream and file interfaces.
If you know that your handler will support, say, exactly one audio
and one video stream, things are also simpler than the completely
general case, because when you create your file object, you know that
you will have to create exactly two stream objects.
Read-only vs. Read-write
A handler can be written which only supports reading or writing; you
can always return an error code from any method. (One suggestion:
don't return unsupported from the FindSample function, but rather
just return that every frame is a key frame, every frame is non-empty, and
that the only format change is frame 0)
Using C++
These handlers don't actually need to be implemented using C++; it
was just easier that way.
Installing your handler:
For your handler to be found, it needs to have the appropriate
entries in the registration database.
Compression DLLs
When you call AVIMakeCompressedStream, you pass in a PAVISTREAM and
are returned another PAVISTREAM. This new stream can be used in two
ways: either you can read from the stream, in which case you will
read data which is compressed from the original stream, or you can
write to the new stream, in which case the data you write will be
compressed and written to the original stream.
To use the "read" method, you would use the following sequence of
calls: (extra parameters left out because I can't remember them at
the moment)
AVIFileOpen(&pf, "foo.avi",...)
AVIFileGetStream(pf, &ps, ...)
AVIMakeCompressedStream(ps, &psC, &options, ...)
AVIStreamReadFormat(psC, lpFormatC, &cbFormatC) // get compressed format
for (loop through frames)
AVIStreamRead(psC, frame, ....) // read compressed frames
To use the "write" method:
AVIFileOpen(&pf, "foo.avi", OF_CREATE | OF_WRITE...)
AVIFileCreateStream(pf, &ps, &strhdr, ....)
AVIMakeCompressedStream(ps, &psU, &options, ...)
AVIStreamSetFormat(psU, lpFormatU, cbFormatU) // set format of data
// to compress
for (loop through frames)
AVIStreamWrite(psU, frame, ....) // write uncompressed frames,
// which will be compressed and
// written to the file
Using the Clipboard functions
The clipboard functions are easy. To copy a bunch of streams to
the clipboard, call AVIMakeFileFromStreams to bundle them up into a
single PAVIFILE, then call AVIPutFileOnClipboard. To get data off of
the clipboard, call AVIGetFromClipboard. To see whether any data is
present on the clipboard, for enabling menus or such, you can just
call AVIGetFromClipboard to see if it returns anything, and release
any file it returns.