uint64_t pixel_width;
uint64_t pixel_height;
EbmlBin color_space;
+ uint64_t display_unit;
uint64_t interlaced;
uint64_t field_order;
uint64_t stereo_mode;
};
static const EbmlSyntax matroska_track_video_color[] = {
- { MATROSKA_ID_VIDEOCOLORMATRIXCOEFF, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, matrix_coefficients), { .u=2 } },
- { MATROSKA_ID_VIDEOCOLORBITSPERCHANNEL, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, bits_per_channel), { .u=8 } },
+ { MATROSKA_ID_VIDEOCOLORMATRIXCOEFF, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, matrix_coefficients), { .u = AVCOL_SPC_UNSPECIFIED } },
+ { MATROSKA_ID_VIDEOCOLORBITSPERCHANNEL, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, bits_per_channel), { .u=0 } },
{ MATROSKA_ID_VIDEOCOLORCHROMASUBHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_horz), { .u=0 } },
{ MATROSKA_ID_VIDEOCOLORCHROMASUBVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_vert), { .u=0 } },
{ MATROSKA_ID_VIDEOCOLORCBSUBHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, cb_sub_horz), { .u=0 } },
{ MATROSKA_ID_VIDEOCOLORCBSUBVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, cb_sub_vert), { .u=0 } },
- { MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_horz), { .u=0 } },
- { MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_vert), { .u=0 } },
- { MATROSKA_ID_VIDEOCOLORRANGE, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, range), { .u=0 } },
- { MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, transfer_characteristics), { .u=2 } },
- { MATROSKA_ID_VIDEOCOLORPRIMARIES, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, primaries), { .u=2 } },
+ { MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_horz), { .u = MATROSKA_COLOUR_CHROMASITINGHORZ_UNDETERMINED } },
+ { MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_vert), { .u = MATROSKA_COLOUR_CHROMASITINGVERT_UNDETERMINED } },
+ { MATROSKA_ID_VIDEOCOLORRANGE, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, range), { .u = AVCOL_RANGE_UNSPECIFIED } },
+ { MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, transfer_characteristics), { .u = AVCOL_TRC_UNSPECIFIED } },
+ { MATROSKA_ID_VIDEOCOLORPRIMARIES, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, primaries), { .u = AVCOL_PRI_UNSPECIFIED } },
{ MATROSKA_ID_VIDEOCOLORMAXCLL, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_cll), { .u=0 } },
{ MATROSKA_ID_VIDEOCOLORMAXFALL, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_fall), { .u=0 } },
{ MATROSKA_ID_VIDEOCOLORMASTERINGMETA, EBML_NEST, 0, offsetof(MatroskaTrackVideoColor, mastering_meta), { .n = matroska_mastering_meta } },
{ MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE },
- { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE },
+ { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_UINT, 0, offsetof(MatroskaTrackVideo, display_unit), { .u= MATROSKA_VIDEO_DISPLAYUNIT_PIXELS } },
{ MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_UINT, 0, offsetof(MatroskaTrackVideo, interlaced), { .u = MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED } },
{ MATROSKA_ID_VIDEOFIELDORDER, EBML_UINT, 0, offsetof(MatroskaTrackVideo, field_order), { .u = MATROSKA_VIDEO_FIELDORDER_UNDETERMINED } },
{ MATROSKA_ID_VIDEOSTEREOMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } },
return 0;
}
-static int mkv_field_order(int64_t field_order)
+static int mkv_field_order(MatroskaDemuxContext *matroska, int64_t field_order)
{
+ int major, minor, micro, bttb = 0;
+
+ /* workaround a bug in our Matroska muxer, introduced in version 57.36 alongside
+ * this function, and fixed in 57.52 */
+ if (matroska->muxingapp && sscanf(matroska->muxingapp, "Lavf%d.%d.%d", &major, &minor, µ) == 3)
+ bttb = (major == 57 && minor >= 36 && minor <= 51 && micro >= 100);
+
switch (field_order) {
case MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE:
return AV_FIELD_PROGRESSIVE;
case MATROSKA_VIDEO_FIELDORDER_BB:
return AV_FIELD_BB;
case MATROSKA_VIDEO_FIELDORDER_BT:
- return AV_FIELD_BT;
+ return bttb ? AV_FIELD_TB : AV_FIELD_BT;
case MATROSKA_VIDEO_FIELDORDER_TB:
- return AV_FIELD_TB;
+ return bttb ? AV_FIELD_BT : AV_FIELD_TB;
default:
return AV_FIELD_UNKNOWN;
}
if (track->video.color.range != AVCOL_RANGE_UNSPECIFIED &&
track->video.color.range <= AVCOL_RANGE_JPEG)
st->codecpar->color_range = track->video.color.range;
+ if (track->video.color.chroma_siting_horz != MATROSKA_COLOUR_CHROMASITINGHORZ_UNDETERMINED &&
+ track->video.color.chroma_siting_vert != MATROSKA_COLOUR_CHROMASITINGVERT_UNDETERMINED &&
+ track->video.color.chroma_siting_horz < MATROSKA_COLOUR_CHROMASITINGHORZ_NB &&
+ track->video.color.chroma_siting_vert < MATROSKA_COLOUR_CHROMASITINGVERT_NB) {
+ st->codecpar->chroma_location =
+ avcodec_chroma_pos_to_enum((track->video.color.chroma_siting_horz - 1) << 7,
+ (track->video.color.chroma_siting_vert - 1) << 7);
+ }
if (has_mastering_primaries || has_mastering_luminance) {
// Use similar rationals as other standards.
st->codecpar->height = track->video.pixel_height;
if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED)
- st->codecpar->field_order = mkv_field_order(track->video.field_order);
+ st->codecpar->field_order = mkv_field_order(matroska, track->video.field_order);
else if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_PROGRESSIVE)
st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB)
mkv_stereo_mode_display_mul(track->video.stereo_mode, &display_width_mul, &display_height_mul);
- av_reduce(&st->sample_aspect_ratio.num,
- &st->sample_aspect_ratio.den,
- st->codecpar->height * track->video.display_width * display_width_mul,
- st->codecpar->width * track->video.display_height * display_height_mul,
- 255);
+ if (track->video.display_unit < MATROSKA_VIDEO_DISPLAYUNIT_UNKNOWN) {
+ av_reduce(&st->sample_aspect_ratio.num,
+ &st->sample_aspect_ratio.den,
+ st->codecpar->height * track->video.display_width * display_width_mul,
+ st->codecpar->width * track->video.display_height * display_height_mul,
+ 255);
+ }
if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
av_free(pkt);
return AVERROR(ENOMEM);
}
- AV_WL32(side_data, 0);
- AV_WL32(side_data + 4, av_rescale_q(discard_padding,
+ discard_padding = av_rescale_q(discard_padding,
(AVRational){1, 1000000000},
- (AVRational){1, st->codecpar->sample_rate}));
+ (AVRational){1, st->codecpar->sample_rate});
+ if (discard_padding > 0) {
+ AV_WL32(side_data + 4, discard_padding);
+ } else {
+ AV_WL32(side_data, -discard_padding);
+ }
}
if (track->ms_compat)
av_log(s, AV_LOG_ERROR, "Failed to read file headers\n");
return -1;
}
+ if (!s->nb_streams) {
+ matroska_read_close(s);
+ av_log(s, AV_LOG_ERROR, "No streams found\n");
+ return AVERROR_INVALIDDATA;
+ }
if (!matroska->is_live) {
buf = av_asprintf("%g", matroska->duration);