double time_scale;
uint64_t default_duration;
uint64_t flag_default;
+ uint64_t flag_forced;
MatroskaTrackVideo video;
MatroskaTrackAudio audio;
EbmlList encodings;
{ MATROSKA_ID_TRACKDEFAULTDURATION, EBML_UINT, 0, offsetof(MatroskaTrack,default_duration) },
{ MATROSKA_ID_TRACKTIMECODESCALE, EBML_FLOAT,0, offsetof(MatroskaTrack,time_scale), {.f=1.0} },
{ MATROSKA_ID_TRACKFLAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTrack,flag_default), {.u=1} },
+ { MATROSKA_ID_TRACKFLAGFORCED, EBML_UINT, 0, offsetof(MatroskaTrack,flag_forced), {.u=0} },
{ MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, offsetof(MatroskaTrack,video), {.n=matroska_track_video} },
{ MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, offsetof(MatroskaTrack,audio), {.n=matroska_track_audio} },
{ MATROSKA_ID_TRACKCONTENTENCODINGS,EBML_NEST, 0, 0, {.n=matroska_track_encodings} },
{ MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE },
- { MATROSKA_ID_TRACKFLAGFORCED, EBML_NONE },
{ MATROSKA_ID_TRACKFLAGLACING, EBML_NONE },
{ MATROSKA_ID_CODECNAME, EBML_NONE },
{ MATROSKA_ID_CODECDECODEALL, EBML_NONE },
if (matroska->num_levels > 0) {
MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1];
- if (pos - level->start >= level->length) {
+ if (pos - level->start >= level->length || matroska->current_id) {
matroska->num_levels--;
return 1;
}
* are supposed to be sub-elements which can be read separately.
* 0 is success, < 0 is failure.
*/
-static int ebml_read_master(MatroskaDemuxContext *matroska, int length)
+static int ebml_read_master(MatroskaDemuxContext *matroska, uint64_t length)
{
ByteIOContext *pb = matroska->ctx->pb;
MatroskaLevel *level;
for (i=0; syntax[i].id; i++)
if (id == syntax[i].id)
break;
+ if (!syntax[i].id && id == MATROSKA_ID_CLUSTER &&
+ matroska->num_levels > 0 &&
+ matroska->levels[matroska->num_levels-1].length == 0xffffffffffffff)
+ return 0; // we reached the end of an unknown size cluster
if (!syntax[i].id && id != EBML_ID_VOID && id != EBML_ID_CRC32)
av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id);
return ebml_parse_elem(matroska, &syntax[i], data);
void *data)
{
if (!matroska->current_id) {
- uint64_t id;
- int res = ebml_read_num(matroska, matroska->ctx->pb, 4, &id);
- if (res < 0)
- return res;
- matroska->current_id = id | 1 << 7*res;
+ uint64_t id;
+ int res = ebml_read_num(matroska, matroska->ctx->pb, 4, &id);
+ if (res < 0)
+ return res;
+ matroska->current_id = id | 1 << 7*res;
}
return ebml_parse_id(matroska, syntax, matroska->current_id, data);
}
uint64_t max_start = 0;
Ebml ebml = { 0 };
AVStream *st;
- int i, j;
+ int i, j, res;
matroska->ctx = s;
ebml_free(ebml_syntax, &ebml);
/* The next thing is a segment. */
- if (ebml_parse(matroska, matroska_segments, matroska) < 0)
- return -1;
+ if ((res = ebml_parse(matroska, matroska_segments, matroska)) < 0)
+ return res;
matroska_execute_seekhead(matroska);
if (!matroska->time_scale)
if (track->flag_default)
st->disposition |= AV_DISPOSITION_DEFAULT;
+ if (track->flag_forced)
+ st->disposition |= AV_DISPOSITION_FORCED;
if (track->default_duration)
av_reduce(&st->codec->time_base.num, &st->codec->time_base.den,
if (matroska->prev_pkt &&
timecode != AV_NOPTS_VALUE &&
matroska->prev_pkt->pts == timecode &&
- matroska->prev_pkt->stream_index == st->index)
+ matroska->prev_pkt->stream_index == st->index &&
+ st->codec->codec_id == CODEC_ID_SSA)
matroska_merge_packets(matroska->prev_pkt, pkt);
else {
dynarray_add(&matroska->packets,&matroska->num_packets,pkt);
matroska->prev_pkt = NULL;
if (matroska->current_id)
pos -= 4; /* sizeof the ID which was already read */
- res = ebml_parse(matroska, matroska_clusters, &cluster);
+ res = ebml_parse(matroska, matroska_clusters, &cluster);
blocks_list = &cluster.blocks;
blocks = blocks_list->elem;
for (i=0; i<blocks_list->nb_elem; i++)