|
|
@ -750,6 +750,26 @@ enum { |
|
|
|
SEEK_TO_PTS, |
|
|
|
SEEK_TO_PTS, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Try to seek over a broken chunk |
|
|
|
|
|
|
|
* @return <0 on error |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
static int recover(WtvContext *wtv, uint64_t broken_pos) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AVIOContext *pb = wtv->pb; |
|
|
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
for (i = 0; i < wtv->nb_index_entries; i++) { |
|
|
|
|
|
|
|
if (wtv->index_entries[i].pos > broken_pos) { |
|
|
|
|
|
|
|
int ret = avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET); |
|
|
|
|
|
|
|
if (ret < 0) |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
wtv->pts = wtv->index_entries[i].timestamp; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return AVERROR(EIO); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Parse WTV chunks |
|
|
|
* Parse WTV chunks |
|
|
|
* @param mode SEEK_TO_DATA or SEEK_TO_PTS |
|
|
|
* @param mode SEEK_TO_DATA or SEEK_TO_PTS |
|
|
@ -767,8 +787,13 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
|
|
|
|
|
|
|
|
ff_get_guid(pb, &g); |
|
|
|
ff_get_guid(pb, &g); |
|
|
|
len = avio_rl32(pb); |
|
|
|
len = avio_rl32(pb); |
|
|
|
if (len < 32) |
|
|
|
if (len < 32) { |
|
|
|
break; |
|
|
|
int ret; |
|
|
|
|
|
|
|
av_log(s, AV_LOG_WARNING, "encountered broken chunk\n"); |
|
|
|
|
|
|
|
if ((ret = recover(wtv, avio_tell(pb) - 20)) < 0) |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
sid = avio_rl32(pb) & 0x7FFF; |
|
|
|
sid = avio_rl32(pb) & 0x7FFF; |
|
|
|
avio_skip(pb, 8); |
|
|
|
avio_skip(pb, 8); |
|
|
|
consumed = 32; |
|
|
|
consumed = 32; |
|
|
|