Rotating Matroska video

2022-02-19 | Martin Hoppenheit | 4 min read

Videos created by mobile phones are often rotated by means of embedded metadata tags. Playback software that respects these tags applies the correct rotation when rendering a video while software that doesn’t only displays the tilted, un-rotated (original) video. Let’s see if we can rotate a Matroska (mkv) video using metadata! (spoiler: not really, but maybe in the future)

Setting the scene

Consider a usual MP4 video file created by a mobile phone. Both ExifTool and ffprobe show its rotation metadata (and most video players apply it):

$ ffprobe a.mp4
Stream #0:0(eng): Video: h264 ...
    rotate: 90

$ exiftool a.mp4
Rotation : 90

Now let’s convert this MP4 to Matroska without transcoding, i.e., changing only the container format while copying the video and audio streams (because reasons):

$ ffmpeg -i a.mp4 -c copy b.mkv

The rotation metadata seems to be intact (although ExifTool needs an additional flag to show it):

$ ffprobe b.mkv
Stream #0:0(eng): Video: h264 ...
    ROTATE: 90

$ exiftool -a b.mkv
Tag Name   : ROTATE
Tag String : 90

We can also use a specialized tool to investigate Matroska metadata, mkvinfo (part of the MKVToolNix suite):

$ mkvinfo b.mkv
+ Tags
 + Tag
  + Simple
   + Name: ROTATE
   + String: 90

However, opening b.mkv in several different viewers like VLC 3.0.16 or Totem 3.38.2 shows a tilted video!

That’s because the rotation metadata only seems to be intact. In fact, what you see here is just a remnant of the MP4 metadata copied to the Matroska file, not a tag that has any specific meaning in the Matroska file format. (If you have some experience with Matroska files you have probably already realized that because the rotation info is recorded as a generic name/value tag, not a proper Matroska element.)

The good …

The Matroska file format uses another metadata element for rotation, as explained in its specification notes:

The ProjectionPoseRoll Element can be used to indicate that the image from the associated video track SHOULD be rotated for presentation.

Sadly, ffmpeg does not set ProjectionPoseRoll to mirror the MP4 rotation metadata automatically. It might be possible to add it manually during the conversion using ffmpeg’s -metadata command line option, but to be honest I don’t know how exactly it should be parameterized in order to create the correct EBML data in the Matroska file. There is a specialized tool called mkvpropedit though that can edit Matroska metadata (again from the MKVToolNix suite):

$ mkvpropedit b.mkv -e track:1 -s projection-pose-roll='-90'

Let’s check with mkvinfo:

$ mkvinfo -a b.mkv
+ Tracks
 + Track
  + Video track
   + Video projection
    + Projection's roll rotation: -90

OK, all set, now we should be good to go, right? No.

The bad …

Opening the video in a viewer, it’s still tilted!

Here comes the really annoying part: The file now has the rotation metadata in the right place and perfectly adheres to the spec; but in the real world, no viewer supports Matroska’s ProjectionPoseRoll element yet. Well, I found one, and VLC has plans for its next major release, so the situation might improve in the future. But right now, there seems to be no feasible way to rotate a Matroska video by means of metadata.

And the ugly

So what can be done? It’s of course possible to rotate the video stream by re-encoding it – with all the usual implications regarding quality and integrity. If you want to do that it’s easiest to just let ffmpeg handle it automatically during the MP4 to Matroska conversion:

$ ffmpeg -i a.mp4 -c:a copy b.mkv

This switches container formats from MP4 to Matroska, copies the audio stream, transcodes the video stream to whatever codec and quality ffmpeg deems appropriate, rotates the video stream according to the MP4 metadata and finally removes said metadata. Alternatively you can rotate an existing Matroska file:

$ ffmpeg -i b.mkv -c:a copy -vf 'transpose=clock' c.mkv

Add the -c:v and -crf options if you want to control the video codec and quality.