mkvtoolnix  32.0.0
About: MKVToolNix is a set of tools to create, alter and inspect Matroska files (the open standard audio/video multimedia container format).
  Fossies Dox: mkvtoolnix-32.0.0.tar.xz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

Some Fossies usage hints in advance:

  1. To see the Doxygen generated documentation please click on one of the items in the "quick index" bar above or use the side panel at the left which displays a hierarchical tree-like index structure and is adjustable in width.
  2. If you want to search for something by keyword rather than browse for it you can use the client side search facility (using Javascript and DHTML) that provides live searching, i.e. the search results are presented and adapted as you type in the Search input field at the top right.
  3. Doxygen doesn't incorporate all member files but just a definable subset (basically the main project source code files that are written in a supported language). So to search and browse all member files you may visit the Fossies mkvtoolnix-32.0.0.tar.xz contents page and use the Fossies standard member browsing features (also with source code highlighting and additionally with optional code folding).
mkvtoolnix Documentation

Introduction

librmff is short for 'RealMedia file format access library'. It aims at providing the programmer an easy way to read and write RealMedia files. It does not contain any codecs for audio/video handling.

You can find a description of the RealMedia file format at http://wiki.multimedia.cx/index.php?title=RealMedia

License

The library was written by Moritz Bunkus morit.nosp@m.z@bu.nosp@m.nkus..nosp@m.org. It is licensed under the terms of the GNU Lesser General Public License (GNU LGPL) which can be found in the file COPYING.

Usage

Here are very short samples of how to use the library.

Reading an existing file

Reading an existing file requires four steps: Opening the file, reading the headers, reading all the frames and closing the file.

Example:

rmff_frame_t *frame;
if (file == NULL) {
// Handle the error.
return;
}
// Output some general information about the tracks in the file.
// Now read all the frames.
while ((frame = rmff_read_next_frame(file, NULL)) != NULL) {
// Do something with the frame and release it afterwards.
}
}

Creating a new file

Creating a new file is a bit more complex. This library only provides a low level codec independant layer to the RealMedia file format.

Creating a new file involves the following step in this particular order:

  1. open a new file with RMFF_OPEN_MODR_WRITING,
  2. add track entries with rmff_add_track,
  3. write the headers with rmff_write_headers,
  4. write all the frames with rmff_write_frame,
  5. optionally write the indexes with rmff_write_index,
  6. fix all the headers with rmff_fix_headers and
  7. close the file with rmff_close_file.

Please note that the error handling is not shown in the following example:

rmff_track_t *track;
rmff_frame_t *frame;
track = rmff_add_track(file, 1); // Also create an index for this track.
// The track types etc are stored in the ::rmff_mdpr_t#type_specific_data
// It usually contains a ::real_audio_v4_props_t, ::real_audio_v5_props_t
// or ::real_video_props_t structures which have to be set by the
// calling application.
// After setting the structures:
while (!done) {
// Generate frames.
...
frame = rmff_allocate_frame(size, NULL);
rmff_write_frame(track, frame);
}

Memory handling

Generally librmff allocates and frees memory itself. You should never mess with pointers inside the structures directly but use the provided functions for manipulating it. There are two exceptions to this rule: the frame handling and the app_data pointers.

The app_data members in rmff_file_t and rmff_track_t are never touched by librmff and can be used by the application to store its own data.

The functions rmff_read_next_frame, rmff_release_frame and rmff_allocate_frame allow the application to provide its own buffers for storing the frame contents. librmff will not copy this memory further. It will read directly into the buffer or write directly from the buffer into the file.

Example:

rmff_frame_t *frame;
unsigned char *buffer,
int size;
while (1) {
// Get the next frame's size.
// Have we reached the end of the file?
if (size == -1)
break;
// Allocate enough space for this frame and let librmff read directly
// into it.
buffer = (unsigned char *)malloc(size);
// Now do something with the buffer. Afterwards release the frame.
// The buffer is still allocated. So free it now.
free(buffer);
}

Packed video frames

The RealVideo frames are not stored one-complete-frame in one packet (packet meaning one 'frame' used by rmff_write_frame and returned by rmff_read_next_frame). They are split up into several sub packets. However, the Real decoder libraries usually need a completely assembled frame that contains all sub packets along with the offsets to each sub packet in the complete frame.

librmff can make the developper's life easier because it provides the function rmff_write_packed_video_frame that will split up such an assembled packet into all the sub packets and write those automatically, and two functions that assemble sub packets into such a packed frame (rmff_assemble_packed_video_frame and rmff_get_packed_video_frame).

Bitstream format

There are three layouts for how the bitstream for such a sub packet looks like which depends on the first two bits.

  1. For AA = 00 and AA = 10:
    AABBBBBB BCCCCCCC DEFFFFFF FFFFFFFF (GGGGGGGG GGGGGGGG) HIJJJJJJ JJJJJJJJ (KKKKKKKK KKKKKKKK) LLLLLLLL
  2. For AA = 01:
    AABBBBBB BCCCCCCC
  3. For AA = 11:
    AABBBBBB DEFFFFFF FFFFFFFF (GGGGGGGG GGGGGGGG) HIJJJJJJ JJJJJJJJ (KKKKKKKK KKKKKKKK) LLLLLLLL
  • A, two bits: Sub packet type indicator
    • 00 partial frame
    • 01 whole frame. If this is the case then only the bits A, B and C are present. In all the other cases the other bits are present as well.
    • 10 last partial frame
    • 11 multiple frames
  • B, seven bits: number of sub packets in the complete frame
  • C, seven bits: current sub packet's sequence number starting at 1
  • D, one bit: unknown
  • E, one bit: If set the G bits/bytes are not present.
  • F, 14 bits: The complete frame's length in bytes. If E is NOT set then the total length is (F << 16) | G, otherwise G is not present and the total length is just F.
  • H, one bit, unknown
  • I, one bit: If set the L bits/bytes are not present.
  • J, 14 bits: The current packet's offset in bytes. If J is NOT set then the offset is (J << 16) | K, otherwise K is not present and the offset is just J. Note that if AA is 10 then the offset is to be interpreted from the end of the of the complete frame. In this case it is equal to the current sub packet's length.
  • L, 8 bits: The current frame's sequence number / frame number % 255. Can be used for detecting frame boundaries if the sub packaging has failed or the stream is broken.
  • The rest is the video data.

Packed frame assembly example

Here's a short example how to use the packet assembly:

rmff_frame_t *raw_frame, *packed_frame;
rmff_track_t *track;
int result;
// Open the file, check the tracks.
while ((raw_frame = rmff_read_next_frame(file, NULL)) != NULL) {
track = rmff_find_track_with_id(file, raw_frame->id);
if (track->type != RMFF_TRACK_TYPE_VIDEO) {
// Handle audio etc.
} else {
if ((result = rmff_assemble_packed_video_frame(track, raw_frame)) < 0) {
// Handle the error.
} else {
while ((packed_frame = rmff_get_packed_video_frame(track)) != NULL) {
// Do something with the assembled frame and release it afterwards.
rmff_release_frame(packed_frame);
}
}
}
rmff_release_frame(raw_frame);
}
rmff_track_t::type
int type
Definition: librmff.h:502
rmff_fix_headers
int rmff_fix_headers(rmff_file_t *file)
Fixes some values in the headers and re-writes them.
Definition: rmff.c:1229
rmff_read_next_frame
rmff_frame_t * rmff_read_next_frame(rmff_file_t *file, void *buffer)
Reads the next frame from the file.
Definition: rmff.c:804
rmff_get_packed_video_frame
rmff_frame_t * rmff_get_packed_video_frame(rmff_track_t *track)
Retrieve an assembled video frame.
Definition: rmff.c:1873
rmff_write_frame
int rmff_write_frame(rmff_track_t *track, rmff_frame_t *frame)
Writes the frame contents to the file.
Definition: rmff.c:1345
rmff_release_frame
void rmff_release_frame(rmff_frame_t *frame)
Frees all resources associated with a frame.
Definition: rmff.c:883
rmff_file_t
Definition: librmff.h:514
rmff_read_headers
int rmff_read_headers(rmff_file_t *file)
Reads the file and track headers.
Definition: rmff.c:575
rmff_frame_t
Definition: librmff.h:472
rmff_open_file
rmff_file_t * rmff_open_file(const char *path, int mode)
Opens a RealMedia file for reading or writing.
Definition: rmff.c:438
RMFF_ERR_OK
#define RMFF_ERR_OK
No error has occured.
Definition: librmff.h:538
rmff_add_track
rmff_track_t * rmff_add_track(rmff_file_t *file, int create_index)
Creates a new track for a file.
Definition: rmff.c:941
compute-powers.result
result
Definition: compute-powers.py:18
RMFF_TRACK_TYPE_VIDEO
#define RMFF_TRACK_TYPE_VIDEO
The track contains video data.
Definition: librmff.h:496
rmff_frame_t::id
uint16_t id
The track ID this frame belongs to. This will be overwritten in rmff_write_frame.
Definition: librmff.h:483
rmff_allocate_frame
rmff_frame_t * rmff_allocate_frame(uint32_t size, void *buffer)
Allocates a frame and possibly a buffer for its contents.
Definition: rmff.c:863
rmff_write_index
int rmff_write_index(rmff_file_t *file)
Creates an index at the end of the file.
Definition: rmff.c:1433
buffer
internal::basic_buffer< FMT_CHAR(S)> buffer
Definition: printf.h:757
RMFF_OPEN_MODE_READING
#define RMFF_OPEN_MODE_READING
Open the file for reading.
Definition: librmff.h:560
internal::basic_buffer
Definition: core.h:215
file
Definition: posix.h:188
rmff_close_file
void rmff_close_file(rmff_file_t *file)
Close the file and release all resources.
Definition: rmff.c:481
rmff_find_track_with_id
rmff_track_t * rmff_find_track_with_id(rmff_file_t *file, uint16_t id)
Finds the track the track ID belongs to.
Definition: rmff.c:1417
rmff_get_next_frame_size
int rmff_get_next_frame_size(rmff_file_t *file)
Retrieves the size of the next frame.
Definition: rmff.c:765
rmff_track_t
Definition: librmff.h:500
RMFF_OPEN_MODE_WRITING
#define RMFF_OPEN_MODE_WRITING
Create a new file.
Definition: librmff.h:562
rmff_write_headers
int rmff_write_headers(rmff_file_t *file)
Writes the file and track headers.
Definition: rmff.c:1164
rmff_assemble_packed_video_frame
int rmff_assemble_packed_video_frame(rmff_track_t *track, rmff_frame_t *frame)
Parses a sub packet and attempts to assemble a packed video frame.
Definition: rmff.c:1724