Using MKVToolNix for HEVC Muxing

Who's ready to mux? To get started, visit the HEVC Support in MKV page to download the toolset you need to start muxing DivX HEVC video into MKV (binaries and our patched source code). By the time you get through this page, you should have a good understanding of how to use MKVToolNix to make it happen.

Download HEVC Bitstreams

First, you'll need some video streams:

Now let's see MKVToolNix in action!

Merge HEVC into MKV

After you download some of the streams (above), then...

mkvmerge --default-duration 0:24fps --aac-is-sbr 0:1 myVideoIn.hevc myAudioIn.aac -o myMuxedMovie.mkv

Extract to MKV

mkvextract tracks myMuxedMovie.mkv 0:myVideoOut.hevc 1:myAudioOut.aac

The above example is for one of the sample 720p showcase content, whose frame rate is 24. If you use mkvmerge with any other content, use the above command with corresponding file names and parameters.

Technical Details

The following section provides some technical details to help you understand our thinking around how HEVC could be stored within the Matroska multimedia container. Consider it a proposal and not a final spec, and please weigh in on our forums or join the discussion over on the Matroska Dev List.

Normative Reference(s)

Informative Reference(s)

Article Conventions

  • An Element will contain children and an Attribute will contain a data
  • ELEM(“name”) – Is used to explicitly denote as an element. e.g. ELEM(“Segment”)
  • ATTR(“name”) – Is used to explicitly denote as an attribute. e.g. ATTR(“CodecPrivate”)

How it is marked as HEVC?

The Matroska multimedia container contains the ATTR("CodecID") a child of the ELEM("TrackEntry") that defines the codec used to encode the data of the track.

The value of ATTR("CodecID") for HEVC is V_MPEGH/ISO/HEVC following the same convention used with AVC that is defined as V_MPEG4/ISO/AVC.

CodecID Description

What is the Codec Specific Information?

The Matroska multimedia container also contains codec initialization data, ATTR("CodecPrivate") in the ELEM("TrackEntry"). The format of the ATTR("CodecPrivate") has been extended to add HEVC support.

The format of the ATTR("CodecPrivate") has been modified to include the new video parameter set (VPS) defined in the HEVC standard. The VPS will be included in the ATTR("CodecPrivate") if and only if available in the HEVC stream. The table below defines the format of the ATTR("CodecPrivate") if the ATTR("CodecID") is equal to V_MPEGH/ISO/HEVC.

Value Bits Description
configuration_version 8 The value should be 0 until the format has been finalized. Thereafter is should have the specified value (probably 1). This allows us to recognize (and ignore) non-standard CodecPrivate
general_profile_space 2 Specifies the context for the interpretation of general_profile_idc and general_profile_compatibility_flag
general_tier_flag 1 Specifies the context for the interpretation of general_level_idc
general_profile_idc 5 Defines the profile of the bitstream
general_profile_compatibility_flag 32 Defines profile compatibility, see [HEVC] for interpretation
general_progressive_source_flag 1 Source is progressive, see [HEVC] for interpretation
general_interlace_source_flag 1 Source is interlaced, see [HEVC] for interpretation
general_non-packed_constraint_flag 1 If 1 then no frame packing arrangement SEI messages
general_frame_only_constraint_flag 1 If 1 then no fields, see [HEVC] for interpretation
Reserved 44 Reserved Field, Value TBD 0
general_level_idc 8 Defines the level of the bitstream
Reserved 4 Reserved Field, value '1111'b
min_spatial_segmentation_idc 12 Maximum possible size of distinct coded spatial segmentation regions in the pictures of the CVS
Reserved 6 Reserved Field, value '111111'b
Parallelism_type 2 0=unknown, 1=slices, 2=tiles, 3=WPP
Reserved 6 Reserved Field, value '111111'b
chroma_format_idc 2 See [HEVC] spec for details, table 6-1
Reserved 5 Reserved Field, value '11111'b
bit_depth_luma_minus8 3 Bit depth luma minus 8
Reserved 5 Reserved Field, value '11111'b
bit_depth_chroma_minus8 3 Bit depth chroma minus 8
Reserved 16 Reserved Field, value 0
Reserved 2 Reserved Field, value 0
max_sub_layers 3 maximum number of temporal sub-layers
temporal_id_nesting_flag 1 Specifies whether inter prediction is additionally restricted. see [HEVC] for interpretation.
size_nalu_minus_one 2 Size of field NALU Length – 1
num_parameter_sets 8 Number of parameter sets
for (i=0;i<num_parameter_sets;i++) {
array_completeness 1 1 when there is no duplicate parameter set with same id in the stream, 0 otherwise or unknown
Reserved 1 Reserved field, Value '1'b
nal_unit_type 6 Nal unit type, restricted to VPS, SPS, PPS and SEI, SEI must be of declarative nature which applies to the whole stream such as user data sei.
nal_unit_count 16 Number of nal units
for (j=0;j<nalu_unit_count;j++) {
size 16 Size of nal unit
for(k=0;k < size;k++) {
data[k] 8 nalu data

Above table references official [HEVC] spec documents

How is the HEVC Stream Stored?

The stream data in Matroska is stored within blocks, either a ATTR("Block") or ATTR("SimpleBlock").

See the Matroska specification for details on this structure:

The HEVC stream is stored within MKV using the same convention as AVC with each NAL unit having a 4-byte unsigned integer that precedes the NAL. The value of the unsigned integer is the size of the NAL unit that follows. In contrast the value of the 4-byte unsigned integer with a stream stored using the Annex B syntax does not use a 4-byte size prefix but instead uses a constant 4-byte start code of 0x00000001.

A HEVC block is considered a keyframe if the HEVC sample is an Instantaneous Decoding Refresh (IDR) picture, a Clean Random Access (CRA) picture, or a Broken Link Access (BLA) picture.