int list_elem_size;
int data_offset;
union {
+ int64_t i;
uint64_t u;
double f;
const char *s;
uint64_t field_order;
uint64_t stereo_mode;
uint64_t alpha_mode;
- MatroskaTrackVideoColor color;
+ EbmlList color;
MatroskaTrackVideoProjection projection;
} MatroskaTrackVideo;
{ MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo, pixel_height) },
{ MATROSKA_ID_VIDEOCOLORSPACE, EBML_BIN, 0, offsetof(MatroskaTrackVideo, color_space) },
{ MATROSKA_ID_VIDEOALPHAMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, alpha_mode) },
- { MATROSKA_ID_VIDEOCOLOR, EBML_NEST, 0, offsetof(MatroskaTrackVideo, color), { .n = matroska_track_video_color } },
+ { MATROSKA_ID_VIDEOCOLOR, EBML_NEST, sizeof(MatroskaTrackVideoColor), offsetof(MatroskaTrackVideo, color), { .n = matroska_track_video_color } },
{ MATROSKA_ID_VIDEOPROJECTION, EBML_NEST, 0, offsetof(MatroskaTrackVideo, projection), { .n = matroska_track_video_projection } },
{ MATROSKA_ID_VIDEOPIXELCROPB, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE },
{ MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock, bin) },
{ MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock, duration) },
{ MATROSKA_ID_DISCARDPADDING, EBML_SINT, 0, offsetof(MatroskaBlock, discard_padding) },
- { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference) },
+ { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference), { .i = INT64_MIN } },
{ MATROSKA_ID_CODECSTATE, EBML_NONE },
{ 1, EBML_UINT, 0, offsetof(MatroskaBlock, non_simple), { .u = 1 } },
{ 0 }
for (i = 0; syntax[i].id; i++)
switch (syntax[i].type) {
+ case EBML_SINT:
+ *(int64_t *) ((char *) data + syntax[i].data_offset) = syntax[i].def.i;
+ break;
case EBML_UINT:
*(uint64_t *) ((char *) data + syntax[i].data_offset) = syntax[i].def.u;
break;
}
static int mkv_parse_video_color(AVStream *st, const MatroskaTrack *track) {
- const MatroskaMasteringMeta* mastering_meta =
- &track->video.color.mastering_meta;
+ const MatroskaTrackVideoColor *color = track->video.color.elem;
+ const MatroskaMasteringMeta *mastering_meta;
+ int has_mastering_primaries, has_mastering_luminance;
+
+ if (!track->video.color.nb_elem)
+ return 0;
+
+ mastering_meta = &color->mastering_meta;
// Mastering primaries are CIE 1931 coords, and must be > 0.
- const int has_mastering_primaries =
+ has_mastering_primaries =
mastering_meta->r_x > 0 && mastering_meta->r_y > 0 &&
mastering_meta->g_x > 0 && mastering_meta->g_y > 0 &&
mastering_meta->b_x > 0 && mastering_meta->b_y > 0 &&
mastering_meta->white_x > 0 && mastering_meta->white_y > 0;
- const int has_mastering_luminance = mastering_meta->max_luminance > 0;
-
- if (track->video.color.matrix_coefficients != AVCOL_SPC_RESERVED)
- st->codecpar->color_space = track->video.color.matrix_coefficients;
- if (track->video.color.primaries != AVCOL_PRI_RESERVED &&
- track->video.color.primaries != AVCOL_PRI_RESERVED0)
- st->codecpar->color_primaries = track->video.color.primaries;
- if (track->video.color.transfer_characteristics != AVCOL_TRC_RESERVED &&
- track->video.color.transfer_characteristics != AVCOL_TRC_RESERVED0)
- st->codecpar->color_trc = track->video.color.transfer_characteristics;
- 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) {
+ has_mastering_luminance = mastering_meta->max_luminance > 0;
+
+ if (color->matrix_coefficients != AVCOL_SPC_RESERVED)
+ st->codecpar->color_space = color->matrix_coefficients;
+ if (color->primaries != AVCOL_PRI_RESERVED &&
+ color->primaries != AVCOL_PRI_RESERVED0)
+ st->codecpar->color_primaries = color->primaries;
+ if (color->transfer_characteristics != AVCOL_TRC_RESERVED &&
+ color->transfer_characteristics != AVCOL_TRC_RESERVED0)
+ st->codecpar->color_trc = color->transfer_characteristics;
+ if (color->range != AVCOL_RANGE_UNSPECIFIED &&
+ color->range <= AVCOL_RANGE_JPEG)
+ st->codecpar->color_range = color->range;
+ if (color->chroma_siting_horz != MATROSKA_COLOUR_CHROMASITINGHORZ_UNDETERMINED &&
+ color->chroma_siting_vert != MATROSKA_COLOUR_CHROMASITINGVERT_UNDETERMINED &&
+ color->chroma_siting_horz < MATROSKA_COLOUR_CHROMASITINGHORZ_NB &&
+ 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);
+ avcodec_chroma_pos_to_enum((color->chroma_siting_horz - 1) << 7,
+ (color->chroma_siting_vert - 1) << 7);
}
if (has_mastering_primaries || has_mastering_luminance) {
switch (track->video.projection.type) {
case MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR:
- if (track->video.projection.private.size < 4)
- return AVERROR_INVALIDDATA;
projection = AV_SPHERICAL_EQUIRECTANGULAR;
break;
case MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP:
ret = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL, (uint8_t *)spherical,
spherical_size);
- if (ret < 0)
+ if (ret < 0) {
+ av_freep(&spherical);
return ret;
+ }
return 0;
}
return ret;
}
- if (s->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
- int ret = mkv_parse_video_color(st, track);
- if (ret < 0)
- return ret;
- }
-
+ ret = mkv_parse_video_color(st, track);
+ if (ret < 0)
+ return ret;
ret = mkv_parse_video_projection(st, track);
if (ret < 0)
return ret;
if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE &&
timecode < track->end_timecode)
is_keyframe = 0; /* overlapping subtitles are not key frame */
- if (is_keyframe)
+ if (is_keyframe) {
+ ff_reduce_index(matroska->ctx, st->index);
av_add_index_entry(st, cluster_pos, timecode, 0, 0,
AVINDEX_KEYFRAME);
+ }
}
if (matroska->skip_to_keyframe &&
matroska->current_cluster_num_blocks = blocks_list->nb_elem;
i = blocks_list->nb_elem - 1;
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
- int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
+ int is_keyframe = blocks[i].non_simple ? blocks[i].reference == INT64_MIN : -1;
uint8_t* additional = blocks[i].additional.size > 0 ?
blocks[i].additional.data : NULL;
if (!blocks[i].non_simple)
blocks = blocks_list->elem;
for (i = 0; i < blocks_list->nb_elem; i++)
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
- int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
+ int is_keyframe = blocks[i].non_simple ? blocks[i].reference == INT64_MIN : -1;
res = matroska_parse_block(matroska, blocks[i].bin.data,
blocks[i].bin.size, blocks[i].bin.pos,
cluster.timecode, blocks[i].duration,
MatroskaDemuxContext *matroska = s->priv_data;
MatroskaTrack *tracks = NULL;
AVStream *st = s->streams[stream_index];
- int i, index, index_sub, index_min;
+ int i, index, index_min;
/* Parse the CUES now since we need the index data to seek. */
if (matroska->cues_parsing_deferred > 0) {