Skip to content

Commit e469a8d

Browse files
committed
cropping: make DisplayWidth/DisplayHeight include cropped area
The primary motivation for this change is to ensure that Matroska files with `PixelCrop*` elements are displayed consistently, regardless of whether cropping is applied. This makes such files compatible across software that either supports or ignores these elements. Without this change, files suffer from limited compatibility, whereas cropping tags should enhance the experience rather than be a requirement for proper image display. A secondary motivation is that an overwhelming number of files in the wild do not actually adjust the `DisplayWidth`/`DisplayHeight` elements as expected by the specification. Most of the time, these values are left uncropped, with the expectation that cropping will be applied later. This issue arises partly because MKVToolNix does not automatically perform this calculation, it only sets the `PixelCrop*` elements unless explicitly instructed by the user. Observing the existing files in circulation, it is evident that almost no one manually adjusts these values. Lastly, some subtitle formats depend on the video size for positioning and rendering, making them sensitive to cropping. Currently, most authoring tools do not take cropping into account. By making the Matroska specification more flexible and allowing subtitles to be cropped along with the video, it becomes easier to produce files that are compatible with various Matroska players. For a more detailed discussion on this topic, please refer to the links below: See: https://gitlab.com/mbunkus/mkvtoolnix/-/issues/2389 See: mpv-player/mpv#13446
1 parent 5ed5c43 commit e469a8d

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

ebml_matroska.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -649,15 +649,15 @@ The format depends on the `ChapProcessCodecID` used; see (#chapprocesscodecid-el
649649
<extension type="webmproject.org" webm="1"/>
650650
</element>
651651
<element name="DisplayWidth" path="\Segment\Tracks\TrackEntry\Video\DisplayWidth" id="0x54B0" type="uinteger" range="not 0" maxOccurs="1">
652-
<documentation lang="en" purpose="definition">Width of the video frames to display. Applies to the video frame after cropping (PixelCrop* Elements).</documentation>
653-
<implementation_note note_attribute="default">If the DisplayUnit of the same `TrackEntry` is 0, then the default value for `DisplayWidth` is equal to `PixelWidth` - `PixelCropLeft` - `PixelCropRight`; else, there is no default value.</implementation_note>
652+
<documentation lang="en" purpose="definition">The width of the video frames to be displayed, including any area cropped according to the PixelCrop* elements.</documentation>
653+
<implementation_note note_attribute="default">If the DisplayUnit of the same `TrackEntry` is 0, then the default value for `DisplayWidth` is equal to `PixelWidth`, else there is no default value.</implementation_note>
654654
<extension type="libmatroska" cppname="VideoDisplayWidth"/>
655655
<extension type="stream copy" keep="1"/>
656656
<extension type="webmproject.org" webm="1"/>
657657
</element>
658658
<element name="DisplayHeight" path="\Segment\Tracks\TrackEntry\Video\DisplayHeight" id="0x54BA" type="uinteger" range="not 0" maxOccurs="1">
659-
<documentation lang="en" purpose="definition">Height of the video frames to display. Applies to the video frame after cropping (PixelCrop* Elements).</documentation>
660-
<implementation_note note_attribute="default">If the DisplayUnit of the same `TrackEntry` is 0, then the default value for `DisplayHeight` is equal to `PixelHeight` - `PixelCropTop` - `PixelCropBottom`; else, there is no default value.</implementation_note>
659+
<documentation lang="en" purpose="definition">The height of the video frames to be displayed, including any area cropped according to the PixelCrop* elements.</documentation>
660+
<implementation_note note_attribute="default">If the DisplayUnit of the same `TrackEntry` is 0, then the default value for `DisplayHeight` is equal to `PixelHeight`, else there is no default value.</implementation_note>
661661
<extension type="libmatroska" cppname="VideoDisplayHeight"/>
662662
<extension type="stream copy" keep="1"/>
663663
<extension type="webmproject.org" webm="1"/>

notes.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -795,9 +795,22 @@ within the center of a padded 1920x1080 encoded image may set both
795795
should crop off 240 columns of pixels from the left and right of
796796
the encoded image to present the image with the pillar-boxes hidden.
797797

798-
Cropping has to be performed before resizing and the display dimensions
799-
given by `DisplayWidth`, `DisplayHeight`, and
800-
`DisplayUnit` apply to the already-cropped image.
798+
Cropping must be performed before resizing to the display dimensions to prevent
799+
the cropped pixels from affecting the resized image. The numbers given in the
800+
PixelCrop elements refer to pixels of the stored video before resizing.
801+
The display dimensions given by `DisplayWidth`, `DisplayHeight`, and `DisplayUnit`
802+
describe the area occupied by the full image, including the cropped pixels,
803+
so the actual displayed image may be smaller after cropping is applied.
804+
805+
Whether cropping is applied or not, it should not affect the displayed geometry
806+
of the image, except for removing the cropped area. After the whole image is
807+
stretched or compressed in accordance with `DisplayWidth` and `DisplayHeight`
808+
and the cropped area is removed, the remaining area is not further stretched
809+
or compressed.
810+
811+
When subtitles are displayed on the video (if relevant to the particular
812+
subtitle format), they are associated with the full (uncropped) video frame and
813+
are cropped along with the video.
801814

802815
## Rotation
803816

0 commit comments

Comments
 (0)