shounen.ruДокументация • OGM
ВcтуплениеОписание (html)Описание (txt)Пример навигационной программы (ANSI C)ZIP

Описание формата OGM

Что есть в этом документе

Формат OGM-файла, принципы объединения нескольких элементарных потоков в один физический файл, структура заголовков аудио, видео и текстовых потоков.

Чего в этом документе нет

Структры данных внутри аудио, видео и текстовых потоков.

Вступление

Некоторое время назад, на смену формата mp3 был создан формат OGG Vorbis. Для хранения звукового потока vorbis был разработан стандарт OGG Bitstream, который в дальнейшем применили для хранения видео.

1. Порядок бит и байт.

Порядок бит в байте: 01234567 (другими словами, последний, правый бит имеет макисмальное значение) Порядок байт при записи многобайтовых чисел: 0123 (0xAB 0xCD 0xEF 0x12 в файле означают число 0x12EFCDAB) (little-endian)

2. Основные концепции.

  1. Логический поток — данные одного типа (например, видео-поток, первый аудио-поток, второй аудио-поток)
  2. Пакет — порция данных логического потока (его структура целиком и полностью лежит на совести кодера/декодера).
  3. Сегмент — кусок данных длиной в 255 байт (и менее) длиной. Сегмент с нулевой длиной так же допустим. У сегмента так же нет ни заголовка ни каких-либо данных помимо содержимого (content'а).
  4. Страница — несколько сегментов с заголовком страницы.
  5. Физический поток — объединение нескольких логических потоков. OGM-файл и представляет из себя этот самый физический поток.

3. Методы объединения страниц нескольких логических потоков внутри одного физического потока

Chaining (объединение по цепочке)

stream1stream2stream3

Grouping (чередование)

page1page1page1page2page3page2page2page3page4...

(В случае AVI-файла это называют interleave)

У каждого логического потока есть признаки начала потока (Begin of Stream, BoS) и конца потока (End of Stream, EoS). Эти признаки обозначаются флагами в заголовке страницы. (BoS - в первой странице логического потока, EoS — в последней). Соответственно, в физическом потоке может быть несколько BoS и EoS. (в случае одного видео и двух аудио, например, три BoS и три EoS).

В случае нескольких логических потоков внутри физического, все страницы с BoS (т.е. "начала логических потоков") должны быть расположены до первой страницы без флага BoS.

Порядок чередования страниц из разных логических потоков может быть произвольным, гарантируется только, что для каждого логического потока страницы расположены в хронологическом порядке (т.е. N-ая страница будет расположена в файле всегда позже, чем N-1).

В случае смешанного типа объединения (т.е. и Chaining'a и Grouping'а) все EoS (последние) страницы первой группы должны появиться до первой (BoS) страницы второй группы.

4. Структуры пакета, сегмента и страницы

Структура пакета, как было уже сказано выше, целиком и полностью определяется декодером.

Пакет режется в несколько сегментов.

Сегмент так же не имеет собственной структруры. По длинне он должен быть не более 255 байт (в частности, сегмент может быть нулевой длины, т.е. не содержать в себе информации).

Сегменты объединяются в страницы, к ним добавляется заголовок страницы. (не более 255 сегментов в странице)

Примечания

5. Заголовок страницы (page_header)

смещениеразмер типимя, значение, комментарии
0x0 4 FourCC capture_pattern, 'OggS', 0x4f 0x67 0x67 0x53
0x4 1 ? должна быть 0, версия структуры заголовка
0x5 1 bitfield header_type_flag,
0x1 — страница содержит продолжение пакета
0x2 — BoS (Begin of Stream, начало потока)
0x4 — EoS (End of Stream, конец потока)
0x6 8 int64 absolute_granule_position, номер последнего сэмпла/фрейма целиком закодированного в этом пакете (сэмплы, закодированные в пакете, который не умещается в эту страницу, а продолжаются дальше, не засчитываются). Число -1 означает что в указанной странице нет целиком закодированных сэмплов.
N.B. little-endian формат числа (как у Интела)
0xE 4 int32 page_serial_number, номер логического потока в указанном физическом потоке. Должно быть уникальным в рамках одного физического потока для всех логических.
0x12 4 int32 Page_sequence_no, порядковый номер страницы в логическом потоке.
0x16 4 uint32 Page_checksum, CRC код страницы
0x1A 1 byte page_segments, число сегментов в странице, диапазон значений [0-255] (0 и 255 допустимы)
0x1B * byte[] segment_table, таблица размеров сегментов в странице. Количество записей в таблице определяется page_segment, в случае нулевого значения, segment_table отсутствует.

Замечания

6. Определение размера сегмента и данных

размер данных в сегменте: сумма всех значений в segment_table. Количество значений указано в page_segments.

размер сегмента: 0x1B+page_segments+сумма всех значений segment_table. (это значение всегда меньше 64k).

7. Стуктура заголовка видео-потока

смещениетипимя, значение, комментарии
0x0 char тип пакета, для заголовка должен быть 0x1
0x1 char[8] streamtype, для видео должен быть 'video   ' последние три символа — 0x0 (не пробелы)
0x9 char[4] subtype, используемый кодек (FourCC)
0xD int32 размер структуры
0x11 int64 time_unit, интервал времени между "юнитами", в 1/10000000 секунды
0x19 int64 samples_per_unit, кадров в "юнит". fps=10000000*samples_per_unit/time_unit
0x21 int32 default_len (честно, не знаю что такое, обычно равно 1)
0x25 int32 buffersize — размер необходимого буфера для декодирования
0x29 int32 bit_per_sample, глубина цвета (битов на пиксел) N.B. В оригинальной спецификации указано, что эта величина - int16, но практика показывает, что всё-таки int32.
0x2D int32 width, ширина картинки (в пикселах)
0x31 int32 Heigth, высота картинки (в пикселах)

8. Стурктура заголовка аудио-потока (для vorbis-audio)

смещениетипимя, значение, комментарии
0x0 byte тип пакета, для заголовка должен быть 0x1
0x1 char[6] для vorbis-audio должен быть 'vorbis'
0x7 int32 vorbis version, в настоящий момент 0.
0xB byte число каналов
0xC int32 частота дискретизации сигнала
0x10 int32 минимальный битрейт (обычно 0)
0x14 int32 средний битрейт
0x18 int32 макисмальный битрейт (обычно 0)
0x1C byte размеры блоков для декодирования (экспонента двойки)
старшие 4 бита - для blocksize_0
младшие 4 бита - для blocksize_1
0x1D byte младший бит - framing_flag

9. Стуктура заголовка текстового потока

смещениетипимя, значение, комментарии
0x0 byte тип пакета, для заголовка должен быть 0x1
0x1 char[8] тип потока, для текста должен быть 'text ' (последние четыре символы не пробелы, а 0x0)
0x9 char [4] subtype, для текста 0.
0xD int32 размер структуры
0x11 int64 длительность отсчёта (для текста 1мс, 0x2710)
0x19 int64 всегда 1
0x21 int32 default_len, 1.
0x25 int32 увы, назначения не знаю (обычно или 96 или 60)
0x29 4 x int32 unknown, usually 0.

10. Комментарии

Каждый поток может иметь комментарии. Они обычно находятся во второй или третьей странице потока.

N.B. в комментариях строки не являются классическими C string'ами (ASCIIZ), и НЕ заканчиваются нулевым байтом. Строка состоит из размера (4 байта) и самой строки (что-то вроде строк в Pascal).

Структура заголовка коментария

смещениетипимя, значение, комментарии
0x0 byte тип пакета, для комментария должен быть 0x3
0x1 int32 vendor_vector_size
0x5 byte[] название софта, создавшего файл
??? int32 user_comment_list_length, количество комментариев

После заголовка следуют сами комментари.

Каждый комментарий состоит из 4байтного поля размера строки и самой строки.

Внутри каждая строка выглядит примерно так:

field_name=field_value

При этом название field_name регистронезависимое, и состоит только из ASCII7.

Точнее (цитирую спецификацию):

The field_name is case-insensitive and may consist of ASCII 0x20 through 0x7D, 0x3D ('=') excluded. ASCII 0x41 through 0x5A inclusive (characters A-Z) is to be considered equivalent to ASCII 0x61 through 0x7A inclusive (characters a-z).

Значение поля (field_value) представяет из себя UTF-8 строку без заключительного 0.

В случае, если комментарии отсутствуют (user_comment_list_length=0), то, соответствено, списка комментариев нет.

В конце после списка комментариев (или даже в случае отсутствия такого списка) следует байт 0x1 (framing_bit), его отстутствие — признак повреждённой страницы.

Названия полей могут быть произвольные, могут повторяться (т.е. например, три строки вида AUTHOR=...).

Примерный список возможных названий полей

(список не полный)

11. Пример кода, работающего с OGM файлом

Код находится в файле ogmnav.c

Замечания к коду:

12. Ссылки на ресурсы

13. Заключение, копирайты

Использование статьи для разработчиков, в т.ч. для написания коммерческого софта абсолютно свободное. Публикация на web-сайтах и в бумажных изданиях возможна при сохранении явно указанного авторства и ссылок, приведённых в статье (при условии их действительности на момент публикации).

Если вы заметили в статье грамматическую, синтаксическую, логическую ошибку, опечатку, неточность, имеете уточнённые данные по значению полей, отмеченных вопросительными знаками, хотите добавить линк в список ресурсов, пишите на указанный адрес.

© George Shuklin,2004 gs@shounen.ru, shounen.ru .