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.
222 lines
6.7 KiB
222 lines
6.7 KiB
4 years ago
|
avilib: Reading and writing avi files
|
||
|
=====================================
|
||
|
|
||
|
Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
|
||
|
|
||
|
avilib is a open source library for dealing with AVI
|
||
|
files under Linux or other UNIX operating systems.
|
||
|
|
||
|
It provides a framework for extracting or adding raw
|
||
|
audio and single raw (=compressed) frames from/to AVI Files.
|
||
|
|
||
|
It does not deal with any compression issues which have to be
|
||
|
handled on a higher level by the user of avilib.
|
||
|
|
||
|
AVI files may have several video and audiotracks.
|
||
|
|
||
|
avilib writes only one video track and (optionally) one
|
||
|
audio track and also extracts only the first video and audio
|
||
|
track (but input files may contain more than one track, the others
|
||
|
just being ingored).
|
||
|
|
||
|
The interface to avilib is kept similar to the quicktime4linux interface
|
||
|
(by Adam Williams) with the following important differences:
|
||
|
|
||
|
- since only the first track of video and audio is considered,
|
||
|
there is no track argument in any of the routines.
|
||
|
|
||
|
- audio is generally considered as a byte stream and therefore
|
||
|
all size arguments used in reading/writing audio are in bytes
|
||
|
and not in samples.
|
||
|
|
||
|
- as mentioned above, there are no routines dealing with compression issues.
|
||
|
|
||
|
|
||
|
Compiling:
|
||
|
==========
|
||
|
|
||
|
Since the library consists only of one c source file, I have not provided
|
||
|
a Makefile or similar, just compile with
|
||
|
|
||
|
cc -c <your favorite options> avilib.c
|
||
|
|
||
|
|
||
|
Portability:
|
||
|
============
|
||
|
|
||
|
AVI-Files use little endian numbers throughout the file, I have tried
|
||
|
to read/write these numbers in a way which doesn't depent on endianness.
|
||
|
This library should therefore also be useable on big endian machines.
|
||
|
This feature is not so heavily tested, however.
|
||
|
|
||
|
|
||
|
Usage:
|
||
|
======
|
||
|
|
||
|
Basics, opening, closing
|
||
|
------------------------
|
||
|
|
||
|
Include "avilib.h" in your source and declare a pointer:
|
||
|
|
||
|
avi_t *avifile;
|
||
|
|
||
|
Open the AVI file with:
|
||
|
|
||
|
avifile = AVI_open_input_file("xxx.avi",1);
|
||
|
|
||
|
or
|
||
|
|
||
|
avifile = AVI_open_output_file("xxx.avi");
|
||
|
|
||
|
You may either only read from the input file (leaving it unchanged)
|
||
|
or create a completly new AVI file. There is no editing or append
|
||
|
mode available.
|
||
|
|
||
|
Both routines will either return a pointer to avi_t or a zero pointer
|
||
|
in the case of an error.
|
||
|
|
||
|
For closing the file, use:
|
||
|
|
||
|
int AVI_close(avi_t *AVI);
|
||
|
|
||
|
Files you have written MUST be closed (the header is written at close time),
|
||
|
else they will not be readable by any other software.
|
||
|
|
||
|
Files opened for reading should be closed to free the file descriptor
|
||
|
and some data (unless your program is finishing anyway).
|
||
|
|
||
|
|
||
|
Error handling:
|
||
|
---------------
|
||
|
|
||
|
Most routines (besides open/close) will return 0 or a usefull number if successfull
|
||
|
and a -1 in the case of an error. If an error occured, the external variable
|
||
|
AVI_errno is set. See avilib.h for the meaning of the error codes in AVI_errno.
|
||
|
|
||
|
There is also a routine (which acts like perror) to output a description
|
||
|
of the last error to stderr:
|
||
|
|
||
|
AVI_print_error(char *str)
|
||
|
|
||
|
|
||
|
|
||
|
Reading from an AVI file:
|
||
|
-------------------------
|
||
|
|
||
|
After opening the file, you can obtain the parameters of the AVI
|
||
|
with the following routines:
|
||
|
|
||
|
long AVI_video_frames(avi_t *AVI);
|
||
|
number of video frames in the file
|
||
|
|
||
|
int AVI_video_width(avi_t *AVI);
|
||
|
int AVI_video_height(avi_t *AVI);
|
||
|
width and height of the video in pixels
|
||
|
|
||
|
double AVI_frame_rate(avi_t *AVI);
|
||
|
frame rate in frames per second, notice that this is a double value!
|
||
|
|
||
|
char* AVI_video_compressor(avi_t *AVI);
|
||
|
string describing the compressor
|
||
|
|
||
|
int AVI_audio_channels(avi_t *AVI);
|
||
|
number of audio channels, 1 for mono, 2 for stereo, 0 if no audio present
|
||
|
|
||
|
int AVI_audio_bits(avi_t *AVI);
|
||
|
audio bits, usually 8 or 16
|
||
|
|
||
|
int AVI_audio_format(avi_t *AVI);
|
||
|
audio format, most common is 1 for raw PCM, look into avilib.h for others
|
||
|
|
||
|
long AVI_audio_rate(avi_t *AVI);
|
||
|
audio rate in samples/second
|
||
|
|
||
|
long AVI_audio_bytes(avi_t *AVI);
|
||
|
total number of audio bytes in the file
|
||
|
|
||
|
|
||
|
In order to read the video frame by frame, use
|
||
|
(frame numbers are starting from 0 !!!!!)
|
||
|
|
||
|
long AVI_frame_size(avi_t *AVI, long frame);
|
||
|
to get the size of frame with number "frame"
|
||
|
|
||
|
long AVI_read_frame(avi_t *AVI, char *vidbuf);
|
||
|
to read the next frame (frame posittion is advanced by 1 after the read)
|
||
|
|
||
|
int AVI_seek_start(avi_t *AVI);
|
||
|
int AVI_set_video_position(avi_t *AVI, long frame);
|
||
|
to position in the AVI file
|
||
|
(for reading the frames out of order)
|
||
|
|
||
|
|
||
|
Read audio with
|
||
|
|
||
|
int AVI_set_audio_position(avi_t *AVI, long byte);
|
||
|
to position to an arbitrary byte position within the audio stream
|
||
|
|
||
|
long AVI_read_audio(avi_t *AVI, char *audbuf, long bytes);
|
||
|
to actually read "bytes" number of audio bytes.
|
||
|
the audio position is advanced by "bytes", so there is no
|
||
|
need to reposition before every call when reading in order.
|
||
|
|
||
|
|
||
|
Avoiding lengthy index searches:
|
||
|
--------------------------------
|
||
|
|
||
|
When opening the AVI file, avilib looks if the file has an index attached
|
||
|
and if this is not the case, it creates one by reading through the whole file.
|
||
|
|
||
|
If you want to read through the file only once, creation of an index is
|
||
|
not necessary in that case. You may use AVI_open_input_file with the second
|
||
|
argument set to 0 and then use AVI_read_data for readin through the file.
|
||
|
|
||
|
Look to the source for the arguments of AVI_read_data.
|
||
|
|
||
|
|
||
|
Writing to an AVI file:
|
||
|
-----------------------
|
||
|
|
||
|
After you have opened the file, use the following routines to set
|
||
|
the properties of the AVI file:
|
||
|
|
||
|
void AVI_set_video(avi_t *AVI, int width, int height, double fps, char *compressor);
|
||
|
void AVI_set_audio(avi_t *AVI, int channels, long rate, int bits, int format);
|
||
|
|
||
|
with:
|
||
|
|
||
|
width, height width and height of the video in pixels
|
||
|
|
||
|
fps frame rate in frames per second, notice that this is a double value!
|
||
|
|
||
|
compressor string describing the compressor
|
||
|
|
||
|
channels number of audio channels, 1 for mono, 2 for stereo, 0 if no audio present
|
||
|
|
||
|
rate audio rate in samples/second
|
||
|
|
||
|
bits audio bits, usually 8 or 16, 0 if no audio present
|
||
|
|
||
|
format audio format, most common is 1 for raw PCM, look into avilib.h for others
|
||
|
|
||
|
|
||
|
to write video frames or audio, use:
|
||
|
|
||
|
int AVI_write_frame(avi_t *AVI, char *data, long bytes);
|
||
|
int AVI_write_audio(avi_t *AVI, char *data, long bytes);
|
||
|
|
||
|
there is also a feature to duplicate the index entry of the last
|
||
|
frame without writing the data again to the file, this should
|
||
|
used with care since I don't know if all AVI players can handle
|
||
|
the resulting file (xanim can do it!):
|
||
|
|
||
|
int AVI_dup_frame(avi_t *AVI);
|
||
|
|
||
|
AVI files have a 2 GB limit (as has the Linux ext2 file system),
|
||
|
avilib will return an error if you try to add more data to the file
|
||
|
(and it cares that the file still can be correctly closed).
|
||
|
If you want to check yourself how far you are away from that limit
|
||
|
(for example to synchronize the amount of audio and video data) use:
|
||
|
|
||
|
long AVI_bytes_remain(avi_t *AVI);
|