MKV(Matroska)
Video 및 Audio stream을 저장하는데 사용하는 동영상 컨테이너 포맷으로 EBML(Extensible Binary Meta Language)을 기반으로 만들어져 있다.
EBML (ISO Base Media File Format)
EBML의 기본 구성 단위는 Element이다. Element는 다음과 같은 구성으로 이루어져있다.
+------------+--------------+--------------+
| Element ID | Element Size | Element Data |
+------------+--------------+--------------+
MP4에서 쓰이는 박스에 대해서 아는 분이라면 이와 매우 유사한 구조임을 알 수 있다.
하지만 Element ID 및 Element Size가 fixed된 4 Byte의 크기를 차지하지 않는다는 점이 다르다.
Element ID 및 Element Size는 아래와 같이 표현된다.
Element ID
bits, big-endian
1xxx xxxx - Class A IDs (2^7 -1 possible values) (base 0x8X)
01xx xxxx xxxx xxxx - Class B IDs (2^14-1 possible values) (base 0x4X 0xXX)
001x xxxx xxxx xxxx xxxx xxxx - Class C IDs (2^21-1 possible values) (base 0x2X 0xXX 0xXX)
0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - Class D IDs (2^28-1 possible values) (base 0x1X 0xXX 0xXX 0xXX)
Element Size
bits, big-endian
1xxx xxxx - value 0 to 2^7-2
01xx xxxx xxxx xxxx - value 0 to 2^14-2
001x xxxx xxxx xxxx xxxx xxxx - value 0 to 2^21-2
0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^28-2
0000 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^35-2
0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^42-2
0000 001x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^49-2
0000 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^56-2
때문에 Element ID 및 Element Size가 얼만큼의 크기를 가지는지는 처음 1이 출력되는 위치에 따라 정의되고 이를 통해 Element를 읽어낼 수 있다.
한편 MP4에서 Box안에 Box가 Data로 들어갈 수 있듯이 Mkv에서도 Element Data안에 Element가 위치 할 수 있다.
MKV physical Structure
MKV File은 큰 2개의 Element, EBML Header 및 Segment 의 합으로 이루어져있다.
+-------------+
| EBML Header |
+---------------------------+
| Segment | SeekHead |
| |-------------|
| | Info |
| |-------------|
| | Tracks |
| |-------------|
| | Chapters |
| |-------------|
| | Cluster |
| |-------------|
| | Cues |
| |-------------|
| | Attachments |
| |-------------|
| | Tags |
+---------------------------+
EBML Header에는 현재 파일의 DocType에 대한 정보가 주를 이루고 있으며 영상과 관련된 정보는 Segment에 속한다. Segment는 다시 SeekHead, Info, Tracks, Chatpers, Cluster, Cues, Attachments, Tags의 Element로 이루어지는데 각각 다음과 같은 정보를 담고 있다.
- SeekHead: 다른 Element(Info, Tracks, Chapters …)의 위치 정보를 담고 있다.
- Info: Segment에 대한 general information을 포함
- Tracks: 여러 Track에 대한 정보
- Chapters: basic menu나 partition data를 설정하는데 사용 (ex. 동영상 책갈피 기능)
- Cluster: 실제로 동영상 데이터가 들어있는 영역
- Cues: 동영상 seek기능을 위해 존재하는 영역
- Attachements: 첨부 파일
- Tags: Metadata 영역
각각의 Element는 또 다른 Element로 구성되어 있다. 이에 대한 상세한 설명은 spec에서 확인 할 수 있다.
Example
그렇다면 실제로 mkv파일을 통해 구조를 확인해보자. 위의 sample_video파일을 hex(왼쪽) 및 binary(오른쪽)로 열면 아래와 같다.
오른쪽의 binary파일을 확인해보면 class D에 해당하는 Element ID를 가짐을 확인할 수 있고 이에 따라 [1A][45][DF][A3] 이 Element ID가 된다 이를 spec페이지에서 확인하면 EBML Header의 ID와 일치한다.
이어서 Size도 같은 방식으로 확인해보면 35bytes가 EBML Header의 Data크기임을 확인 할 수 있으며, 이 영역에 EBML Header의 정보가 담겨있음을 확인해 볼 수 있다. 이제 EBML Header Data영역에서 첫 번째 Element ID를 찾으면 spec페이지의 EBML Version ID와 일치함을 확인 할 수 있다. 같은 방식으로 Size를 확인하면 1byte의 영역이 Data임을 확인 할 수 있고, Data 영역을 통해 EBML Version이 1임을 확인 할 수 있다.
이와 같은 방식으로 sample_video를 쭉 분석해보면 대략적으로 아래와 같은 정보가 포함되어 있음을 확인 할 수 있다.
- EBML Header ID: 1A 45 DF A3
- EBML Header Size: 01 00 00 00 00 00 00 23
- EBML Header Data:
- EBMLVersion ID: 42 86
- EBMLVersion Size: 81
- EBMLVersion Data: 01
- EBMLReadVersion ID: 42 F7
- EBMLReadVersion Size: 81
- EBMLReadVersion Data: 01
- EBMLMaxIDLength ID: 42 F2
- EBMLMaxIDLength Size: 81
- EBMLMaxIDLength Data: 04
- EBMLMaxSizeLength ID: 42 F3
- EBMLMaxSizeLength Size: 81
- EBMLMaxSizeLength Data: 08
- DocType ID: 42 82
- DocType Size: 88
- DocType Data: 6D 61 74 72 6F 73 6B 61
- DocTypeVersion ID: 42 87
- DocTypeVersion Size: 81
- DocTypeVersion Data: 04
- DocTypeReadVersion ID: 42 85
- DocTypeReadVersion Size: 81
- DocTypeReadVersion Data: 02
- Segment ID: 18 53 80 67
- Segment Size: 01 00 00 00 02 47 90 7B
- Segment Data :
- SeekHead ID: 11 4D 9B 74
- SeekHead Size: 40 43
- SeekHead Data:
- CRC-32 ID: BF
- CRC-32 Size: 84
- CRC-32 Data: 4A FD E8 91
- Seek ID: 4D BB
- Seek Size: 8B
- Seek Data:
- SeekID ID: 53 AB
- SeekID Size: 84
- SeekID Data: 15 49 A9 66 (Info ID)
- SeekPosition ID: 53 AC
- SeekPosition Size: 81
- SeekPoistion Data: E5
- Seek ID: 4D BB
- Seek Size: 8C
- Seek Data:
- SeekID ID: 53 AB
- SeekID Size: 84
- SeekID Data: 16 54 AE 6B (Tracks ID)
- SeekPosition ID: 53 AC
- SeekPosition Size: 82
- SeekPosition Data: 01 3C
- Seek ID: 4D BB
- Seek Size: 8C
- Seek Data:
- SeekID ID: 53 AB
- SeekID Size: 84
- SeekID Data: 12 54 C3 67 (Tags ID)
- SeekPosition ID: 53 AC
- SeekPosition Size: 82
- SeekPosition Data: 01 D3
- Seek ID: 4D BB
- Seek Size: 8E
- Seek Data:
- SeekID ID: 53 AB
- SeekID Size: 84
- SeekID Data: 1C 53 BB 6B (Cues ID)
- SeekPosition ID: 53 AC
- SeekPosition Size: 84
- SeekPosition Data: 02 47 90 31
- Void ID: EC
- Void Size: 01 00 00 00 00 00 00 93
- Void Data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- Info ID: 15 49 A9 66
- Info Size: 01 00 00 00 00 00 00 4B
- Info Data:
- CRC-32 ID: BF
- CRC-32 Size: 84
- CRC-32 Data: DC 4D 77 8B
- TimecodeScale ID: 2A D7 B1
- TimecodeScale Size: 83
- TimecodeScale Data: 0F 42 40
- MuxingApp ID: 4D 80
- MuxingApp Size: 8D
- MuxingApp Data: 4C 61 76 66 35 37 2E 38 33 2E 31 30 30
- WritingApp ID: 57 41
- WritingApp Size: 8D
- WritingApp Data: 4C 61 76 66 35 37 2E 38 33 2E 31 30 30
- SegmentUID ID: 73 A4
- SegmentUID Size: 90
- SegmentUID Data:
- CodecID ID: 86
- CodecID Size: D2
- CodecID Data: 8C 51 43 E4 80 9D
- Tracks ID: 16 54 AE 6B
- Tracks Size: 01 00 00 00 00 00 00 8B
- Tracks Data:
- CRC-32 ID: BF
- CRC-32 Size: 84
- CRC-32 Data: 8A 1C 69 A7
- TrackEntry ID: AE
- TrackEntry Size: 01 00 00 00 00 00 00 7C
- TrackEntry Data:
- TrackNumber ID: D7
- TrackNumber Size: 81
- TrackNumber Data: 01
- TrackUID: 73 C5
- TrackUID Size: 81
- TrackUID Data: 01 …
- Tags ID: 12 54 C3 67
- Tags Size: 01 00 00 00 00 00 01 66
- Tags Data:
- CRC-32 ID: BF
- CRC-32 Size: 84
- CRC-32 Data: 94 6E ED 2E
- Tag ID: 73 73
- Tag Size: 01 00 00 00 00 00 00 9C
- Tag Data:
- Targets ID : 63 C0
- Targets Size: 01 00 00 00 00 00 00 00
- SimpleTag ID : 67 C8
- SimpleTag Size: 01 00 00 00 00 00 00 15
- SimpleTag Data:
- TagName ID: 45 A3
- TagName Size: 8B
- TagName Data: 4D 41 …
- Cluster ID: 1F 43 B6 75
- Cluster Size: 01 00 00 00 00 51 E1 4F
- Cluster Data:
- CRC-32 ID: BF
- CRC-32 Size: 84
- CRC-32 Data: 72 D9 28 A7
- Timecode ID: E7
- Timecode Size: 81
- Timecode Data: 00
- SimpleBlock ID: A3
- SimpleBlock Size: 26 34 C6
- SimpleBlock Data: 81 00 00 80 00 00 02 …
- Cues ID: 1C 53 BB 6B
- Cues Size: 01 00 00 00 00 00 00 3E
- Cues Data:
- CRC-32 ID: BF
- CRC-32 Size: 84
- CRC-32 Data: 1F BF 5B 48
- CuePoint ID: BB
- CuePoint Size: 8F
- CuePoint Data:
- CueTime ID: B3
- CueTime Size: 81
- CueTime Data: 00
- CueTrackPositions ID: B7
- CueTrackPositions Size: 8A
- CueTrackPositions Data:
- CueTrack ID: F7
- CueTrack Size: 81
- CueTrack Data: 01
- CueClusterPosition ID: F1
- CueCluster Size: 82
- CueCluster Data: 03 45
- CueRelativePositions ID: F0
- CueRelativePositions Size: 81
- CueRelativePoistions Data: 09
- CuePoint ID: BB …