Writing a file

The following commands are good for writing to a file.

Immediately after opening the file, set up some tracks to write with these commands:

quicktime_set_audio(quicktime_t *file, int channels, long sample_rate, int bits, char *compressor);
quicktime_set_video(quicktime_t *file, int tracks, int frame_w, int frame_h, float frame_rate, char *compressor);

Don't call the audio command if you don't intend to store any audio data. Some programs rely on an audio track for video timing. Likewise, don't call the video command if you're just going to save audio.

Notice the channels argument for audio channels but there is no argument for total audio tracks. For sanity reasons, the library only supports writing one audio track of any number of channels.

If you intend to use the library's built-in compression routines specify a compressor #define from quicktime.h as the compressor argument. If you want to write your own compression routine, specify any 4 byte identifier you want. The compressor applies to all tracks of the same media type, for sanity reasons.

Choose an audio compressor for the audio command and a video compressor for the video command. The library doesn't check for conflicting media types or whether a compressor you make up is legitimate.

Now you'll want to seek to any point in the file. Seeking works exactly as in reading, using the same commands, except if you seek to the middle of a file and write out data, you're going to cause a glitch in the playback data. It's virtually impossible to line up new frame boundaries with old frames since some codecs aren't linear and hardly anyone uses this library anyway.

Encoding video

The library generates compressed video frames from rows of unsigned RGB bytes. This depends on whether the compressor you passed to quicktime_set_video is supported in the library. First use

int quicktime_supported_video(quicktime_t *file, int track);

to find out if the codec for the track is in the library. This returns 1 if it is and 0 if it isn't supported. Then use

int quicktime_encode_video(quicktime_t *file, unsigned char **row_pointers, int track);

to compress the frame pointed to by **row_pointers, write it at the current position of the track and advance the current position. The return value is always 1 for failure and 0 for success.

Changing the colormodel

The quicktime_encode_video command can encode rows other than RGB. Before calling quicktime_encode_video call

int quicktime_writes_cmodel(quicktime_t *file, int colormodel, int track);

colormodels.h contains a set of colormodel #defines which supply the colormodel argument. The function returns True or False depending on if the colormodel argument is supported. BC_RGB888 is always supported.

Once you find a supported colormodel call

quicktime_set_cmodel(quicktime_t *file, int colormodel);

and then

quicktime_encode_video The row pointers must point to rows stored in the colormodel. Planar colormodels use only the first 3 row pointers, each pointing to one of the planes.

Encoding audio

The library also supports encoding certain audio codecs. Before writing a buffer of samples, try

int quicktime_supported_audio(quicktime_t *file, int track);

The track argument is really hypothetical here, since you should only pass 0 for it. If you get a TRUE return value, you are free to use

int quicktime_encode_audio(quicktime_t *file, QUICKTIME_INT16 **input_i, float **input_f, long samples);

to encode the sample buffer. Pass an array of buffers to either the QUICKTIME_INT16** or the float** argument, depending on what format your data is in. Pass a NULL to the undesired format. The array of buffers is one buffer of samples for each channel, all pointed to by an array. This means all the channels have to be written simultaneously. The return value is 0 on success.

Writing raw video

For writing raw data, you need to supply a buffer of data exactly as you intend the read operations to see it, with the encoding done, then call one of these functions to write it. For video, specify the number of bytes in the frame buffer and the track this frame belongs to. Video can only be written one frame at a time.

int quicktime_write_frame(quicktime_t *file, unsigned char *video_buffer, long bytes, int track);

Now some of you are going to want to write frames directly to a file descriptor using another library like libjpeg or something. For every frame start by calling quicktime_write_frame_init to initialize the output.

int quicktime_write_frame_init(quicktime_t *file, int track);

Then write your raw, compressed data to the file descriptor given by quicktime_get_fd.

FILE* quicktime_get_fd(quicktime_t *file);

End the frame by calling quicktime_write_frame_end.

int quicktime_write_frame_end(quicktime_t *file, int track);

Repeat starting at quicktime_write_frame_init for every frame.

Writing raw audio data

Writing audio involves writing the raw audio data exactly the way the read operations are going to see it, with channels interleaved and whatever else.

int quicktime_write_audio(quicktime_t *file, char *audio_buffer, long samples, int track);

The library automatically converts the sample count to the number of bytes of data in the buffer, based on channels and bits values you passed to quicktime_set_audio.

When you're done, call quicktime_close to close the file.

int quicktime_close(file);